ash: cleanup part 7

This commit is contained in:
Denis Vlasenko 2007-02-23 01:05:26 +00:00
parent a6704933dd
commit 4fe15f3d9e

View File

@ -932,7 +932,6 @@ static int startlinno; /* line # where last token started */
static char *commandname; /* currently executing command */
static struct strlist *cmdenviron; /* environment for builtin command */
static int exitstatus; /* exit status of last command */
static int back_exitstatus; /* exit status of backquoted command */
/* ============ Message printing */
@ -2398,19 +2397,6 @@ static int casematch(union node *, char *);
static void expari(int);
#endif
/* eval.h */
struct backcmd { /* result of evalbackcmd */
int fd; /* file descriptor to read from */
char *buf; /* buffer */
int nleft; /* number of chars in buffer */
struct job *jp; /* job structure for command */
};
static void freefunc(struct funcnode *);
/* parser.h */
/* control characters in argument strings */
@ -3160,104 +3146,6 @@ struct builtincmd {
/* unsigned flags; */
};
#define COMMANDCMD (builtincmd + 5 + \
2 * ENABLE_ASH_BUILTIN_TEST + \
ENABLE_ASH_ALIAS + \
ENABLE_ASH_JOB_CONTROL)
#define EXECCMD (builtincmd + 7 + \
2 * ENABLE_ASH_BUILTIN_TEST + \
ENABLE_ASH_ALIAS + \
ENABLE_ASH_JOB_CONTROL + \
ENABLE_ASH_CMDCMD + \
ENABLE_ASH_BUILTIN_ECHO)
#define BUILTIN_NOSPEC "0"
#define BUILTIN_SPECIAL "1"
#define BUILTIN_REGULAR "2"
#define BUILTIN_SPEC_REG "3"
#define BUILTIN_ASSIGN "4"
#define BUILTIN_SPEC_ASSG "5"
#define BUILTIN_REG_ASSG "6"
#define BUILTIN_SPEC_REG_ASSG "7"
#define IS_BUILTIN_SPECIAL(builtincmd) ((builtincmd)->name[0] & 1)
#define IS_BUILTIN_REGULAR(builtincmd) ((builtincmd)->name[0] & 2)
#define IS_BUILTIN_ASSIGN(builtincmd) ((builtincmd)->name[0] & 4)
/* make sure to keep these in proper order since it is searched via bsearch() */
static const struct builtincmd builtincmd[] = {
{ BUILTIN_SPEC_REG ".", dotcmd },
{ BUILTIN_SPEC_REG ":", truecmd },
#if ENABLE_ASH_BUILTIN_TEST
{ BUILTIN_REGULAR "[", testcmd },
{ BUILTIN_REGULAR "[[", testcmd },
#endif
#if ENABLE_ASH_ALIAS
{ BUILTIN_REG_ASSG "alias", aliascmd },
#endif
#if JOBS
{ BUILTIN_REGULAR "bg", fg_bgcmd },
#endif
{ BUILTIN_SPEC_REG "break", breakcmd },
{ BUILTIN_REGULAR "cd", cdcmd },
{ BUILTIN_NOSPEC "chdir", cdcmd },
#if ENABLE_ASH_CMDCMD
{ BUILTIN_REGULAR "command", commandcmd },
#endif
{ BUILTIN_SPEC_REG "continue", breakcmd },
#if ENABLE_ASH_BUILTIN_ECHO
{ BUILTIN_REGULAR "echo", echocmd },
#endif
{ BUILTIN_SPEC_REG "eval", evalcmd },
{ BUILTIN_SPEC_REG "exec", execcmd },
{ BUILTIN_SPEC_REG "exit", exitcmd },
{ BUILTIN_SPEC_REG_ASSG "export", exportcmd },
{ BUILTIN_REGULAR "false", falsecmd },
#if JOBS
{ BUILTIN_REGULAR "fg", fg_bgcmd },
#endif
#if ENABLE_ASH_GETOPTS
{ BUILTIN_REGULAR "getopts", getoptscmd },
#endif
{ BUILTIN_NOSPEC "hash", hashcmd },
#if !ENABLE_FEATURE_SH_EXTRA_QUIET
{ BUILTIN_NOSPEC "help", helpcmd },
#endif
#if JOBS
{ BUILTIN_REGULAR "jobs", jobscmd },
{ BUILTIN_REGULAR "kill", killcmd },
#endif
#if ENABLE_ASH_MATH_SUPPORT
{ BUILTIN_NOSPEC "let", letcmd },
#endif
{ BUILTIN_ASSIGN "local", localcmd },
{ BUILTIN_NOSPEC "pwd", pwdcmd },
{ BUILTIN_REGULAR "read", readcmd },
{ BUILTIN_SPEC_REG_ASSG "readonly", exportcmd },
{ BUILTIN_SPEC_REG "return", returncmd },
{ BUILTIN_SPEC_REG "set", setcmd },
{ BUILTIN_SPEC_REG "shift", shiftcmd },
{ BUILTIN_SPEC_REG "source", dotcmd },
#if ENABLE_ASH_BUILTIN_TEST
{ BUILTIN_REGULAR "test", testcmd },
#endif
{ BUILTIN_SPEC_REG "times", timescmd },
{ BUILTIN_SPEC_REG "trap", trapcmd },
{ BUILTIN_REGULAR "true", truecmd },
{ BUILTIN_NOSPEC "type", typecmd },
{ BUILTIN_NOSPEC "ulimit", ulimitcmd },
{ BUILTIN_REGULAR "umask", umaskcmd },
#if ENABLE_ASH_ALIAS
{ BUILTIN_REGULAR "unalias", unaliascmd },
#endif
{ BUILTIN_SPEC_REG "unset", unsetcmd },
{ BUILTIN_REGULAR "wait", waitcmd },
};
#define NUMBUILTINS (sizeof(builtincmd) / sizeof(builtincmd[0]))
struct cmdentry {
int cmdtype;
union param {
@ -3267,7 +3155,6 @@ struct cmdentry {
} u;
};
/* action to find_command() */
#define DO_ERR 0x01 /* prints errors */
#define DO_ABS 0x02 /* checks absolute paths */
@ -3674,12 +3561,6 @@ static void evalcommand(union node *, int);
static int evalbltin(const struct builtincmd *, int, char **);
static int evalfun(struct funcnode *, int, char **, int);
static void prehash(union node *);
static int bltincmd(int, char **);
static const struct builtincmd bltin = {
"\0\0", bltincmd
};
/*
* Evaluate a parse tree. The value is left in the global variable
@ -4039,57 +3920,6 @@ evalpipe(union node *n, int flags)
}
/*
* Execute a command inside back quotes. If it's a builtin command, we
* want to save its output in a block obtained from malloc. Otherwise
* we fork off a subprocess and get the output of the command via a pipe.
* Should be called with interrupts off.
*/
static void
evalbackcmd(union node *n, struct backcmd *result)
{
int saveherefd;
result->fd = -1;
result->buf = NULL;
result->nleft = 0;
result->jp = NULL;
if (n == NULL) {
goto out;
}
saveherefd = herefd;
herefd = -1;
{
int pip[2];
struct job *jp;
if (pipe(pip) < 0)
ash_msg_and_raise_error("Pipe call failed");
jp = makejob(n, 1);
if (forkshell(jp, n, FORK_NOJOB) == 0) {
FORCE_INT_ON;
close(pip[0]);
if (pip[1] != 1) {
close(1);
copyfd(pip[1], 1);
close(pip[1]);
}
eflag = 0;
evaltreenr(n, EV_EXIT);
/* NOTREACHED */
}
close(pip[1]);
result->fd = pip[0];
result->jp = jp;
}
herefd = saveherefd;
out:
TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n",
result->fd, result->buf, result->nleft, result->jp));
}
#if ENABLE_ASH_CMDCMD
static char **
parse_command_args(char **argv, const char **path)
@ -4125,20 +3955,127 @@ parse_command_args(char **argv, const char **path)
}
#endif
static int isassignment(const char *p)
#define BUILTIN_NOSPEC "0"
#define BUILTIN_SPECIAL "1"
#define BUILTIN_REGULAR "2"
#define BUILTIN_SPEC_REG "3"
#define BUILTIN_ASSIGN "4"
#define BUILTIN_SPEC_ASSG "5"
#define BUILTIN_REG_ASSG "6"
#define BUILTIN_SPEC_REG_ASSG "7"
#define IS_BUILTIN_SPECIAL(b) ((b)->name[0] & 1)
#define IS_BUILTIN_REGULAR(b) ((b)->name[0] & 2)
#define IS_BUILTIN_ASSIGN(b) ((b)->name[0] & 4)
/* make sure to keep these in proper order since it is searched via bsearch() */
static const struct builtincmd builtintab[] = {
{ BUILTIN_SPEC_REG ".", dotcmd },
{ BUILTIN_SPEC_REG ":", truecmd },
#if ENABLE_ASH_BUILTIN_TEST
{ BUILTIN_REGULAR "[", testcmd },
{ BUILTIN_REGULAR "[[", testcmd },
#endif
#if ENABLE_ASH_ALIAS
{ BUILTIN_REG_ASSG "alias", aliascmd },
#endif
#if JOBS
{ BUILTIN_REGULAR "bg", fg_bgcmd },
#endif
{ BUILTIN_SPEC_REG "break", breakcmd },
{ BUILTIN_REGULAR "cd", cdcmd },
{ BUILTIN_NOSPEC "chdir", cdcmd },
#if ENABLE_ASH_CMDCMD
{ BUILTIN_REGULAR "command", commandcmd },
#endif
{ BUILTIN_SPEC_REG "continue", breakcmd },
#if ENABLE_ASH_BUILTIN_ECHO
{ BUILTIN_REGULAR "echo", echocmd },
#endif
{ BUILTIN_SPEC_REG "eval", evalcmd },
{ BUILTIN_SPEC_REG "exec", execcmd },
{ BUILTIN_SPEC_REG "exit", exitcmd },
{ BUILTIN_SPEC_REG_ASSG "export", exportcmd },
{ BUILTIN_REGULAR "false", falsecmd },
#if JOBS
{ BUILTIN_REGULAR "fg", fg_bgcmd },
#endif
#if ENABLE_ASH_GETOPTS
{ BUILTIN_REGULAR "getopts", getoptscmd },
#endif
{ BUILTIN_NOSPEC "hash", hashcmd },
#if !ENABLE_FEATURE_SH_EXTRA_QUIET
{ BUILTIN_NOSPEC "help", helpcmd },
#endif
#if JOBS
{ BUILTIN_REGULAR "jobs", jobscmd },
{ BUILTIN_REGULAR "kill", killcmd },
#endif
#if ENABLE_ASH_MATH_SUPPORT
{ BUILTIN_NOSPEC "let", letcmd },
#endif
{ BUILTIN_ASSIGN "local", localcmd },
{ BUILTIN_NOSPEC "pwd", pwdcmd },
{ BUILTIN_REGULAR "read", readcmd },
{ BUILTIN_SPEC_REG_ASSG "readonly", exportcmd },
{ BUILTIN_SPEC_REG "return", returncmd },
{ BUILTIN_SPEC_REG "set", setcmd },
{ BUILTIN_SPEC_REG "shift", shiftcmd },
{ BUILTIN_SPEC_REG "source", dotcmd },
#if ENABLE_ASH_BUILTIN_TEST
{ BUILTIN_REGULAR "test", testcmd },
#endif
{ BUILTIN_SPEC_REG "times", timescmd },
{ BUILTIN_SPEC_REG "trap", trapcmd },
{ BUILTIN_REGULAR "true", truecmd },
{ BUILTIN_NOSPEC "type", typecmd },
{ BUILTIN_NOSPEC "ulimit", ulimitcmd },
{ BUILTIN_REGULAR "umask", umaskcmd },
#if ENABLE_ASH_ALIAS
{ BUILTIN_REGULAR "unalias", unaliascmd },
#endif
{ BUILTIN_SPEC_REG "unset", unsetcmd },
{ BUILTIN_REGULAR "wait", waitcmd },
};
#define NUMBUILTINS (sizeof(builtintab) / sizeof(builtintab[0]))
#define COMMANDCMD (builtintab + 5 + \
2 * ENABLE_ASH_BUILTIN_TEST + \
ENABLE_ASH_ALIAS + \
ENABLE_ASH_JOB_CONTROL)
#define EXECCMD (builtintab + 7 + \
2 * ENABLE_ASH_BUILTIN_TEST + \
ENABLE_ASH_ALIAS + \
ENABLE_ASH_JOB_CONTROL + \
ENABLE_ASH_CMDCMD + \
ENABLE_ASH_BUILTIN_ECHO)
/*
* Execute a simple command.
*/
static int back_exitstatus; /* exit status of backquoted command */
static int
isassignment(const char *p)
{
const char *q = endofname(p);
if (p == q)
return 0;
return *q == '=';
}
/*
* Execute a simple command.
*/
static int
bltincmd(int argc, char **argv)
{
/* Preserve exitstatus of a previous possible redirection
* as POSIX mandates */
return back_exitstatus;
}
static void
evalcommand(union node *cmd, int flags)
{
static const struct builtincmd bltin = {
"\0\0", bltincmd
};
struct stackmark smark;
union node *argp;
struct arglist arglist;
@ -4269,7 +4206,6 @@ evalcommand(union node *cmd, int flags)
cmd_is_exec++;
#if ENABLE_ASH_CMDCMD
if (cmdentry.u.cmd == COMMANDCMD) {
path = oldpath;
nargv = parse_command_args(argv, &path);
if (!nargv)
@ -4429,6 +4365,16 @@ poplocalvars(void)
}
}
/*
* Free a parse tree.
*/
static void
freefunc(struct funcnode *f)
{
if (f && --f->count < 0)
free(f);
}
static int
evalfun(struct funcnode *func, int argc, char **argv, int flags)
{
@ -4497,26 +4443,11 @@ prehash(union node *n)
}
/*
* Builtin commands. Builtin commands whose functions are closely
* tied to evaluation are implemented here.
*/
/*
* No command given.
*/
static int
bltincmd(int argc, char **argv)
{
/*
* Preserve exitstatus of a previous possible redirection
* as POSIX mandates
*/
return back_exitstatus;
}
/*
* Handle break and continue commands. Break, continue, and return are
* all handled by setting the evalskip flag. The evaluation routines
@ -4544,7 +4475,6 @@ breakcmd(int argc, char **argv)
return 0;
}
/*
* The return command.
*/
@ -4559,21 +4489,18 @@ returncmd(int argc, char **argv)
return argv[1] ? number(argv[1]) : exitstatus;
}
static int
falsecmd(int argc, char **argv)
{
return 1;
}
static int
truecmd(int argc, char **argv)
{
return 0;
}
static int
execcmd(int argc, char **argv)
{
@ -4984,7 +4911,7 @@ find_builtin(const char *name)
struct builtincmd *bp;
bp = bsearch(
name, builtincmd, NUMBUILTINS, sizeof(struct builtincmd),
name, builtintab, NUMBUILTINS, sizeof(builtintab[0]),
pstrcmp
);
return bp;
@ -5154,7 +5081,8 @@ delete_cmd_entry(void)
* Add a new command entry, replacing any existing command entry for
* the same name - except special builtins.
*/
static void addcmdentry(char *name, struct cmdentry *entry)
static void
addcmdentry(char *name, struct cmdentry *entry)
{
struct tblentry *cmdp;
@ -5171,7 +5099,8 @@ static void addcmdentry(char *name, struct cmdentry *entry)
/*
* Make a copy of a parse tree.
*/
static struct funcnode * copyfunc(union node *n)
static struct funcnode *
copyfunc(union node *n)
{
struct funcnode *f;
size_t blocksize;
@ -5188,7 +5117,6 @@ static struct funcnode * copyfunc(union node *n)
return f;
}
/*
* Define a shell function.
*/
@ -5204,7 +5132,6 @@ defun(char *name, union node *func)
INT_ON;
}
/*
* Delete a function if it exists.
*/
@ -5432,8 +5359,8 @@ static void varunset(const char *, const char *, const char *, int) ATTRIBUTE_NO
*
* Returns an stalloced string.
*/
static char * preglob(const char *pattern, int quoted, int flag)
static char *
preglob(const char *pattern, int quoted, int flag)
{
flag |= RMESCAPE_GLOB;
if (quoted) {
@ -5458,8 +5385,8 @@ esclen(const char *start, const char *p)
/*
* Expand shell variables and backquotes inside a here document.
*/
static void expandhere(union node *arg, int fd)
static void
expandhere(union node *arg, int fd)
{
herefd = fd;
expandarg(arg, (struct arglist *)NULL, 0);
@ -5756,7 +5683,7 @@ removerecordregions(int endoff)
* Expand arithmetic expression. Backup to start of expression,
* evaluate, place result in (backed up) result, adjust string position.
*/
void
static void
expari(int quotes)
{
char *p, *start;
@ -5814,6 +5741,64 @@ expari(int quotes)
#endif
/*
* Execute a command inside back quotes. If it's a builtin command, we
* want to save its output in a block obtained from malloc. Otherwise
* we fork off a subprocess and get the output of the command via a pipe.
* Should be called with interrupts off.
*/
struct backcmd { /* result of evalbackcmd */
int fd; /* file descriptor to read from */
char *buf; /* buffer */
int nleft; /* number of chars in buffer */
struct job *jp; /* job structure for command */
};
static void
evalbackcmd(union node *n, struct backcmd *result)
{
int saveherefd;
result->fd = -1;
result->buf = NULL;
result->nleft = 0;
result->jp = NULL;
if (n == NULL) {
goto out;
}
saveherefd = herefd;
herefd = -1;
{
int pip[2];
struct job *jp;
if (pipe(pip) < 0)
ash_msg_and_raise_error("Pipe call failed");
jp = makejob(n, 1);
if (forkshell(jp, n, FORK_NOJOB) == 0) {
FORCE_INT_ON;
close(pip[0]);
if (pip[1] != 1) {
close(1);
copyfd(pip[1], 1);
close(pip[1]);
}
eflag = 0;
evaltreenr(n, EV_EXIT);
/* NOTREACHED */
}
close(pip[1]);
result->fd = pip[0];
result->jp = jp;
}
herefd = saveherefd;
out:
TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n",
result->fd, result->buf, result->nleft, result->jp));
}
/*
* Expand stuff in backwards quotes.
*/
@ -5834,7 +5819,7 @@ expbackq(union node *cmd, int quoted, int quotes)
dest = expdest;
startloc = dest - (char *)stackblock();
grabstackstr(dest);
evalbackcmd(cmd, (struct backcmd *) &in);
evalbackcmd(cmd, &in);
popstackmark(&smark);
p = in.buf;
@ -8918,17 +8903,6 @@ nodeckstrdup(char *s)
}
/*
* Free a parse tree.
*/
static void
freefunc(struct funcnode *f)
{
if (f && --f->count < 0)
free(f);
}
static void
optschanged(void)
{