sync with dash_0.5.3-1
This commit was genuinely broken at the time (not related to our build system): scripts/config/mkconfigs.c (2005-08-01 - 2006-10-05 arasi) uretilen bbconfigopts.h icine .config satirlarini kacissiz, ham newline'larla gömüyordu - gecerli C degildi, busybox'un kendi bb_mkdep araci bile parse edemiyordu (7d219aab7 ile duzeltildi, mkconfigs shell scripte cevrildi)
No binary (build failed)
—
(log yok)
| @@ -36,7 +36,7 @@ | |
| * Modified by Paul Mundt <[email protected]> (c) 2004 to support | |
| * dynamic variables. | |
| * | |
| - | * Modified by Vladimir Oleynik <[email protected]> (c) 2001-2004 to be |
| + | * Modified by Vladimir Oleynik <[email protected]> (c) 2001-2005 to be |
| * used in busybox and size optimizations, | |
| * rewrote arith (see notes to this), added locale support, | |
| * rewrote dynamic variables. | |
| @@ -66,7 +66,6 @@ | |
| #endif | |
| #include <sys/types.h> | |
| - | #include <sys/cdefs.h> |
| #include <sys/ioctl.h> | |
| #include <sys/param.h> | |
| #include <sys/resource.h> | |
| @@ -91,7 +90,6 @@ | |
| #include <setjmp.h> | |
| #include <signal.h> | |
| #include <stdint.h> | |
| - | #include <sysexits.h> |
| #include <time.h> | |
| #include <fnmatch.h> | |
| @@ -130,7 +128,7 @@ static int *dash_errno; | |
| #ifdef CONFIG_ASH_ALIAS | |
| - | /* $NetBSD: alias.h,v 1.5 2002/11/24 22:35:38 christos Exp $ */ |
| + | /* alias.h */ |
| #define ALIASINUSE 1 | |
| #define ALIASDEAD 2 | |
| @@ -150,12 +148,12 @@ static int unalias(const char *); | |
| static void printalias(const struct alias *); | |
| #endif | |
| - | /* $NetBSD: cd.h,v 1.3 2002/11/24 22:35:39 christos Exp $ */ |
| + | /* cd.h */ |
| static void setpwd(const char *, int); | |
| - | /* $NetBSD: error.h,v 1.15 2002/11/24 22:35:39 christos Exp $ */ |
| + | /* error.h */ |
| /* | |
| @@ -189,8 +187,6 @@ static int exception; | |
| static volatile int suppressint; | |
| static volatile sig_atomic_t intpending; | |
| - | static int exerrno; /* Last exec error, error for EXEXEC */ |
| - | |
| /* exceptions */ | |
| #define EXINT 0 /* SIGINT received */ | |
| #define EXERROR 1 /* a generic error */ | |
| @@ -240,7 +236,7 @@ static volatile sig_atomic_t pendingsigs; | |
| static void exraise(int) __attribute__((__noreturn__)); | |
| static void onint(void) __attribute__((__noreturn__)); | |
| - | static void error(const char *, ...) __attribute__((__noreturn__)); |
| + | static void sh_error(const char *, ...) __attribute__((__noreturn__)); |
| static void exerror(int, const char *, ...) __attribute__((__noreturn__)); | |
| static void sh_warnx(const char *, ...); | |
| @@ -276,7 +272,7 @@ static void forceinton(void) | |
| }) | |
| #endif /* CONFIG_ASH_OPTIMIZE_FOR_SIZE */ | |
| - | /* $NetBSD: expand.h,v 1.13 2002/11/24 22:35:40 christos Exp $ */ |
| + | /* expand.h */ |
| struct strlist { | |
| struct strlist *next; | |
| @@ -313,7 +309,7 @@ static int casematch(union node *, char *); | |
| static void expari(int); | |
| #endif | |
| - | /* $NetBSD: eval.h,v 1.13 2002/11/24 22:35:39 christos Exp $ */ |
| + | /* eval.h */ |
| static char *commandname; /* currently executing command */ | |
| static struct strlist *cmdenviron; /* environment for builtin command */ | |
| @@ -492,7 +488,7 @@ struct funcnode { | |
| static void freefunc(struct funcnode *); | |
| - | /* $NetBSD: parser.h,v 1.15 2002/11/24 22:35:42 christos Exp $ */ |
| + | /* parser.h */ |
| /* control characters in argument strings */ | |
| #define CTL_FIRST '\201' /* first 'special' character */ | |
| @@ -591,7 +587,7 @@ static void fixredir(union node *, const char *, int); | |
| static const char *const *findkwd(const char *); | |
| static char *endofname(const char *); | |
| - | /* $NetBSD: shell.h,v 1.16 2003/01/22 20:36:04 dsl Exp $ */ |
| + | /* shell.h */ |
| typedef void *pointer; | |
| @@ -693,7 +689,7 @@ static const char *tokname(int tok) | |
| return buf; | |
| } | |
| - | /* $NetBSD: machdep.h,v 1.10 2002/10/07 14:26:08 christos Exp $ */ |
| + | /* machdep.h */ |
| /* | |
| * Most machines require the value returned from malloc to be aligned | |
| @@ -1160,7 +1156,7 @@ static const char syntax_index_table[258] = { | |
| #endif /* USE_SIT_FUNCTION */ | |
| - | /* $NetBSD: alias.c,v 1.11 2002/11/24 22:35:38 christos Exp $ */ |
| + | /* alias.c */ |
| #define ATABSIZE 39 | |
| @@ -1207,29 +1203,27 @@ static struct nodelist *copynodelist(struct nodelist *); | |
| static char *nodesavestr(char *); | |
| - | |
| - | static void evalstring(char *); |
| + | static int evalstring(char *, int mask); |
| union node; /* BLETCH for ansi C */ | |
| static void evaltree(union node *, int); | |
| static void evalbackcmd(union node *, struct backcmd *); | |
| - | /* in_function returns nonzero if we are currently evaluating a function */ |
| - | #define in_function() funcnest |
| static int evalskip; /* set if we are skipping commands */ | |
| static int skipcount; /* number of levels to skip */ | |
| static int funcnest; /* depth of function calls */ | |
| /* reasons for skipping commands (see comment on breakcmd routine) */ | |
| - | #define SKIPBREAK 1 |
| - | #define SKIPCONT 2 |
| - | #define SKIPFUNC 3 |
| - | #define SKIPFILE 4 |
| + | #define SKIPBREAK (1 << 0) |
| + | #define SKIPCONT (1 << 1) |
| + | #define SKIPFUNC (1 << 2) |
| + | #define SKIPFILE (1 << 3) |
| + | #define SKIPEVAL (1 << 4) |
| /* | |
| * This file was generated by the mkbuiltins program. | |
| */ | |
| - | #ifdef JOBS |
| + | #if JOBS |
| static int bgcmd(int, char **); | |
| #endif | |
| static int breakcmd(int, char **); | |
| @@ -1246,7 +1240,7 @@ static int execcmd(int, char **); | |
| static int exitcmd(int, char **); | |
| static int exportcmd(int, char **); | |
| static int falsecmd(int, char **); | |
| - | #ifdef JOBS |
| + | #if JOBS |
| static int fgcmd(int, char **); | |
| #endif | |
| #ifdef CONFIG_ASH_GETOPTS | |
| @@ -1256,7 +1250,7 @@ static int hashcmd(int, char **); | |
| #ifndef CONFIG_FEATURE_SH_EXTRA_QUIET | |
| static int helpcmd(int argc, char **argv); | |
| #endif | |
| - | #ifdef JOBS |
| + | #if JOBS |
| static int jobscmd(int, char **); | |
| #endif | |
| #ifdef CONFIG_ASH_MATH_SUPPORT | |
| @@ -1276,18 +1270,18 @@ static int umaskcmd(int, char **); | |
| static int unsetcmd(int, char **); | |
| static int waitcmd(int, char **); | |
| static int ulimitcmd(int, char **); | |
| - | #ifdef JOBS |
| + | #if JOBS |
| static int killcmd(int, char **); | |
| #endif | |
| - | /* $NetBSD: mail.h,v 1.9 2002/11/24 22:35:40 christos Exp $ */ |
| + | /* mail.h */ |
| #ifdef CONFIG_ASH_MAIL | |
| static void chkmail(void); | |
| static void changemail(const char *); | |
| #endif | |
| - | /* $NetBSD: exec.h,v 1.20 2003/01/22 20:36:04 dsl Exp $ */ |
| + | /* exec.h */ |
| /* values of cmdtype */ | |
| #define CMDUNKNOWN -1 /* no entry in table for command */ | |
| @@ -1327,7 +1321,7 @@ static const struct builtincmd builtincmd[] = { | |
| #ifdef CONFIG_ASH_ALIAS | |
| { BUILTIN_REG_ASSG "alias", aliascmd }, | |
| #endif | |
| - | #ifdef JOBS |
| + | #if JOBS |
| { BUILTIN_REGULAR "bg", bgcmd }, | |
| #endif | |
| { BUILTIN_SPEC_REG "break", breakcmd }, | |
| @@ -1345,7 +1339,7 @@ static const struct builtincmd builtincmd[] = { | |
| { BUILTIN_SPEC_REG "exit", exitcmd }, | |
| { BUILTIN_SPEC_REG_ASSG "export", exportcmd }, | |
| { BUILTIN_REGULAR "false", falsecmd }, | |
| - | #ifdef JOBS |
| + | #if JOBS |
| { BUILTIN_REGULAR "fg", fgcmd }, | |
| #endif | |
| #ifdef CONFIG_ASH_GETOPTS | |
| @@ -1355,7 +1349,7 @@ static const struct builtincmd builtincmd[] = { | |
| #ifndef CONFIG_FEATURE_SH_EXTRA_QUIET | |
| { BUILTIN_NOSPEC "help", helpcmd }, | |
| #endif | |
| - | #ifdef JOBS |
| + | #if JOBS |
| { BUILTIN_REGULAR "jobs", jobscmd }, | |
| { BUILTIN_REGULAR "kill", killcmd }, | |
| #endif | |
| @@ -1434,11 +1428,11 @@ static void change_random(const char *); | |
| # endif | |
| #endif | |
| - | /* $NetBSD: init.h,v 1.9 2002/11/24 22:35:40 christos Exp $ */ |
| + | /* init.h */ |
| static void reset(void); | |
| - | /* $NetBSD: var.h,v 1.21 2003/01/22 20:36:04 dsl Exp $ */ |
| + | /* var.h */ |
| /* | |
| * Shell variables. | |
| @@ -1613,7 +1607,7 @@ static int nullredirs; | |
| extern char **environ; | |
| - | /* $NetBSD: output.h,v 1.16 2002/11/24 22:35:42 christos Exp $ */ |
| + | /* output.h */ |
| static void outstr(const char *, FILE *); | |
| @@ -1714,6 +1708,11 @@ init(void) | |
| /* PEOF (the end of file marker) */ | |
| + | enum { |
| + | INPUT_PUSH_FILE = 1, |
| + | INPUT_NOFILE_OK = 2, |
| + | }; |
| + | |
| /* | |
| * The input line number. Input.c just defines this variable, and saves | |
| * and restores it when files are pushed and popped. The user of this | |
| @@ -1726,7 +1725,6 @@ static int preadbuffer(void); | |
| static void pungetc(void); | |
| static void pushstring(char *, void *); | |
| static void popstring(void); | |
| - | static void setinputfile(const char *, int); |
| static void setinputfd(int, int); | |
| static void setinputstring(char *); | |
| static void popfile(void); | |
| @@ -1734,7 +1732,7 @@ static void popallfiles(void); | |
| static void closescript(void); | |
| - | /* $NetBSD: jobs.h,v 1.17 2003/01/22 20:36:04 dsl Exp $ */ |
| + | /* jobs.h */ |
| /* Mode argument to forkshell. Don't change FORK_FG or FORK_BG. */ | |
| @@ -1801,18 +1799,19 @@ static void setjobctl(int); | |
| static void showjobs(FILE *, int); | |
| #endif | |
| - | /* $NetBSD: main.h,v 1.9 2002/11/24 22:35:41 christos Exp $ */ |
| + | /* main.h */ |
| /* pid of main shell */ | |
| static int rootpid; | |
| - | /* true if we aren't a child of the main shell */ |
| - | static int rootshell; |
| + | /* shell level: 0 for the main shell, 1 for its children, and so on */ |
| + | static int shlvl; |
| + | #define rootshell (!shlvl) |
| static void readcmdfile(char *); | |
| - | static void cmdloop(int); |
| + | static int cmdloop(int); |
| - | /* $NetBSD: memalloc.h,v 1.13 2003/01/22 20:36:04 dsl Exp $ */ |
| + | /* memalloc.h */ |
| struct stackmark { | |
| @@ -1853,7 +1852,7 @@ static char *stnputs(const char *, size_t, char *); | |
| static char *stputs(const char *, char *); | |
| - | static inline char *_STPUTC(char c, char *p) { |
| + | static inline char *_STPUTC(int c, char *p) { |
| if (p == sstrend) | |
| p = growstackstr(); | |
| *p++ = c; | |
| @@ -1885,7 +1884,7 @@ static inline char *_STPUTC(char c, char *p) { | |
| #define ckfree(p) free((pointer)(p)) | |
| - | /* $NetBSD: mystring.h,v 1.10 2002/11/24 22:35:42 christos Exp $ */ |
| + | /* mystring.h */ |
| #define DOLATSTRLEN 4 | |
| @@ -1899,7 +1898,7 @@ static char *sstrdup(const char *); | |
| #define equal(s1, s2) (strcmp(s1, s2) == 0) | |
| #define scopy(s1, s2) ((void)strcpy(s2, s1)) | |
| - | /* $NetBSD: options.h,v 1.16 2003/01/22 20:36:04 dsl Exp $ */ |
| + | /* options.h */ |
| struct shparam { | |
| int nparam; /* # of positional parameters (without $0) */ | |
| @@ -1925,19 +1924,18 @@ struct shparam { | |
| #define aflag optlist[10] | |
| #define bflag optlist[11] | |
| #define uflag optlist[12] | |
| - | #define qflag optlist[13] |
| - | #define viflag optlist[14] |
| + | #define viflag optlist[13] |
| #ifdef DEBUG | |
| - | #define nolog optlist[15] |
| - | #define debug optlist[16] |
| + | #define nolog optlist[14] |
| + | #define debug optlist[15] |
| #endif | |
| #ifndef CONFIG_FEATURE_COMMAND_EDITING_VI | |
| #define setvimode(on) viflag = 0 /* forcibly keep the option off */ | |
| #endif | |
| - | /* $NetBSD: options.c,v 1.33 2003/01/22 20:36:04 dsl Exp $ */ |
| + | /* options.c */ |
| static const char *const optletters_optnames[] = { | |
| @@ -1954,7 +1952,6 @@ static const char *const optletters_optnames[] = { | |
| "a" "allexport", | |
| "b" "notify", | |
| "u" "nounset", | |
| - | "q" "quietprofile", |
| "\0" "vi", | |
| #ifdef DEBUG | |
| "\0" "nolog", | |
| @@ -1987,7 +1984,7 @@ static int shiftcmd(int, char **); | |
| static int setcmd(int, char **); | |
| static int nextopt(const char *); | |
| - | /* $NetBSD: redir.h,v 1.14 2002/11/24 22:35:43 christos Exp $ */ |
| + | /* redir.h */ |
| /* flags passed to redirect */ | |
| #define REDIR_PUSH 01 /* save previous values of file descriptors */ | |
| @@ -2000,7 +1997,7 @@ static void clearredir(int); | |
| static int copyfd(int, int); | |
| static int redirectsafe(union node *, int); | |
| - | /* $NetBSD: show.h,v 1.6 2003/01/22 20:36:04 dsl Exp $ */ |
| + | /* show.h */ |
| #ifdef DEBUG | |
| @@ -2013,7 +2010,7 @@ static void trputs(const char *); | |
| static void opentrace(void); | |
| #endif | |
| - | /* $NetBSD: trap.h,v 1.16 2002/11/24 22:35:43 christos Exp $ */ |
| + | /* trap.h */ |
| /* trap handler commands */ | |
| @@ -2027,7 +2024,7 @@ static void clear_traps(void); | |
| static void setsignal(int); | |
| static void ignoresig(int); | |
| static void onsig(int); | |
| - | static void dotrap(void); |
| + | static int dotrap(void); |
| static void setinteractive(int); | |
| static void exitshell(void) __attribute__((__noreturn__)); | |
| static int decode_signal(const char *, int); | |
| @@ -2044,7 +2041,6 @@ reset(void) | |
| { | |
| evalskip = 0; | |
| loopnest = 0; | |
| - | funcnest = 0; |
| } | |
| /* from input.c: */ | |
| @@ -2250,7 +2246,7 @@ __lookupalias(const char *name) { | |
| #endif /* CONFIG_ASH_ALIAS */ | |
| - | /* $NetBSD: cd.c,v 1.30 2003/01/22 20:36:03 dsl Exp $ */ |
| + | /* cd.c */ |
| /* | |
| * The cd and pwd commands. | |
| @@ -2337,7 +2333,7 @@ docd: | |
| break; | |
| } | |
| } while (path); | |
| - | error("can't cd to %s", dest); |
| + | sh_error("can't cd to %s", dest); |
| /* NOTREACHED */ | |
| out: | |
| if (flags & CD_PRINT) | |
| @@ -2495,7 +2491,7 @@ setpwd(const char *val, int setold) | |
| setvar("PWD", dir, VEXPORT); | |
| } | |
| - | /* $NetBSD: error.c,v 1.30 2003/01/22 20:36:03 dsl Exp $ */ |
| + | /* error.c */ |
| /* | |
| * Errors and exceptions. | |
| @@ -2602,7 +2598,7 @@ exverror(int cond, const char *msg, va_list ap) | |
| static void | |
| - | error(const char *msg, ...) |
| + | sh_error(const char *msg, ...) |
| { | |
| va_list ap; | |
| @@ -2656,7 +2652,7 @@ errmsg(int e, const char *em) | |
| } | |
| - | /* $NetBSD: eval.c,v 1.71 2003/01/23 03:33:16 rafal Exp $ */ |
| + | /* eval.c */ |
| /* | |
| * Evaluate a command. | |
| @@ -2715,7 +2711,8 @@ evalcmd(int argc, char **argv) | |
| STPUTC('\0', concat); | |
| p = grabstackstr(concat); | |
| } | |
| - | evalstring(p); |
| + | evalstring(p, ~SKIPEVAL); |
| + | |
| } | |
| return exitstatus; | |
| } | |
| @@ -2725,23 +2722,29 @@ evalcmd(int argc, char **argv) | |
| * Execute a command or commands contained in a string. | |
| */ | |
| - | static void |
| - | evalstring(char *s) |
| + | static int |
| + | evalstring(char *s, int mask) |
| { | |
| union node *n; | |
| struct stackmark smark; | |
| + | int skip; |
| - | setstackmark(&smark); |
| setinputstring(s); | |
| + | setstackmark(&smark); |
| + | skip = 0; |
| while ((n = parsecmd(0)) != NEOF) { | |
| evaltree(n, 0); | |
| popstackmark(&smark); | |
| - | if (evalskip) |
| + | skip = evalskip; |
| + | if (skip) |
| break; | |
| } | |
| popfile(); | |
| - | popstackmark(&smark); |
| + | |
| + | skip &= mask; |
| + | evalskip = skip; |
| + | return skip; |
| } | |
| @@ -2853,10 +2856,15 @@ setstatus: | |
| break; | |
| } | |
| out: | |
| - | if (pendingsigs) |
| - | dotrap(); |
| - | if (flags & EV_EXIT || checkexit & exitstatus) |
| + | if ((checkexit & exitstatus)) |
| + | evalskip |= SKIPEVAL; |
| + | else if (pendingsigs && dotrap()) |
| + | goto exexit; |
| + | |
| + | if (flags & EV_EXIT) { |
| + | exexit: |
| exraise(EXEXIT); | |
| + | } |
| } | |
| @@ -3071,7 +3079,7 @@ evalpipe(union node *n, int flags) | |
| if (lp->next) { | |
| if (pipe(pip) < 0) { | |
| close(prevfd); | |
| - | error("Pipe call failed"); |
| + | sh_error("Pipe call failed"); |
| } | |
| } | |
| if (forkshell(jp, lp->n, n->npipe.backgnd) == 0) { | |
| @@ -3132,7 +3140,7 @@ evalbackcmd(union node *n, struct backcmd *result) | |
| struct job *jp; | |
| if (pipe(pip) < 0) | |
| - | error("Pipe call failed"); |
| + | sh_error("Pipe call failed"); |
| jp = makejob(n, 1); | |
| if (forkshell(jp, n, FORK_NOJOB) == 0) { | |
| FORCEINTON; | |
| @@ -3485,6 +3493,7 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags) | |
| localvars = NULL; | |
| shellparam.malloc = 0; | |
| func->count++; | |
| + | funcnest++; |
| INTON; | |
| shellparam.nparam = argc - 1; | |
| shellparam.p = argv + 1; | |
| @@ -3492,11 +3501,10 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags) | |
| shellparam.optind = 1; | |
| shellparam.optoff = -1; | |
| #endif | |
| - | funcnest++; |
| evaltree(&func->n, flags & EV_TESTED); | |
| - | funcnest--; |
| funcdone: | |
| INTOFF; | |
| + | funcnest--; |
| freefunc(func); | |
| poplocalvars(); | |
| localvars = savelocalvars; | |
| @@ -3504,10 +3512,7 @@ funcdone: | |
| shellparam = saveparam; | |
| handler = savehandler; | |
| INTON; | |
| - | if (evalskip == SKIPFUNC) { |
| - | evalskip = 0; |
| - | skipcount = 0; |
| - | } |
| + | evalskip &= ~SKIPFUNC; |
| return e; | |
| } | |
| @@ -3575,7 +3580,7 @@ breakcmd(int argc, char **argv) | |
| int n = argc > 1 ? number(argv[1]) : 1; | |
| if (n <= 0) | |
| - | error(illnum, argv[1]); |
| + | sh_error(illnum, argv[1]); |
| if (n > loopnest) | |
| n = loopnest; | |
| if (n > 0) { | |
| @@ -3593,19 +3598,12 @@ breakcmd(int argc, char **argv) | |
| static int | |
| returncmd(int argc, char **argv) | |
| { | |
| - | int ret = argc > 1 ? number(argv[1]) : exitstatus; |
| - | |
| - | if (funcnest) { |
| - | evalskip = SKIPFUNC; |
| - | skipcount = 1; |
| - | return ret; |
| - | } |
| - | else { |
| - | /* Do what ksh does; skip the rest of the file */ |
| - | evalskip = SKIPFILE; |
| - | skipcount = 1; |
| - | return ret; |
| - | } |
| + | /* |
| + | * If called outside a function, do what ksh does; |
| + | * skip the rest of the file. |
| + | */ |
| + | evalskip = funcnest ? SKIPFUNC : SKIPFILE; |
| + | return argv[1] ? number(argv[1]) : exitstatus; |
| } | |
| @@ -3636,7 +3634,7 @@ execcmd(int argc, char **argv) | |
| } | |
| - | /* $NetBSD: exec.c,v 1.35 2003/01/22 20:36:04 dsl Exp $ */ |
| + | /* exec.c */ |
| /* | |
| * When commands are first encountered, they are entered in a hash table. | |
| @@ -3682,6 +3680,7 @@ shellexec(char **argv, const char *path, int idx) | |
| char *cmdname; | |
| int e; | |
| char **envp; | |
| + | int exerrno; |
| clearredir(1); | |
| envp = environment(); | |
| @@ -3716,6 +3715,7 @@ shellexec(char **argv, const char *path, int idx) | |
| exerrno = 2; | |
| break; | |
| } | |
| + | exitstatus = exerrno; |
| TRACE(("shellexec failed for %s, errno %d, suppressint %d\n", | |
| argv[0], e, suppressint )); | |
| exerror(EXEXEC, "%s: %s", argv[0], errmsg(e, E_EXEC)); | |
| @@ -4004,7 +4004,7 @@ loop: | |
| readcmdfile(fullname); | |
| if ((cmdp = cmdlookup(name, 0)) == NULL || | |
| cmdp->cmdtype != CMDFUNCTION) | |
| - | error("%s not defined in %s", name, fullname); |
| + | sh_error("%s not defined in %s", name, fullname); |
| stunalloc(fullname); | |
| goto success; | |
| } | |
| @@ -4438,46 +4438,28 @@ static int | |
| commandcmd(int argc, char **argv) | |
| { | |
| int c; | |
| - | int default_path = 0; |
| - | int verify_only = 0; |
| - | int verbose_verify_only = 0; |
| + | enum { |
| + | VERIFY_BRIEF = 1, |
| + | VERIFY_VERBOSE = 2, |
| + | } verify = 0; |
| while ((c = nextopt("pvV")) != '\0') | |
| - | switch (c) { |
| - | default: |
| + | if (c == 'V') |
| + | verify |= VERIFY_VERBOSE; |
| + | else if (c == 'v') |
| + | verify |= VERIFY_BRIEF; |
| #ifdef DEBUG | |
| - | fprintf(stderr, |
| - | "command: nextopt returned character code 0%o\n", c); |
| - | return EX_SOFTWARE; |
| + | else if (c != 'p') |
| + | abort(); |
| #endif | |
| - | case 'p': |
| - | default_path = 1; |
| - | break; |
| - | case 'v': |
| - | verify_only = 1; |
| - | break; |
| - | case 'V': |
| - | verbose_verify_only = 1; |
| - | break; |
| - | } |
| - | |
| - | if (default_path + verify_only + verbose_verify_only > 1 || |
| - | !*argptr) { |
| - | fprintf(stderr, |
| - | "command [-p] command [arg ...]\n" |
| - | "command {-v|-V} command\n"); |
| - | return EX_USAGE; |
| - | } |
| - | |
| - | if (verify_only || verbose_verify_only) { |
| - | return describe_command(*argptr, verbose_verify_only); |
| - | } |
| + | if (verify) |
| + | return describe_command(*argptr, verify - VERIFY_BRIEF); |
| return 0; | |
| } | |
| #endif | |
| - | /* $NetBSD: expand.c,v 1.56 2002/11/24 22:35:39 christos Exp $ */ |
| + | /* expand.c */ |
| /* | |
| * Routines to expand arguments to commands. We have to deal with | |
| @@ -4806,14 +4788,13 @@ exptilde(char *startp, char *p, int flag) | |
| done: | |
| *p = '\0'; | |
| if (*name == '\0') { | |
| - | if ((home = lookupvar(homestr)) == NULL) |
| - | goto lose; |
| + | home = lookupvar(homestr); |
| } else { | |
| if ((pw = getpwnam(name)) == NULL) | |
| goto lose; | |
| home = pw->pw_dir; | |
| } | |
| - | if (*home == '\0') |
| + | if (!home || !*home) |
| goto lose; | |
| *p = c; | |
| startloc = expdest - (char *)stackblock(); | |
| @@ -4897,7 +4878,7 @@ expari(int quotes) | |
| p--; | |
| #ifdef DEBUG | |
| if (p < start) { | |
| - | error("missing CTLARI (shouldn't happen)"); |
| + | sh_error("missing CTLARI (shouldn't happen)"); |
| } | |
| #endif | |
| } | |
| @@ -5275,7 +5256,7 @@ memtodest(const char *p, size_t len, int syntax, int quotes) { | |
| q = makestrspace(len * 2, q); | |
| while (len--) { | |
| - | int c = *p++; |
| + | int c = (unsigned char)*p++; |
| if (!c) | |
| continue; | |
| if (quotes && (SIT(c, syntax) == CCTL || SIT(c, syntax) == CBACK)) | |
| @@ -5932,11 +5913,11 @@ varunset(const char *end, const char *var, const char *umsg, int varflags) | |
| } else | |
| msg = umsg; | |
| } | |
| - | error("%.*s: %s%s", end - var - 1, var, msg, tail); |
| + | sh_error("%.*s: %s%s", end - var - 1, var, msg, tail); |
| } | |
| - | /* $NetBSD: input.c,v 1.37 2002/11/24 22:35:40 christos Exp $ */ |
| + | /* input.c */ |
| /* | |
| * This implements the input routines used by the parser. | |
| @@ -6103,7 +6084,7 @@ retry: | |
| int | |
| preadbuffer(void) | |
| { | |
| - | char *p, *q; |
| + | char *q; |
| int more; | |
| char savec; | |
| @@ -6122,39 +6103,42 @@ preadbuffer(void) | |
| return PEOF; | |
| flushall(); | |
| + | more = parselleft; |
| + | if (more <= 0) { |
| again: | |
| - | if (parselleft <= 0) { |
| - | if ((parselleft = preadfd()) <= 0) { |
| + | if ((more = preadfd()) <= 0) { |
| parselleft = parsenleft = EOF_NLEFT; | |
| return PEOF; | |
| } | |
| } | |
| - | q = p = parsenextc; |
| + | q = parsenextc; |
| /* delete nul characters */ | |
| - | for (more = 1; more;) { |
| - | switch (*p) { |
| - | case '\0': |
| - | p++; /* Skip nul */ |
| - | goto check; |
| + | for (;;) { |
| + | int c; |
| - | case '\n': |
| - | parsenleft = q - parsenextc; |
| - | more = 0; /* Stop processing here */ |
| - | break; |
| + | more--; |
| + | c = *q; |
| + | if (!c) |
| + | memmove(q, q + 1, more); |
| + | else { |
| + | q++; |
| + | if (c == '\n') { |
| + | parsenleft = q - parsenextc - 1; |
| + | break; |
| + | } |
| } | |
| - | *q++ = *p++; |
| - | check: |
| - | if (--parselleft <= 0 && more) { |
| + | if (more <= 0) { |
| parsenleft = q - parsenextc - 1; | |
| if (parsenleft < 0) | |
| goto again; | |
| - | more = 0; |
| + | break; |
| } | |
| } | |
| + | parselleft = more; |
| savec = *q; | |
| *q = '\0'; | |
| @@ -6247,24 +6231,29 @@ popstring(void) | |
| * old input onto the stack first. | |
| */ | |
| - | void |
| - | setinputfile(const char *fname, int push) |
| + | static int |
| + | setinputfile(const char *fname, int flags) |
| { | |
| int fd; | |
| int fd2; | |
| INTOFF; | |
| - | if ((fd = open(fname, O_RDONLY)) < 0) |
| - | error("Can't open %s", fname); |
| + | if ((fd = open(fname, O_RDONLY)) < 0) { |
| + | if (flags & INPUT_NOFILE_OK) |
| + | goto out; |
| + | sh_error("Can't open %s", fname); |
| + | } |
| if (fd < 10) { | |
| fd2 = copyfd(fd, 10); | |
| close(fd); | |
| if (fd2 < 0) | |
| - | error("Out of file descriptors"); |
| + | sh_error("Out of file descriptors"); |
| fd = fd2; | |
| } | |
| - | setinputfd(fd, push); |
| + | setinputfd(fd, flags & INPUT_PUSH_FILE); |
| + | out: |
| INTON; | |
| + | return fd; |
| } | |
| @@ -6378,7 +6367,7 @@ closescript(void) | |
| } | |
| } | |
| - | /* $NetBSD: jobs.c,v 1.56 2002/11/25 12:13:03 agc Exp $ */ |
| + | /* jobs.c */ |
| /* mode flags for set_curjob */ | |
| #define CUR_DELETE 2 | |
| @@ -6453,14 +6442,14 @@ set_curjob(struct job *jp, unsigned mode) | |
| put after all stopped jobs. */ | |
| do { | |
| jp1 = *jpp; | |
| - | #ifdef JOBS |
| + | #if JOBS |
| if (!jp1 || jp1->state != JOBSTOPPED) | |
| #endif | |
| break; | |
| jpp = &jp1->prev_job; | |
| } while (1); | |
| /* FALLTHROUGH */ | |
| - | #ifdef JOBS |
| + | #if JOBS |
| case CUR_STOPPED: | |
| #endif | |
| /* newly stopped job - becomes curjob */ | |
| @@ -6549,7 +6538,7 @@ killcmd(int argc, char **argv) | |
| if (argc <= 1) { | |
| usage: | |
| - | error( |
| + | sh_error( |
| "Usage: kill [-s sigspec | -signum | -sigspec] [pid | job]... or\n" | |
| "kill -l [exitstatus]" | |
| ); | |
| @@ -6572,7 +6561,7 @@ usage: | |
| case 's': | |
| signo = decode_signal(optionarg, 1); | |
| if (signo < 0) { | |
| - | error( |
| + | sh_error( |
| "invalid signal number or name: %s", | |
| optionarg | |
| ); | |
| @@ -6606,7 +6595,7 @@ usage: | |
| if (name) | |
| out1fmt(snlfmt, name); | |
| else | |
| - | error("invalid signal number or exit status: %s", *argptr); |
| + | sh_error("invalid signal number or exit status: %s", *argptr); |
| return 0; | |
| } | |
| @@ -6637,7 +6626,7 @@ jobno(const struct job *jp) | |
| } | |
| #endif | |
| - | #ifdef JOBS |
| + | #if JOBS |
| static int | |
| fgcmd(int argc, char **argv) | |
| { | |
| @@ -7020,7 +7009,7 @@ gotit: | |
| #endif | |
| return jp; | |
| err: | |
| - | error(err_msg, name); |
| + | sh_error(err_msg, name); |
| } | |
| @@ -7132,18 +7121,18 @@ growjobtab(void) | |
| static inline void | |
| forkchild(struct job *jp, union node *n, int mode) | |
| { | |
| - | int wasroot; |
| + | int oldlvl; |
| TRACE(("Child shell %d\n", getpid())); | |
| - | wasroot = rootshell; |
| - | rootshell = 0; |
| + | oldlvl = shlvl; |
| + | shlvl++; |
| closescript(); | |
| clear_traps(); | |
| #if JOBS | |
| /* do job control only in root shell */ | |
| jobctl = 0; | |
| - | if (mode != FORK_NOJOB && jp->jobctl && wasroot) { |
| + | if (mode != FORK_NOJOB && jp->jobctl && !oldlvl) { |
| pid_t pgrp; | |
| if (jp->nprocs == 0) | |
| @@ -7164,10 +7153,10 @@ forkchild(struct job *jp, union node *n, int mode) | |
| if (jp->nprocs == 0) { | |
| close(0); | |
| if (open(_PATH_DEVNULL, O_RDONLY) != 0) | |
| - | error("Can't open %s", _PATH_DEVNULL); |
| + | sh_error("Can't open %s", _PATH_DEVNULL); |
| } | |
| } | |
| - | if (wasroot && iflag) { |
| + | if (!oldlvl && iflag) { |
| setsignal(SIGINT); | |
| setsignal(SIGQUIT); | |
| setsignal(SIGTERM); | |
| @@ -7225,7 +7214,7 @@ forkshell(struct job *jp, union node *n, int mode) | |
| TRACE(("Fork failed, errno=%d", errno)); | |
| if (jp) | |
| freejob(jp); | |
| - | error("Cannot fork"); |
| + | sh_error("Cannot fork"); |
| } | |
| if (pid == 0) | |
| forkchild(jp, n, mode); | |
| @@ -7365,7 +7354,7 @@ dowait(int block, struct job *job) | |
| } | |
| if (sp->status == -1) | |
| state = JOBRUNNING; | |
| - | #ifdef JOBS |
| + | #if JOBS |
| if (state == JOBRUNNING) | |
| continue; | |
| if (WIFSTOPPED(sp->status)) { | |
| @@ -7377,7 +7366,7 @@ dowait(int block, struct job *job) | |
| if (thisjob) | |
| goto gotjob; | |
| } | |
| - | #ifdef JOBS |
| + | #if JOBS |
| if (!WIFSTOPPED(status)) | |
| #endif | |
| @@ -7391,7 +7380,7 @@ gotjob: | |
| if (thisjob->state != state) { | |
| TRACE(("Job %d: changing state from %d to %d\n", jobno(thisjob), thisjob->state, state)); | |
| thisjob->state = state; | |
| - | #ifdef JOBS |
| + | #if JOBS |
| if (state == JOBSTOPPED) { | |
| set_curjob(thisjob, CUR_STOPPED); | |
| } | |
| @@ -7739,7 +7728,7 @@ static void | |
| xtcsetpgrp(int fd, pid_t pgrp) | |
| { | |
| if (tcsetpgrp(fd, pgrp)) | |
| - | error("Cannot set tty process group (%m)"); |
| + | sh_error("Cannot set tty process group (%m)"); |
| } | |
| #endif /* JOBS */ | |
| @@ -7771,7 +7760,7 @@ getstatus(struct job *job) { | |
| } | |
| #ifdef CONFIG_ASH_MAIL | |
| - | /* $NetBSD: mail.c,v 1.15 2002/11/24 22:35:40 christos Exp $ */ |
| + | /* mail.c */ |
| /* | |
| * Routines to check for mail. (Perhaps make part of main.c?) | |
| @@ -7842,7 +7831,7 @@ changemail(const char *val) | |
| #endif /* CONFIG_ASH_MAIL */ | |
| - | /* $NetBSD: main.c,v 1.46 2002/12/11 19:12:18 christos Exp $ */ |
| + | /* main.c */ |
| #if PROFILE | |
| @@ -7879,28 +7868,16 @@ ash_main(int argc, char **argv) | |
| #endif | |
| state = 0; | |
| if (setjmp(jmploc.loc)) { | |
| - | int status; |
| int e; | |
| + | int s; |
| reset(); | |
| e = exception; | |
| - | switch (exception) { |
| - | case EXEXEC: |
| - | status = exerrno; |
| - | break; |
| - | |
| - | case EXERROR: |
| - | status = 2; |
| - | break; |
| - | |
| - | default: |
| - | status = exitstatus; |
| - | break; |
| - | } |
| - | exitstatus = status; |
| - | |
| - | if (e == EXEXIT || state == 0 || iflag == 0 || ! rootshell) |
| + | if (e == EXERROR) |
| + | exitstatus = 2; |
| + | s = state; |
| + | if (e == EXEXIT || s == 0 || iflag == 0 || shlvl) |
| exitshell(); | |
| if (e == EXINT) { | |
| @@ -7908,11 +7885,11 @@ ash_main(int argc, char **argv) | |
| } | |
| popstackmark(&smark); | |
| FORCEINTON; /* enable interrupts */ | |
| - | if (state == 1) |
| + | if (s == 1) |
| goto state1; | |
| - | else if (state == 2) |
| + | else if (s == 2) |
| goto state2; | |
| - | else if (state == 3) |
| + | else if (s == 3) |
| goto state3; | |
| else | |
| goto state4; | |
| @@ -7927,7 +7904,6 @@ ash_main(int argc, char **argv) | |
| #ifdef CONFIG_ASH_RANDOM_SUPPORT | |
| rseed = rootpid + ((time_t)time((time_t *)0)); | |
| #endif | |
| - | rootshell = 1; |
| init(); | |
| setstackmark(&smark); | |
| procargs(argc, argv); | |
| @@ -7969,7 +7945,7 @@ state2: | |
| state3: | |
| state = 4; | |
| if (minusc) | |
| - | evalstring(minusc); |
| + | evalstring(minusc, 0); |
| if (sflag || minusc == NULL) { | |
| #ifdef CONFIG_FEATURE_COMMAND_SAVEHISTORY | |
| @@ -8002,7 +7978,7 @@ state4: /* XXX ??? - why isn't this before the "if" statement */ | |
| * loop; it turns on prompting if the shell is interactive. | |
| */ | |
| - | static void |
| + | static int |
| cmdloop(int top) | |
| { | |
| union node *n; | |
| @@ -8012,9 +7988,9 @@ cmdloop(int top) | |
| TRACE(("cmdloop(%d) called\n", top)); | |
| for (;;) { | |
| + | int skip; |
| + | |
| setstackmark(&smark); | |
| - | if (pendingsigs) |
| - | dotrap(); |
| #if JOBS | |
| if (jobctl) | |
| showjobs(stderr, SHOW_CHANGED); | |
| @@ -8037,17 +8013,21 @@ cmdloop(int top) | |
| out2str("\nUse \"exit\" to leave shell.\n"); | |
| } | |
| numeof++; | |
| - | } else if (n != NULL && nflag == 0) { |
| + | } else if (nflag == 0) { |
| job_warning = (job_warning == 2) ? 1 : 0; | |
| numeof = 0; | |
| evaltree(n, 0); | |
| } | |
| popstackmark(&smark); | |
| - | if (evalskip) { |
| + | skip = evalskip; |
| + | |
| + | if (skip) { |
| evalskip = 0; | |
| - | break; |
| + | return skip & SKIPEVAL; |
| } | |
| } | |
| + | |
| + | return 0; |
| } | |
| @@ -8058,31 +8038,16 @@ cmdloop(int top) | |
| static void | |
| read_profile(const char *name) | |
| { | |
| - | int fd; |
| - | int xflag_set = 0; |
| - | int vflag_set = 0; |
| + | int skip; |
| - | INTOFF; |
| - | if ((fd = open(name, O_RDONLY)) >= 0) |
| - | setinputfd(fd, 1); |
| - | INTON; |
| - | if (fd < 0) |
| + | if (setinputfile(name, INPUT_PUSH_FILE | INPUT_NOFILE_OK) < 0) |
| return; | |
| - | /* -q turns off -x and -v just when executing init files */ |
| - | if (qflag) { |
| - | if (xflag) |
| - | xflag = 0, xflag_set = 1; |
| - | if (vflag) |
| - | vflag = 0, vflag_set = 1; |
| - | } |
| - | cmdloop(0); |
| - | if (qflag) { |
| - | if (xflag_set) |
| - | xflag = 1; |
| - | if (vflag_set) |
| - | vflag = 1; |
| - | } |
| + | |
| + | skip = cmdloop(0); |
| popfile(); | |
| + | |
| + | if (skip) |
| + | exitshell(); |
| } | |
| @@ -8093,14 +8058,7 @@ read_profile(const char *name) | |
| static void | |
| readcmdfile(char *name) | |
| { | |
| - | int fd; |
| - | |
| - | INTOFF; |
| - | if ((fd = open(name, O_RDONLY)) >= 0) |
| - | setinputfd(fd, 1); |
| - | else |
| - | error("Can't open %s", name); |
| - | INTON; |
| + | setinputfile(name, INPUT_PUSH_FILE); |
| cmdloop(0); | |
| popfile(); | |
| } | |
| @@ -8134,7 +8092,7 @@ find_dot_file(char *name) | |
| } | |
| /* not found in the PATH */ | |
| - | error(not_found_msg, name); |
| + | sh_error(not_found_msg, name); |
| /* NOTREACHED */ | |
| } | |
| @@ -8142,17 +8100,14 @@ static int dotcmd(int argc, char **argv) | |
| { | |
| struct strlist *sp; | |
| volatile struct shparam saveparam; | |
| - | |
| - | exitstatus = 0; |
| + | int status = 0; |
| for (sp = cmdenviron; sp; sp = sp->next) | |
| setvareq(bb_xstrdup(sp->text), VSTRFIXED | VTEXTFIXED); | |
| if (argc >= 2) { /* That's what SVR2 does */ | |
| char *fullname; | |
| - | struct stackmark smark; |
| - | setstackmark(&smark); |
| fullname = find_dot_file(argv[1]); | |
| if (argc > 2) { | |
| @@ -8162,7 +8117,7 @@ static int dotcmd(int argc, char **argv) | |
| shellparam.p = argv + 2; | |
| }; | |
| - | setinputfile(fullname, 1); |
| + | setinputfile(fullname, INPUT_PUSH_FILE); |
| commandname = fullname; | |
| cmdloop(0); | |
| popfile(); | |
| @@ -8171,10 +8126,9 @@ static int dotcmd(int argc, char **argv) | |
| freeparam(&shellparam); | |
| shellparam = saveparam; | |
| }; | |
| - | |
| - | popstackmark(&smark); |
| + | status = exitstatus; |
| } | |
| - | return exitstatus; |
| + | return status; |
| } | |
| @@ -8196,7 +8150,7 @@ echocmd(int argc, char **argv) | |
| return bb_echo(argc, argv); | |
| } | |
| #endif | |
| - | /* $NetBSD: memalloc.c,v 1.27 2003/01/22 20:36:04 dsl Exp $ */ |
| + | /* memalloc.c */ |
| /* | |
| * Same for malloc, realloc, but returns an error when out of space. | |
| @@ -8207,7 +8161,7 @@ ckrealloc(pointer p, size_t nbytes) | |
| { | |
| p = realloc(p, nbytes); | |
| if (p == NULL) | |
| - | error(bb_msg_memory_exhausted); |
| + | sh_error(bb_msg_memory_exhausted); |
| return p; | |
| } | |
| @@ -8226,7 +8180,7 @@ savestr(const char *s) | |
| { | |
| char *p = strdup(s); | |
| if (!p) | |
| - | error(bb_msg_memory_exhausted); |
| + | sh_error(bb_msg_memory_exhausted); |
| return p; | |
| } | |
| @@ -8258,7 +8212,7 @@ stalloc(size_t nbytes) | |
| blocksize = MINSIZE; | |
| len = sizeof(struct stack_block) - MINSIZE + blocksize; | |
| if (len < blocksize) | |
| - | error(bb_msg_memory_exhausted); |
| + | sh_error(bb_msg_memory_exhausted); |
| INTOFF; | |
| sp = ckmalloc(len); | |
| sp->prev = stackp; | |
| @@ -8336,7 +8290,7 @@ growstackblock(void) | |
| newlen = stacknleft * 2; | |
| if (newlen < stacknleft) | |
| - | error(bb_msg_memory_exhausted); |
| + | sh_error(bb_msg_memory_exhausted); |
| if (newlen < 128) | |
| newlen += 128; | |
| @@ -8456,7 +8410,7 @@ stputs(const char *s, char *p) | |
| return stnputs(s, strlen(s), p); | |
| } | |
| - | /* $NetBSD: mystring.c,v 1.15 2002/11/24 22:35:42 christos Exp $ */ |
| + | /* mystring.c */ |
| /* | |
| * String functions. | |
| @@ -8490,7 +8444,7 @@ number(const char *s) | |
| { | |
| if (! is_number(s)) | |
| - | error(illnum, s); |
| + | sh_error(illnum, s); |
| return atoi(s); | |
| } | |
| @@ -8815,7 +8769,7 @@ procargs(int argc, char **argv) | |
| xminusc = minusc; | |
| if (*xargv == NULL) { | |
| if (xminusc) | |
| - | error("-c requires an argument"); |
| + | sh_error("-c requires an argument"); |
| sflag = 1; | |
| } | |
| if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1)) | |
| @@ -8881,7 +8835,7 @@ minus_o(char *name, int val) | |
| optlist[i] = val; | |
| return; | |
| } | |
| - | error("Illegal option -o %s", name); |
| + | sh_error("Illegal option -o %s", name); |
| } | |
| } | |
| @@ -8949,7 +8903,7 @@ setoption(int flag, int val) | |
| optlist[i] = val; | |
| return; | |
| } | |
| - | error("Illegal option -%c", flag); |
| + | sh_error("Illegal option -%c", flag); |
| /* NOTREACHED */ | |
| } | |
| @@ -9015,7 +8969,7 @@ shiftcmd(int argc, char **argv) | |
| if (argc > 1) | |
| n = number(argv[1]); | |
| if (n > shellparam.nparam) | |
| - | error("can't shift that many"); |
| + | sh_error("can't shift that many"); |
| INTOFF; | |
| shellparam.nparam -= n; | |
| for (ap1 = shellparam.p ; --n >= 0 ; ap1++) { | |
| @@ -9203,7 +9157,7 @@ getoptscmd(int argc, char **argv) | |
| char **optbase; | |
| if (argc < 3) | |
| - | error("Usage: getopts optstring var [arg]"); |
| + | sh_error("Usage: getopts optstring var [arg]"); |
| else if (argc == 3) { | |
| optbase = shellparam.p; | |
| if (shellparam.optind > shellparam.nparam + 1) { | |
| @@ -9253,13 +9207,13 @@ nextopt(const char *optstring) | |
| c = *p++; | |
| for (q = optstring ; *q != c ; ) { | |
| if (*q == '\0') | |
| - | error("Illegal option -%c", c); |
| + | sh_error("Illegal option -%c", c); |
| if (*++q == ':') | |
| q++; | |
| } | |
| if (*++q == ':') { | |
| if (*p == '\0' && (p = *argptr++) == NULL) | |
| - | error("No arg for -%c option", c); |
| + | sh_error("No arg for -%c option", c); |
| optionarg = p; | |
| p = NULL; | |
| } | |
| @@ -9268,7 +9222,7 @@ nextopt(const char *optstring) | |
| } | |
| - | /* $NetBSD: output.c,v 1.27 2002/11/24 22:35:42 christos Exp $ */ |
| + | /* output.c */ |
| void | |
| outstr(const char *p, FILE *file) | |
| @@ -9336,7 +9290,7 @@ fmtstr(char *outbuf, size_t length, const char *fmt, ...) | |
| - | /* $NetBSD: parser.c,v 1.54 2002/11/24 22:35:42 christos Exp $ */ |
| + | /* parser.c */ |
| /* | |
| @@ -10855,7 +10809,7 @@ static void synexpect(int token) | |
| static void | |
| synerror(const char *msg) | |
| { | |
| - | error("Syntax error: %s", msg); |
| + | sh_error("Syntax error: %s", msg); |
| /* NOTREACHED */ | |
| } | |
| @@ -10923,7 +10877,7 @@ static const char *const *findkwd(const char *s) | |
| sizeof(const char *), pstrcmp); | |
| } | |
| - | /* $NetBSD: redir.c,v 1.27 2002/11/24 22:35:42 christos Exp $ */ |
| + | /* redir.c */ |
| /* | |
| * Code for dealing with input/output redirection. | |
| @@ -11007,7 +10961,7 @@ openhere(union node *redir) | |
| size_t len = 0; | |
| if (pipe(pip) < 0) | |
| - | error("Pipe call failed"); |
| + | sh_error("Pipe call failed"); |
| if (redir->type == NHERE) { | |
| len = strlen(redir->nhere.doc->narg.text); | |
| if (len <= PIPESIZE) { | |
| @@ -11088,9 +11042,9 @@ openredirect(union node *redir) | |
| return f; | |
| ecreate: | |
| - | error("cannot create %s: %s", fname, errmsg(errno, E_CREAT)); |
| + | sh_error("cannot create %s: %s", fname, errmsg(errno, E_CREAT)); |
| eopen: | |
| - | error("cannot open %s: %s", fname, errmsg(errno, E_OPEN)); |
| + | sh_error("cannot open %s: %s", fname, errmsg(errno, E_OPEN)); |
| } | |
| static inline void | |
| @@ -11164,7 +11118,7 @@ redirect(union node *redir, int flags) | |
| if (i != EBADF) { | |
| close(newfd); | |
| errno = i; | |
| - | error("%d: %m", fd); |
| + | sh_error("%d: %m", fd); |
| /* NOTREACHED */ | |
| } | |
| } else { | |
| @@ -11247,7 +11201,7 @@ copyfd(int from, int to) | |
| if (errno == EMFILE) | |
| return EMPTY; | |
| else | |
| - | error("%d: %m", from); |
| + | sh_error("%d: %m", from); |
| } | |
| return newfd; | |
| } | |
| @@ -11273,7 +11227,7 @@ redirectsafe(union node *redir, int flags) | |
| return err; | |
| } | |
| - | /* $NetBSD: show.c,v 1.24 2003/01/22 20:36:04 dsl Exp $ */ |
| + | /* show.c */ |
| #ifdef DEBUG | |
| static void shtree(union node *, int, char *, FILE*); | |
| @@ -11620,7 +11574,7 @@ opentrace(void) | |
| #endif /* DEBUG */ | |
| - | /* $NetBSD: trap.c,v 1.28 2002/11/24 22:35:43 christos Exp $ */ |
| + | /* trap.c */ |
| /* | |
| * Sigmode records the current value of the signal handlers for the various | |
| @@ -11669,7 +11623,7 @@ trapcmd(int argc, char **argv) | |
| action = *ap++; | |
| while (*ap) { | |
| if ((signo = decode_signal(*ap, 0)) < 0) | |
| - | error("%s: bad trap", *ap); |
| + | sh_error("%s: bad trap", *ap); |
| INTOFF; | |
| if (action) { | |
| if (action[0] == '-' && action[1] == '\0') | |
| @@ -11834,23 +11788,34 @@ onsig(int signo) | |
| * handlers while we are executing a trap handler. | |
| */ | |
| - | void |
| + | int |
| dotrap(void) | |
| { | |
| char *p; | |
| char *q; | |
| + | int i; |
| int savestatus; | |
| + | int skip = 0; |
| savestatus = exitstatus; | |
| - | q = gotsig; |
| - | while (pendingsigs = 0, xbarrier(), (p = memchr(q, 1, NSIG - 1))) { |
| - | *p = 0; |
| - | p = trap[p - q + 1]; |
| + | pendingsigs = 0; |
| + | xbarrier(); |
| + | |
| + | for (i = 0, q = gotsig; i < NSIG - 1; i++, q++) { |
| + | if (!*q) |
| + | continue; |
| + | *q = 0; |
| + | |
| + | p = trap[i + 1]; |
| if (!p) | |
| continue; | |
| - | evalstring(p); |
| + | skip = evalstring(p, SKIPEVAL); |
| exitstatus = savestatus; | |
| + | if (skip) |
| + | break; |
| } | |
| + | |
| + | return skip; |
| } | |
| @@ -11931,17 +11896,18 @@ exitshell(void) | |
| struct jmploc loc; | |
| char *p; | |
| int status; | |
| - | int jmp; |
| - | jmp = setjmp(loc.loc); |
| status = exitstatus; | |
| TRACE(("pid %d, exitshell(%d)\n", getpid(), status)); | |
| - | if (jmp) |
| + | if (setjmp(loc.loc)) { |
| + | if (exception == EXEXIT) |
| + | _exit(exitstatus); |
| goto out; | |
| + | } |
| handler = &loc; | |
| - | if ((p = trap[0]) != NULL && *p != '\0') { |
| + | if ((p = trap[0])) { |
| trap[0] = NULL; | |
| - | evalstring(p); |
| + | evalstring(p, 0); |
| } | |
| flushall(); | |
| setjobctl(0); | |
| @@ -11966,7 +11932,7 @@ static int decode_signal(const char *string, int minsig) | |
| return name ? signo : -1; | |
| } | |
| - | /* $NetBSD: var.c,v 1.32 2003/01/22 20:36:04 dsl Exp $ */ |
| + | /* var.c */ |
| static struct var *vartab[VTABSIZE]; | |
| @@ -12022,7 +11988,7 @@ setvar(const char *name, const char *val, int flags) | |
| p = strchrnul(q, '='); | |
| namelen = p - name; | |
| if (!namelen || p != q) | |
| - | error("%.*s: bad variable name", namelen, name); |
| + | sh_error("%.*s: bad variable name", namelen, name); |
| vallen = 0; | |
| if (val == NULL) { | |
| flags |= VUNSET; | |
| @@ -12031,9 +11997,8 @@ setvar(const char *name, const char *val, int flags) | |
| } | |
| INTOFF; | |
| p = mempcpy(nameeq = ckmalloc(namelen + vallen + 2), name, namelen); | |
| - | *p++ = '\0'; |
| if (val) { | |
| - | p[-1] = '='; |
| + | *p++ = '='; |
| p = mempcpy(p, val, vallen); | |
| } | |
| *p = '\0'; | |
| @@ -12065,7 +12030,7 @@ setvareq(char *s, int flags) | |
| if (flags & VNOSAVE) | |
| free(s); | |
| n = vp->text; | |
| - | error("%.*s: is read only", strchrnul(n, '=') - n, n); |
| + | sh_error("%.*s: is read only", strchrnul(n, '=') - n, n); |
| } | |
| if (flags & VNOSET) | |
| @@ -12495,7 +12460,7 @@ findvar(struct var **vpp, const char *name) | |
| } | |
| return vpp; | |
| } | |
| - | /* $NetBSD: setmode.c,v 1.29 2003/01/15 23:58:03 kleink Exp $ */ |
| + | /* setmode.c */ |
| #include <sys/times.h> | |
| @@ -12540,11 +12505,11 @@ dash_arith(const char *s) | |
| result = arith(s, &errcode); | |
| if (errcode < 0) { | |
| if (errcode == -3) | |
| - | error("exponent less than 0"); |
| + | sh_error("exponent less than 0"); |
| else if (errcode == -2) | |
| - | error("divide by zero"); |
| + | sh_error("divide by zero"); |
| else if (errcode == -5) | |
| - | error("expression recursion loop detected"); |
| + | sh_error("expression recursion loop detected"); |
| else | |
| synerror(s); | |
| } | |
| @@ -12569,7 +12534,7 @@ letcmd(int argc, char **argv) | |
| ap = argv + 1; | |
| if(!*ap) | |
| - | error("expression expected"); |
| + | sh_error("expression expected"); |
| for (ap = argv + 1; *ap; ap++) { | |
| i = dash_arith(*ap); | |
| } | |
| @@ -12578,7 +12543,7 @@ letcmd(int argc, char **argv) | |
| } | |
| #endif /* CONFIG_ASH_MATH_SUPPORT */ | |
| - | /* $NetBSD: miscbltin.c,v 1.31 2002/11/24 22:35:41 christos Exp $ */ |
| + | /* miscbltin.c */ |
| /* | |
| * Miscellaneous builtins. | |
| @@ -12646,7 +12611,7 @@ readcmd(int argc, char **argv) | |
| case 'n': | |
| nchars = strtol(optionarg, &p, 10); | |
| if (*p) | |
| - | error("invalid count"); |
| + | sh_error("invalid count"); |
| nch_flag = (nchars > 0); | |
| break; | |
| case 's': | |
| @@ -12663,19 +12628,19 @@ readcmd(int argc, char **argv) | |
| int scale; | |
| ts.tv_usec = strtol(p, &p2, 10); | |
| if (*p2) | |
| - | error("invalid timeout"); |
| + | sh_error("invalid timeout"); |
| scale = p2 - p; | |
| /* normalize to usec */ | |
| if (scale > 6) | |
| - | error("invalid timeout"); |
| + | sh_error("invalid timeout"); |
| while (scale++ < 6) | |
| ts.tv_usec *= 10; | |
| } | |
| } else if (*p) { | |
| - | error("invalid timeout"); |
| + | sh_error("invalid timeout"); |
| } | |
| if ( ! ts.tv_sec && ! ts.tv_usec) | |
| - | error("invalid timeout"); |
| + | sh_error("invalid timeout"); |
| break; | |
| #endif | |
| case 'r': | |
| @@ -12689,7 +12654,7 @@ readcmd(int argc, char **argv) | |
| out2str(prompt); | |
| } | |
| if (*(ap = argptr) == NULL) | |
| - | error("arg count"); |
| + | sh_error("arg count"); |
| if ((ifs = bltinlookup("IFS")) == NULL) | |
| ifs = defifs; | |
| #if defined(CONFIG_ASH_READ_NCHARS) | |
| @@ -12832,14 +12797,14 @@ static int umaskcmd(int argc, char **argv) | |
| mask = 0; | |
| do { | |
| if (*ap >= '8' || *ap < '0') | |
| - | error(illnum, argv[1]); |
| + | sh_error(illnum, argv[1]); |
| mask = (mask << 3) + (*ap - '0'); | |
| } while (*++ap != '\0'); | |
| umask(mask); | |
| } else { | |
| mask = ~mask & 0777; | |
| if (!bb_parse_mode(ap, &mask)) { | |
| - | error("Illegal mode: %s", ap); |
| + | sh_error("Illegal mode: %s", ap); |
| } | |
| umask(~mask & 0777); | |
| } | |
| @@ -12989,7 +12954,7 @@ ulimitcmd(int argc, char **argv) | |
| char *p = *argptr; | |
| if (all || argptr[1]) | |
| - | error("too many arguments"); |
| + | sh_error("too many arguments"); |
| if (strncmp(p, "unlimited\n", 9) == 0) | |
| val = RLIM_INFINITY; | |
| else { | |
| @@ -13002,7 +12967,7 @@ ulimitcmd(int argc, char **argv) | |
| break; | |
| } | |
| if (c) | |
| - | error("bad number"); |
| + | sh_error("bad number"); |
| val *= l->factor; | |
| } | |
| } | |
| @@ -13022,7 +12987,7 @@ ulimitcmd(int argc, char **argv) | |
| if (how & SOFT) | |
| limit.rlim_cur = val; | |
| if (setrlimit(l->cmd, &limit) < 0) | |
| - | error("error setting limit (%m)"); |
| + | sh_error("error setting limit (%m)"); |
| } else { | |
| printlim(how, &limit, l); | |
| } | |