diff options
author | vda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2007-02-18 19:56:41 +0000 |
---|---|---|
committer | vda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2007-02-18 19:56:41 +0000 |
commit | 02af72fc98c373dce7b97ac5b133c3c2a9fbede6 (patch) | |
tree | d7a5e015e63259f509e22d2e748c9b3466247a6a /shell | |
parent | a37c3e885989602fe1a1b98aa59091ce3aee2ef7 (diff) | |
download | busybox-w32-02af72fc98c373dce7b97ac5b133c3c2a9fbede6.tar.gz busybox-w32-02af72fc98c373dce7b97ac5b133c3c2a9fbede6.tar.bz2 busybox-w32-02af72fc98c373dce7b97ac5b133c3c2a9fbede6.zip |
ash: de-obfuscate code, add 'static' keyword, etc.
git-svn-id: svn://busybox.net/trunk/busybox@17929 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash.c | 663 |
1 files changed, 299 insertions, 364 deletions
diff --git a/shell/ash.c b/shell/ash.c index 981532120..c1b5841dd 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -203,7 +203,8 @@ static volatile sig_atomic_t pendingsigs; | |||
203 | #define RESTOREINT(v) \ | 203 | #define RESTOREINT(v) \ |
204 | ({ \ | 204 | ({ \ |
205 | xbarrier(); \ | 205 | xbarrier(); \ |
206 | if ((suppressint = (v)) == 0 && intpending) onint(); \ | 206 | suppressint = (v); \ |
207 | if (suppressint == 0 && intpending) onint(); \ | ||
207 | 0; \ | 208 | 0; \ |
208 | }) | 209 | }) |
209 | #define EXSIGON() \ | 210 | #define EXSIGON() \ |
@@ -1570,7 +1571,8 @@ static int varcmp(const char *, const char *); | |||
1570 | static struct var **hashvar(const char *); | 1571 | static struct var **hashvar(const char *); |
1571 | 1572 | ||
1572 | 1573 | ||
1573 | static int varequal(const char *a, const char *b) { | 1574 | static int varequal(const char *a, const char *b) |
1575 | { | ||
1574 | return !varcmp(a, b); | 1576 | return !varcmp(a, b); |
1575 | } | 1577 | } |
1576 | 1578 | ||
@@ -1837,7 +1839,8 @@ static char *stnputs(const char *, size_t, char *); | |||
1837 | static char *stputs(const char *, char *); | 1839 | static char *stputs(const char *, char *); |
1838 | 1840 | ||
1839 | 1841 | ||
1840 | static char *_STPUTC(int c, char *p) { | 1842 | static char *_STPUTC(int c, char *p) |
1843 | { | ||
1841 | if (p == sstrend) | 1844 | if (p == sstrend) |
1842 | p = growstackstr(); | 1845 | p = growstackstr(); |
1843 | *p++ = c; | 1846 | *p++ = c; |
@@ -2049,7 +2052,6 @@ static int is_safe_applet(char *name) | |||
2049 | * This routine is called when an error or an interrupt occurs in an | 2052 | * This routine is called when an error or an interrupt occurs in an |
2050 | * interactive shell and control is returned to the main command loop. | 2053 | * interactive shell and control is returned to the main command loop. |
2051 | */ | 2054 | */ |
2052 | |||
2053 | static void | 2055 | static void |
2054 | reset(void) | 2056 | reset(void) |
2055 | { | 2057 | { |
@@ -2176,8 +2178,10 @@ aliascmd(int argc, char **argv) | |||
2176 | return 0; | 2178 | return 0; |
2177 | } | 2179 | } |
2178 | while ((n = *++argv) != NULL) { | 2180 | while ((n = *++argv) != NULL) { |
2179 | if ((v = strchr(n+1, '=')) == NULL) { /* n+1: funny ksh stuff */ | 2181 | v = strchr(n+1, '='); |
2180 | if ((ap = *__lookupalias(n)) == NULL) { | 2182 | if (v == NULL) { /* n+1: funny ksh stuff */ |
2183 | ap = *__lookupalias(n); | ||
2184 | if (ap == NULL) { | ||
2181 | fprintf(stderr, "%s: %s not found\n", "alias", n); | 2185 | fprintf(stderr, "%s: %s not found\n", "alias", n); |
2182 | ret = 1; | 2186 | ret = 1; |
2183 | } else | 2187 | } else |
@@ -2317,7 +2321,7 @@ cdcmd(int argc, char **argv) | |||
2317 | goto step7; | 2321 | goto step7; |
2318 | if (*dest == '.') { | 2322 | if (*dest == '.') { |
2319 | c = dest[1]; | 2323 | c = dest[1]; |
2320 | dotdot: | 2324 | dotdot: |
2321 | switch (c) { | 2325 | switch (c) { |
2322 | case '\0': | 2326 | case '\0': |
2323 | case '/': | 2327 | case '/': |
@@ -2330,9 +2334,10 @@ dotdot: | |||
2330 | } | 2334 | } |
2331 | if (!*dest) | 2335 | if (!*dest) |
2332 | dest = "."; | 2336 | dest = "."; |
2333 | if (!(path = bltinlookup("CDPATH"))) { | 2337 | path = bltinlookup("CDPATH"); |
2334 | step6: | 2338 | if (!path) { |
2335 | step7: | 2339 | step6: |
2340 | step7: | ||
2336 | p = dest; | 2341 | p = dest; |
2337 | goto docd; | 2342 | goto docd; |
2338 | } | 2343 | } |
@@ -2342,7 +2347,7 @@ step7: | |||
2342 | if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) { | 2347 | if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) { |
2343 | if (c && c != ':') | 2348 | if (c && c != ':') |
2344 | flags |= CD_PRINT; | 2349 | flags |= CD_PRINT; |
2345 | docd: | 2350 | docd: |
2346 | if (!docd(p, flags)) | 2351 | if (!docd(p, flags)) |
2347 | goto out; | 2352 | goto out; |
2348 | break; | 2353 | break; |
@@ -2350,7 +2355,7 @@ docd: | |||
2350 | } while (path); | 2355 | } while (path); |
2351 | sh_error("can't cd to %s", dest); | 2356 | sh_error("can't cd to %s", dest); |
2352 | /* NOTREACHED */ | 2357 | /* NOTREACHED */ |
2353 | out: | 2358 | out: |
2354 | if (flags & CD_PRINT) | 2359 | if (flags & CD_PRINT) |
2355 | out1fmt(snlfmt, curdir); | 2360 | out1fmt(snlfmt, curdir); |
2356 | return 0; | 2361 | return 0; |
@@ -2361,7 +2366,6 @@ out: | |||
2361 | * Update curdir (the name of the current directory) in response to a | 2366 | * Update curdir (the name of the current directory) in response to a |
2362 | * cd command. | 2367 | * cd command. |
2363 | */ | 2368 | */ |
2364 | |||
2365 | static const char * updatepwd(const char *dir) | 2369 | static const char * updatepwd(const char *dir) |
2366 | { | 2370 | { |
2367 | char *new; | 2371 | char *new; |
@@ -2418,11 +2422,11 @@ static const char * updatepwd(const char *dir) | |||
2418 | return stackblock(); | 2422 | return stackblock(); |
2419 | } | 2423 | } |
2420 | 2424 | ||
2425 | |||
2421 | /* | 2426 | /* |
2422 | * Actually do the chdir. We also call hashcd to let the routines in exec.c | 2427 | * Actually do the chdir. We also call hashcd to let the routines in exec.c |
2423 | * know that the current directory has changed. | 2428 | * know that the current directory has changed. |
2424 | */ | 2429 | */ |
2425 | |||
2426 | static int | 2430 | static int |
2427 | docd(const char *dest, int flags) | 2431 | docd(const char *dest, int flags) |
2428 | { | 2432 | { |
@@ -2442,7 +2446,7 @@ docd(const char *dest, int flags) | |||
2442 | goto out; | 2446 | goto out; |
2443 | setpwd(dir, 1); | 2447 | setpwd(dir, 1); |
2444 | hashcd(); | 2448 | hashcd(); |
2445 | out: | 2449 | out: |
2446 | INTON; | 2450 | INTON; |
2447 | return err; | 2451 | return err; |
2448 | } | 2452 | } |
@@ -2522,7 +2526,6 @@ static void exverror(int, const char *, va_list) ATTRIBUTE_NORETURN; | |||
2522 | * just do a longjmp to the exception handler. The type of exception is | 2526 | * just do a longjmp to the exception handler. The type of exception is |
2523 | * stored in the global variable "exception". | 2527 | * stored in the global variable "exception". |
2524 | */ | 2528 | */ |
2525 | |||
2526 | static void | 2529 | static void |
2527 | exraise(int e) | 2530 | exraise(int e) |
2528 | { | 2531 | { |
@@ -2544,7 +2547,6 @@ exraise(int e) | |||
2544 | * are held using the INTOFF macro. (The test for iflag is just | 2547 | * are held using the INTOFF macro. (The test for iflag is just |
2545 | * defensive programming.) | 2548 | * defensive programming.) |
2546 | */ | 2549 | */ |
2547 | |||
2548 | static void | 2550 | static void |
2549 | onint(void) { | 2551 | onint(void) { |
2550 | int i; | 2552 | int i; |
@@ -2626,10 +2628,10 @@ exerror(int cond, const char *msg, ...) | |||
2626 | va_end(ap); | 2628 | va_end(ap); |
2627 | } | 2629 | } |
2628 | 2630 | ||
2631 | |||
2629 | /* | 2632 | /* |
2630 | * error/warning routines for external builtins | 2633 | * error/warning routines for external builtins |
2631 | */ | 2634 | */ |
2632 | |||
2633 | static void | 2635 | static void |
2634 | sh_warnx(const char *fmt, ...) | 2636 | sh_warnx(const char *fmt, ...) |
2635 | { | 2637 | { |
@@ -2646,7 +2648,6 @@ sh_warnx(const char *fmt, ...) | |||
2646 | * pointer to a static buffer that will be overwritten on the next call. | 2648 | * pointer to a static buffer that will be overwritten on the next call. |
2647 | * Action describes the operation that got the error. | 2649 | * Action describes the operation that got the error. |
2648 | */ | 2650 | */ |
2649 | |||
2650 | static const char * | 2651 | static const char * |
2651 | errmsg(int e, const char *em) | 2652 | errmsg(int e, const char *em) |
2652 | { | 2653 | { |
@@ -2694,7 +2695,6 @@ static const struct builtincmd bltin = { | |||
2694 | /* | 2695 | /* |
2695 | * The eval command. | 2696 | * The eval command. |
2696 | */ | 2697 | */ |
2697 | |||
2698 | static int | 2698 | static int |
2699 | evalcmd(int argc, char **argv) | 2699 | evalcmd(int argc, char **argv) |
2700 | { | 2700 | { |
@@ -2709,7 +2709,8 @@ evalcmd(int argc, char **argv) | |||
2709 | ap = argv + 2; | 2709 | ap = argv + 2; |
2710 | for (;;) { | 2710 | for (;;) { |
2711 | concat = stputs(p, concat); | 2711 | concat = stputs(p, concat); |
2712 | if ((p = *ap++) == NULL) | 2712 | p = *ap++; |
2713 | if (p == NULL) | ||
2713 | break; | 2714 | break; |
2714 | STPUTC(' ', concat); | 2715 | STPUTC(' ', concat); |
2715 | } | 2716 | } |
@@ -2726,7 +2727,6 @@ evalcmd(int argc, char **argv) | |||
2726 | /* | 2727 | /* |
2727 | * Execute a command or commands contained in a string. | 2728 | * Execute a command or commands contained in a string. |
2728 | */ | 2729 | */ |
2729 | |||
2730 | static int | 2730 | static int |
2731 | evalstring(char *s, int mask) | 2731 | evalstring(char *s, int mask) |
2732 | { | 2732 | { |
@@ -2757,7 +2757,6 @@ evalstring(char *s, int mask) | |||
2757 | * Evaluate a parse tree. The value is left in the global variable | 2757 | * Evaluate a parse tree. The value is left in the global variable |
2758 | * exitstatus. | 2758 | * exitstatus. |
2759 | */ | 2759 | */ |
2760 | |||
2761 | static void | 2760 | static void |
2762 | evaltree(union node *n, int flags) | 2761 | evaltree(union node *n, int flags) |
2763 | { | 2762 | { |
@@ -2793,7 +2792,7 @@ evaltree(union node *n, int flags) | |||
2793 | goto setstatus; | 2792 | goto setstatus; |
2794 | case NCMD: | 2793 | case NCMD: |
2795 | evalfn = evalcommand; | 2794 | evalfn = evalcommand; |
2796 | checkexit: | 2795 | checkexit: |
2797 | if (eflag && !(flags & EV_TESTED)) | 2796 | if (eflag && !(flags & EV_TESTED)) |
2798 | checkexit = ~0; | 2797 | checkexit = ~0; |
2799 | goto calleval; | 2798 | goto calleval; |
@@ -2832,9 +2831,9 @@ checkexit: | |||
2832 | break; | 2831 | break; |
2833 | if (!evalskip) { | 2832 | if (!evalskip) { |
2834 | n = n->nbinary.ch2; | 2833 | n = n->nbinary.ch2; |
2835 | evaln: | 2834 | evaln: |
2836 | evalfn = evaltree; | 2835 | evalfn = evaltree; |
2837 | calleval: | 2836 | calleval: |
2838 | evalfn(n, flags); | 2837 | evalfn(n, flags); |
2839 | break; | 2838 | break; |
2840 | } | 2839 | } |
@@ -2853,20 +2852,20 @@ calleval: | |||
2853 | goto success; | 2852 | goto success; |
2854 | case NDEFUN: | 2853 | case NDEFUN: |
2855 | defun(n->narg.text, n->narg.next); | 2854 | defun(n->narg.text, n->narg.next); |
2856 | success: | 2855 | success: |
2857 | status = 0; | 2856 | status = 0; |
2858 | setstatus: | 2857 | setstatus: |
2859 | exitstatus = status; | 2858 | exitstatus = status; |
2860 | break; | 2859 | break; |
2861 | } | 2860 | } |
2862 | out: | 2861 | out: |
2863 | if ((checkexit & exitstatus)) | 2862 | if ((checkexit & exitstatus)) |
2864 | evalskip |= SKIPEVAL; | 2863 | evalskip |= SKIPEVAL; |
2865 | else if (pendingsigs && dotrap()) | 2864 | else if (pendingsigs && dotrap()) |
2866 | goto exexit; | 2865 | goto exexit; |
2867 | 2866 | ||
2868 | if (flags & EV_EXIT) { | 2867 | if (flags & EV_EXIT) { |
2869 | exexit: | 2868 | exexit: |
2870 | exraise(EXEXIT); | 2869 | exraise(EXEXIT); |
2871 | } | 2870 | } |
2872 | } | 2871 | } |
@@ -2891,7 +2890,8 @@ evalloop(union node *n, int flags) | |||
2891 | 2890 | ||
2892 | evaltree(n->nbinary.ch1, EV_TESTED); | 2891 | evaltree(n->nbinary.ch1, EV_TESTED); |
2893 | if (evalskip) { | 2892 | if (evalskip) { |
2894 | skipping: if (evalskip == SKIPCONT && --skipcount <= 0) { | 2893 | skipping: |
2894 | if (evalskip == SKIPCONT && --skipcount <= 0) { | ||
2895 | evalskip = 0; | 2895 | evalskip = 0; |
2896 | continue; | 2896 | continue; |
2897 | } | 2897 | } |
@@ -2949,12 +2949,11 @@ evalfor(union node *n, int flags) | |||
2949 | } | 2949 | } |
2950 | } | 2950 | } |
2951 | loopnest--; | 2951 | loopnest--; |
2952 | out: | 2952 | out: |
2953 | popstackmark(&smark); | 2953 | popstackmark(&smark); |
2954 | } | 2954 | } |
2955 | 2955 | ||
2956 | 2956 | ||
2957 | |||
2958 | static void | 2957 | static void |
2959 | evalcase(union node *n, int flags) | 2958 | evalcase(union node *n, int flags) |
2960 | { | 2959 | { |
@@ -2977,7 +2976,7 @@ evalcase(union node *n, int flags) | |||
2977 | } | 2976 | } |
2978 | } | 2977 | } |
2979 | } | 2978 | } |
2980 | out: | 2979 | out: |
2981 | popstackmark(&smark); | 2980 | popstackmark(&smark); |
2982 | } | 2981 | } |
2983 | 2982 | ||
@@ -2985,7 +2984,6 @@ out: | |||
2985 | /* | 2984 | /* |
2986 | * Kick off a subshell to evaluate a tree. | 2985 | * Kick off a subshell to evaluate a tree. |
2987 | */ | 2986 | */ |
2988 | |||
2989 | static void | 2987 | static void |
2990 | evalsubshell(union node *n, int flags) | 2988 | evalsubshell(union node *n, int flags) |
2991 | { | 2989 | { |
@@ -3019,7 +3017,6 @@ nofork: | |||
3019 | /* | 3017 | /* |
3020 | * Compute the names of the files in a redirection list. | 3018 | * Compute the names of the files in a redirection list. |
3021 | */ | 3019 | */ |
3022 | |||
3023 | static void | 3020 | static void |
3024 | expredir(union node *n) | 3021 | expredir(union node *n) |
3025 | { | 3022 | { |
@@ -3059,7 +3056,6 @@ expredir(union node *n) | |||
3059 | * of the shell, which make the last process in a pipeline the parent | 3056 | * of the shell, which make the last process in a pipeline the parent |
3060 | * of all the rest.) | 3057 | * of all the rest.) |
3061 | */ | 3058 | */ |
3062 | |||
3063 | static void | 3059 | static void |
3064 | evalpipe(union node *n, int flags) | 3060 | evalpipe(union node *n, int flags) |
3065 | { | 3061 | { |
@@ -3121,7 +3117,6 @@ evalpipe(union node *n, int flags) | |||
3121 | * we fork off a subprocess and get the output of the command via a pipe. | 3117 | * we fork off a subprocess and get the output of the command via a pipe. |
3122 | * Should be called with interrupts off. | 3118 | * Should be called with interrupts off. |
3123 | */ | 3119 | */ |
3124 | |||
3125 | static void | 3120 | static void |
3126 | evalbackcmd(union node *n, struct backcmd *result) | 3121 | evalbackcmd(union node *n, struct backcmd *result) |
3127 | { | 3122 | { |
@@ -3162,7 +3157,7 @@ evalbackcmd(union node *n, struct backcmd *result) | |||
3162 | result->jp = jp; | 3157 | result->jp = jp; |
3163 | } | 3158 | } |
3164 | herefd = saveherefd; | 3159 | herefd = saveherefd; |
3165 | out: | 3160 | out: |
3166 | TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n", | 3161 | TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n", |
3167 | result->fd, result->buf, result->nleft, result->jp)); | 3162 | result->fd, result->buf, result->nleft, result->jp)); |
3168 | } | 3163 | } |
@@ -3178,7 +3173,8 @@ static char ** parse_command_args(char **argv, const char **path) | |||
3178 | return 0; | 3173 | return 0; |
3179 | if (*cp++ != '-') | 3174 | if (*cp++ != '-') |
3180 | break; | 3175 | break; |
3181 | if (!(c = *cp++)) | 3176 | c = *cp++; |
3177 | if (!c) | ||
3182 | break; | 3178 | break; |
3183 | if (c == '-' && !*cp) { | 3179 | if (c == '-' && !*cp) { |
3184 | argv++; | 3180 | argv++; |
@@ -3216,7 +3212,6 @@ static const char *expandstr(const char *ps); | |||
3216 | /* | 3212 | /* |
3217 | * Execute a simple command. | 3213 | * Execute a simple command. |
3218 | */ | 3214 | */ |
3219 | |||
3220 | static void | 3215 | static void |
3221 | evalcommand(union node *cmd, int flags) | 3216 | evalcommand(union node *cmd, int flags) |
3222 | { | 3217 | { |
@@ -3369,7 +3364,7 @@ evalcommand(union node *cmd, int flags) | |||
3369 | /* We have a redirection error. */ | 3364 | /* We have a redirection error. */ |
3370 | if (spclbltin > 0) | 3365 | if (spclbltin > 0) |
3371 | exraise(EXERROR); | 3366 | exraise(EXERROR); |
3372 | bail: | 3367 | bail: |
3373 | exitstatus = status; | 3368 | exitstatus = status; |
3374 | goto out; | 3369 | goto out; |
3375 | } | 3370 | } |
@@ -3423,7 +3418,7 @@ bail: | |||
3423 | exitstatus = exit_status; | 3418 | exitstatus = exit_status; |
3424 | 3419 | ||
3425 | if (i == EXINT || spclbltin > 0) { | 3420 | if (i == EXINT || spclbltin > 0) { |
3426 | raise: | 3421 | raise: |
3427 | longjmp(handler->loc, 1); | 3422 | longjmp(handler->loc, 1); |
3428 | } | 3423 | } |
3429 | FORCEINTON; | 3424 | FORCEINTON; |
@@ -3437,7 +3432,7 @@ raise: | |||
3437 | break; | 3432 | break; |
3438 | } | 3433 | } |
3439 | 3434 | ||
3440 | out: | 3435 | out: |
3441 | popredir(cmd_is_exec); | 3436 | popredir(cmd_is_exec); |
3442 | if (lastarg) | 3437 | if (lastarg) |
3443 | /* dsl: I think this is intended to be used to support | 3438 | /* dsl: I think this is intended to be used to support |
@@ -3449,14 +3444,16 @@ out: | |||
3449 | } | 3444 | } |
3450 | 3445 | ||
3451 | static int | 3446 | static int |
3452 | evalbltin(const struct builtincmd *cmd, int argc, char **argv) { | 3447 | evalbltin(const struct builtincmd *cmd, int argc, char **argv) |
3448 | { | ||
3453 | char *volatile savecmdname; | 3449 | char *volatile savecmdname; |
3454 | struct jmploc *volatile savehandler; | 3450 | struct jmploc *volatile savehandler; |
3455 | struct jmploc jmploc; | 3451 | struct jmploc jmploc; |
3456 | int i; | 3452 | int i; |
3457 | 3453 | ||
3458 | savecmdname = commandname; | 3454 | savecmdname = commandname; |
3459 | if ((i = setjmp(jmploc.loc))) | 3455 | i = setjmp(jmploc.loc); |
3456 | if (i) | ||
3460 | goto cmddone; | 3457 | goto cmddone; |
3461 | savehandler = handler; | 3458 | savehandler = handler; |
3462 | handler = &jmploc; | 3459 | handler = &jmploc; |
@@ -3465,7 +3462,7 @@ evalbltin(const struct builtincmd *cmd, int argc, char **argv) { | |||
3465 | optptr = NULL; /* initialize nextopt */ | 3462 | optptr = NULL; /* initialize nextopt */ |
3466 | exitstatus = (*cmd->builtin)(argc, argv); | 3463 | exitstatus = (*cmd->builtin)(argc, argv); |
3467 | flushall(); | 3464 | flushall(); |
3468 | cmddone: | 3465 | cmddone: |
3469 | exitstatus |= ferror(stdout); | 3466 | exitstatus |= ferror(stdout); |
3470 | clearerr(stdout); | 3467 | clearerr(stdout); |
3471 | commandname = savecmdname; | 3468 | commandname = savecmdname; |
@@ -3486,7 +3483,8 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags) | |||
3486 | 3483 | ||
3487 | saveparam = shellparam; | 3484 | saveparam = shellparam; |
3488 | savelocalvars = localvars; | 3485 | savelocalvars = localvars; |
3489 | if ((e = setjmp(jmploc.loc))) { | 3486 | e = setjmp(jmploc.loc); |
3487 | if (e) { | ||
3490 | goto funcdone; | 3488 | goto funcdone; |
3491 | } | 3489 | } |
3492 | INTOFF; | 3490 | INTOFF; |
@@ -3524,13 +3522,13 @@ static int goodname(const char *p) | |||
3524 | return !*endofname(p); | 3522 | return !*endofname(p); |
3525 | } | 3523 | } |
3526 | 3524 | ||
3525 | |||
3527 | /* | 3526 | /* |
3528 | * Search for a command. This is called before we fork so that the | 3527 | * Search for a command. This is called before we fork so that the |
3529 | * location of the command will be available in the parent as well as | 3528 | * location of the command will be available in the parent as well as |
3530 | * the child. The check for "goodname" is an overly conservative | 3529 | * the child. The check for "goodname" is an overly conservative |
3531 | * check that the name will not be subject to expansion. | 3530 | * check that the name will not be subject to expansion. |
3532 | */ | 3531 | */ |
3533 | |||
3534 | static void | 3532 | static void |
3535 | prehash(union node *n) | 3533 | prehash(union node *n) |
3536 | { | 3534 | { |
@@ -3550,7 +3548,6 @@ prehash(union node *n) | |||
3550 | /* | 3548 | /* |
3551 | * No command given. | 3549 | * No command given. |
3552 | */ | 3550 | */ |
3553 | |||
3554 | static int | 3551 | static int |
3555 | bltincmd(int argc, char **argv) | 3552 | bltincmd(int argc, char **argv) |
3556 | { | 3553 | { |
@@ -3593,7 +3590,6 @@ breakcmd(int argc, char **argv) | |||
3593 | /* | 3590 | /* |
3594 | * The return command. | 3591 | * The return command. |
3595 | */ | 3592 | */ |
3596 | |||
3597 | static int | 3593 | static int |
3598 | returncmd(int argc, char **argv) | 3594 | returncmd(int argc, char **argv) |
3599 | { | 3595 | { |
@@ -3648,7 +3644,6 @@ execcmd(int argc, char **argv) | |||
3648 | #define ARB 1 /* actual size determined at run time */ | 3644 | #define ARB 1 /* actual size determined at run time */ |
3649 | 3645 | ||
3650 | 3646 | ||
3651 | |||
3652 | struct tblentry { | 3647 | struct tblentry { |
3653 | struct tblentry *next; /* next entry in hash chain */ | 3648 | struct tblentry *next; /* next entry in hash chain */ |
3654 | union param param; /* definition of builtin function */ | 3649 | union param param; /* definition of builtin function */ |
@@ -3750,7 +3745,7 @@ tryexec(char *cmd, char **argv, char **envp) | |||
3750 | } | 3745 | } |
3751 | #endif | 3746 | #endif |
3752 | 3747 | ||
3753 | repeat: | 3748 | repeat: |
3754 | #ifdef SYSV | 3749 | #ifdef SYSV |
3755 | do { | 3750 | do { |
3756 | execve(cmd, argv, envp); | 3751 | execve(cmd, argv, envp); |
@@ -3779,7 +3774,6 @@ repeat: | |||
3779 | } | 3774 | } |
3780 | 3775 | ||
3781 | 3776 | ||
3782 | |||
3783 | /* | 3777 | /* |
3784 | * Do a path search. The variable path (passed by reference) should be | 3778 | * Do a path search. The variable path (passed by reference) should be |
3785 | * set to the start of the path before the first call; padvance will update | 3779 | * set to the start of the path before the first call; padvance will update |
@@ -3789,7 +3783,6 @@ repeat: | |||
3789 | * pathopt will be set to point to it; otherwise pathopt will be set to | 3783 | * pathopt will be set to point to it; otherwise pathopt will be set to |
3790 | * NULL. | 3784 | * NULL. |
3791 | */ | 3785 | */ |
3792 | |||
3793 | static char * | 3786 | static char * |
3794 | padvance(const char **path, const char *name) | 3787 | padvance(const char **path, const char *name) |
3795 | { | 3788 | { |
@@ -3868,7 +3861,8 @@ hashcmd(int argc, char **argv) | |||
3868 | } | 3861 | } |
3869 | c = 0; | 3862 | c = 0; |
3870 | while ((name = *argptr) != NULL) { | 3863 | while ((name = *argptr) != NULL) { |
3871 | if ((cmdp = cmdlookup(name, 0)) != NULL | 3864 | cmdp = cmdlookup(name, 0); |
3865 | if (cmdp != NULL | ||
3872 | && (cmdp->cmdtype == CMDNORMAL | 3866 | && (cmdp->cmdtype == CMDNORMAL |
3873 | || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0))) | 3867 | || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0))) |
3874 | delete_cmd_entry(); | 3868 | delete_cmd_entry(); |
@@ -3885,7 +3879,6 @@ hashcmd(int argc, char **argv) | |||
3885 | * Resolve a command name. If you change this routine, you may have to | 3879 | * Resolve a command name. If you change this routine, you may have to |
3886 | * change the shellexec routine as well. | 3880 | * change the shellexec routine as well. |
3887 | */ | 3881 | */ |
3888 | |||
3889 | static void | 3882 | static void |
3890 | find_command(char *name, struct cmdentry *entry, int act, const char *path) | 3883 | find_command(char *name, struct cmdentry *entry, int act, const char *path) |
3891 | { | 3884 | { |
@@ -3937,7 +3930,8 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path) | |||
3937 | } | 3930 | } |
3938 | 3931 | ||
3939 | /* If name is in the table, check answer will be ok */ | 3932 | /* If name is in the table, check answer will be ok */ |
3940 | if ((cmdp = cmdlookup(name, 0)) != NULL) { | 3933 | cmdp = cmdlookup(name, 0); |
3934 | if (cmdp != NULL) { | ||
3941 | int bit; | 3935 | int bit; |
3942 | 3936 | ||
3943 | switch (cmdp->cmdtype) { | 3937 | switch (cmdp->cmdtype) { |
@@ -3981,7 +3975,7 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path) | |||
3981 | 3975 | ||
3982 | e = ENOENT; | 3976 | e = ENOENT; |
3983 | idx = -1; | 3977 | idx = -1; |
3984 | loop: | 3978 | loop: |
3985 | while ((fullname = padvance(&path, name)) != NULL) { | 3979 | while ((fullname = padvance(&path, name)) != NULL) { |
3986 | stunalloc(fullname); | 3980 | stunalloc(fullname); |
3987 | idx++; | 3981 | idx++; |
@@ -4020,8 +4014,8 @@ loop: | |||
4020 | if (pathopt) { /* this is a %func directory */ | 4014 | if (pathopt) { /* this is a %func directory */ |
4021 | stalloc(strlen(fullname) + 1); | 4015 | stalloc(strlen(fullname) + 1); |
4022 | readcmdfile(fullname); | 4016 | readcmdfile(fullname); |
4023 | if ((cmdp = cmdlookup(name, 0)) == NULL || | 4017 | cmdp = cmdlookup(name, 0); |
4024 | cmdp->cmdtype != CMDFUNCTION) | 4018 | if (cmdp == NULL || cmdp->cmdtype != CMDFUNCTION) |
4025 | sh_error("%s not defined in %s", name, fullname); | 4019 | sh_error("%s not defined in %s", name, fullname); |
4026 | stunalloc(fullname); | 4020 | stunalloc(fullname); |
4027 | goto success; | 4021 | goto success; |
@@ -4048,7 +4042,7 @@ loop: | |||
4048 | entry->cmdtype = CMDUNKNOWN; | 4042 | entry->cmdtype = CMDUNKNOWN; |
4049 | return; | 4043 | return; |
4050 | 4044 | ||
4051 | builtin_success: | 4045 | builtin_success: |
4052 | if (!updatetbl) { | 4046 | if (!updatetbl) { |
4053 | entry->cmdtype = CMDBUILTIN; | 4047 | entry->cmdtype = CMDBUILTIN; |
4054 | entry->u.cmd = bcmd; | 4048 | entry->u.cmd = bcmd; |
@@ -4059,7 +4053,7 @@ builtin_success: | |||
4059 | cmdp->cmdtype = CMDBUILTIN; | 4053 | cmdp->cmdtype = CMDBUILTIN; |
4060 | cmdp->param.cmd = bcmd; | 4054 | cmdp->param.cmd = bcmd; |
4061 | INTON; | 4055 | INTON; |
4062 | success: | 4056 | success: |
4063 | cmdp->rehash = 0; | 4057 | cmdp->rehash = 0; |
4064 | entry->cmdtype = cmdp->cmdtype; | 4058 | entry->cmdtype = cmdp->cmdtype; |
4065 | entry->u = cmdp->param; | 4059 | entry->u = cmdp->param; |
@@ -4074,10 +4068,10 @@ static int pstrcmp(const void *a, const void *b) | |||
4074 | return strcmp((const char *) a, (*(const char *const *) b) + 1); | 4068 | return strcmp((const char *) a, (*(const char *const *) b) + 1); |
4075 | } | 4069 | } |
4076 | 4070 | ||
4071 | |||
4077 | /* | 4072 | /* |
4078 | * Search the table of builtin commands. | 4073 | * Search the table of builtin commands. |
4079 | */ | 4074 | */ |
4080 | |||
4081 | static struct builtincmd * | 4075 | static struct builtincmd * |
4082 | find_builtin(const char *name) | 4076 | find_builtin(const char *name) |
4083 | { | 4077 | { |
@@ -4095,7 +4089,6 @@ find_builtin(const char *name) | |||
4095 | * Called when a cd is done. Marks all commands so the next time they | 4089 | * Called when a cd is done. Marks all commands so the next time they |
4096 | * are executed they will be rehashed. | 4090 | * are executed they will be rehashed. |
4097 | */ | 4091 | */ |
4098 | |||
4099 | static void | 4092 | static void |
4100 | hashcd(void) | 4093 | hashcd(void) |
4101 | { | 4094 | { |
@@ -4121,7 +4114,6 @@ hashcd(void) | |||
4121 | * pathval() still returns the old value at this point. | 4114 | * pathval() still returns the old value at this point. |
4122 | * Called with interrupts off. | 4115 | * Called with interrupts off. |
4123 | */ | 4116 | */ |
4124 | |||
4125 | static void | 4117 | static void |
4126 | changepath(const char *newval) | 4118 | changepath(const char *newval) |
4127 | { | 4119 | { |
@@ -4165,7 +4157,6 @@ changepath(const char *newval) | |||
4165 | * Clear out command entries. The argument specifies the first entry in | 4157 | * Clear out command entries. The argument specifies the first entry in |
4166 | * PATH which has changed. | 4158 | * PATH which has changed. |
4167 | */ | 4159 | */ |
4168 | |||
4169 | static void | 4160 | static void |
4170 | clearcmdentry(int firstchange) | 4161 | clearcmdentry(int firstchange) |
4171 | { | 4162 | { |
@@ -4193,7 +4184,6 @@ clearcmdentry(int firstchange) | |||
4193 | } | 4184 | } |
4194 | 4185 | ||
4195 | 4186 | ||
4196 | |||
4197 | /* | 4187 | /* |
4198 | * Locate a command in the command hash table. If "add" is nonzero, | 4188 | * Locate a command in the command hash table. If "add" is nonzero, |
4199 | * add the command to the table if it is not already present. The | 4189 | * add the command to the table if it is not already present. The |
@@ -4203,10 +4193,8 @@ clearcmdentry(int firstchange) | |||
4203 | * | 4193 | * |
4204 | * Interrupts must be off if called with add != 0. | 4194 | * Interrupts must be off if called with add != 0. |
4205 | */ | 4195 | */ |
4206 | |||
4207 | static struct tblentry **lastcmdentry; | 4196 | static struct tblentry **lastcmdentry; |
4208 | 4197 | ||
4209 | |||
4210 | static struct tblentry * | 4198 | static struct tblentry * |
4211 | cmdlookup(const char *name, int add) | 4199 | cmdlookup(const char *name, int add) |
4212 | { | 4200 | { |
@@ -4237,10 +4225,10 @@ cmdlookup(const char *name, int add) | |||
4237 | return cmdp; | 4225 | return cmdp; |
4238 | } | 4226 | } |
4239 | 4227 | ||
4228 | |||
4240 | /* | 4229 | /* |
4241 | * Delete the command entry returned on the last lookup. | 4230 | * Delete the command entry returned on the last lookup. |
4242 | */ | 4231 | */ |
4243 | |||
4244 | static void | 4232 | static void |
4245 | delete_cmd_entry(void) | 4233 | delete_cmd_entry(void) |
4246 | { | 4234 | { |
@@ -4260,7 +4248,6 @@ delete_cmd_entry(void) | |||
4260 | * Add a new command entry, replacing any existing command entry for | 4248 | * Add a new command entry, replacing any existing command entry for |
4261 | * the same name - except special builtins. | 4249 | * the same name - except special builtins. |
4262 | */ | 4250 | */ |
4263 | |||
4264 | static void addcmdentry(char *name, struct cmdentry *entry) | 4251 | static void addcmdentry(char *name, struct cmdentry *entry) |
4265 | { | 4252 | { |
4266 | struct tblentry *cmdp; | 4253 | struct tblentry *cmdp; |
@@ -4274,10 +4261,10 @@ static void addcmdentry(char *name, struct cmdentry *entry) | |||
4274 | cmdp->rehash = 0; | 4261 | cmdp->rehash = 0; |
4275 | } | 4262 | } |
4276 | 4263 | ||
4264 | |||
4277 | /* | 4265 | /* |
4278 | * Make a copy of a parse tree. | 4266 | * Make a copy of a parse tree. |
4279 | */ | 4267 | */ |
4280 | |||
4281 | static struct funcnode * copyfunc(union node *n) | 4268 | static struct funcnode * copyfunc(union node *n) |
4282 | { | 4269 | { |
4283 | struct funcnode *f; | 4270 | struct funcnode *f; |
@@ -4295,10 +4282,10 @@ static struct funcnode * copyfunc(union node *n) | |||
4295 | return f; | 4282 | return f; |
4296 | } | 4283 | } |
4297 | 4284 | ||
4285 | |||
4298 | /* | 4286 | /* |
4299 | * Define a shell function. | 4287 | * Define a shell function. |
4300 | */ | 4288 | */ |
4301 | |||
4302 | static void | 4289 | static void |
4303 | defun(char *name, union node *func) | 4290 | defun(char *name, union node *func) |
4304 | { | 4291 | { |
@@ -4315,7 +4302,6 @@ defun(char *name, union node *func) | |||
4315 | /* | 4302 | /* |
4316 | * Delete a function if it exists. | 4303 | * Delete a function if it exists. |
4317 | */ | 4304 | */ |
4318 | |||
4319 | static void | 4305 | static void |
4320 | unsetfunc(const char *name) | 4306 | unsetfunc(const char *name) |
4321 | { | 4307 | { |
@@ -4329,8 +4315,6 @@ unsetfunc(const char *name) | |||
4329 | /* | 4315 | /* |
4330 | * Locate and print what a word is... | 4316 | * Locate and print what a word is... |
4331 | */ | 4317 | */ |
4332 | |||
4333 | |||
4334 | #if ENABLE_ASH_CMDCMD | 4318 | #if ENABLE_ASH_CMDCMD |
4335 | static int | 4319 | static int |
4336 | describe_command(char *command, int describe_command_verbose) | 4320 | describe_command(char *command, int describe_command_verbose) |
@@ -4359,7 +4343,8 @@ describe_command(char *command) | |||
4359 | 4343 | ||
4360 | #if ENABLE_ASH_ALIAS | 4344 | #if ENABLE_ASH_ALIAS |
4361 | /* Then look at the aliases */ | 4345 | /* Then look at the aliases */ |
4362 | if ((ap = lookupalias(command, 0)) != NULL) { | 4346 | ap = lookupalias(command, 0); |
4347 | if (ap != NULL) { | ||
4363 | if (describe_command_verbose) { | 4348 | if (describe_command_verbose) { |
4364 | out1fmt(" is an alias for %s", ap->val); | 4349 | out1fmt(" is an alias for %s", ap->val); |
4365 | } else { | 4350 | } else { |
@@ -4371,7 +4356,8 @@ describe_command(char *command) | |||
4371 | } | 4356 | } |
4372 | #endif | 4357 | #endif |
4373 | /* Then check if it is a tracked alias */ | 4358 | /* Then check if it is a tracked alias */ |
4374 | if ((cmdp = cmdlookup(command, 0)) != NULL) { | 4359 | cmdp = cmdlookup(command, 0); |
4360 | if (cmdp != NULL) { | ||
4375 | entry.cmdtype = cmdp->cmdtype; | 4361 | entry.cmdtype = cmdp->cmdtype; |
4376 | entry.u = cmdp->param; | 4362 | entry.u = cmdp->param; |
4377 | } else { | 4363 | } else { |
@@ -4426,8 +4412,7 @@ describe_command(char *command) | |||
4426 | } | 4412 | } |
4427 | return 127; | 4413 | return 127; |
4428 | } | 4414 | } |
4429 | 4415 | out: | |
4430 | out: | ||
4431 | outstr("\n", stdout); | 4416 | outstr("\n", stdout); |
4432 | return 0; | 4417 | return 0; |
4433 | } | 4418 | } |
@@ -4543,7 +4528,8 @@ static void varunset(const char *, const char *, const char *, int) | |||
4543 | * Returns an stalloced string. | 4528 | * Returns an stalloced string. |
4544 | */ | 4529 | */ |
4545 | 4530 | ||
4546 | static char * preglob(const char *pattern, int quoted, int flag) { | 4531 | static char * preglob(const char *pattern, int quoted, int flag) |
4532 | { | ||
4547 | flag |= RMESCAPE_GLOB; | 4533 | flag |= RMESCAPE_GLOB; |
4548 | if (quoted) { | 4534 | if (quoted) { |
4549 | flag |= RMESCAPE_QUOTED; | 4535 | flag |= RMESCAPE_QUOTED; |
@@ -4581,8 +4567,7 @@ static void expandhere(union node *arg, int fd) | |||
4581 | * perform splitting and file name expansion. When arglist is NULL, perform | 4567 | * perform splitting and file name expansion. When arglist is NULL, perform |
4582 | * here document expansion. | 4568 | * here document expansion. |
4583 | */ | 4569 | */ |
4584 | 4570 | static void | |
4585 | void | ||
4586 | expandarg(union node *arg, struct arglist *arglist, int flag) | 4571 | expandarg(union node *arg, struct arglist *arglist, int flag) |
4587 | { | 4572 | { |
4588 | struct strlist *sp; | 4573 | struct strlist *sp; |
@@ -4631,7 +4616,6 @@ expandarg(union node *arg, struct arglist *arglist, int flag) | |||
4631 | * characters to allow for further processing. Otherwise treat | 4616 | * characters to allow for further processing. Otherwise treat |
4632 | * $@ like $* since no splitting will be performed. | 4617 | * $@ like $* since no splitting will be performed. |
4633 | */ | 4618 | */ |
4634 | |||
4635 | static void | 4619 | static void |
4636 | argstr(char *p, int flag) | 4620 | argstr(char *p, int flag) |
4637 | { | 4621 | { |
@@ -4668,14 +4652,14 @@ argstr(char *p, int flag) | |||
4668 | char *q; | 4652 | char *q; |
4669 | 4653 | ||
4670 | flag &= ~EXP_TILDE; | 4654 | flag &= ~EXP_TILDE; |
4671 | tilde: | 4655 | tilde: |
4672 | q = p; | 4656 | q = p; |
4673 | if (*q == CTLESC && (flag & EXP_QWORD)) | 4657 | if (*q == CTLESC && (flag & EXP_QWORD)) |
4674 | q++; | 4658 | q++; |
4675 | if (*q == '~') | 4659 | if (*q == '~') |
4676 | p = exptilde(p, q, flag); | 4660 | p = exptilde(p, q, flag); |
4677 | } | 4661 | } |
4678 | start: | 4662 | start: |
4679 | startloc = expdest - (char *)stackblock(); | 4663 | startloc = expdest - (char *)stackblock(); |
4680 | for (;;) { | 4664 | for (;;) { |
4681 | length += strcspn(p + length, reject); | 4665 | length += strcspn(p + length, reject); |
@@ -4739,7 +4723,7 @@ start: | |||
4739 | goto start; | 4723 | goto start; |
4740 | } | 4724 | } |
4741 | inquotes = !inquotes; | 4725 | inquotes = !inquotes; |
4742 | addquote: | 4726 | addquote: |
4743 | if (quotes) { | 4727 | if (quotes) { |
4744 | p--; | 4728 | p--; |
4745 | length++; | 4729 | length++; |
@@ -4767,7 +4751,7 @@ addquote: | |||
4767 | #endif | 4751 | #endif |
4768 | } | 4752 | } |
4769 | } | 4753 | } |
4770 | breakloop: | 4754 | breakloop: |
4771 | ; | 4755 | ; |
4772 | } | 4756 | } |
4773 | 4757 | ||
@@ -4798,12 +4782,13 @@ exptilde(char *startp, char *p, int flag) | |||
4798 | goto done; | 4782 | goto done; |
4799 | } | 4783 | } |
4800 | } | 4784 | } |
4801 | done: | 4785 | done: |
4802 | *p = '\0'; | 4786 | *p = '\0'; |
4803 | if (*name == '\0') { | 4787 | if (*name == '\0') { |
4804 | home = lookupvar(homestr); | 4788 | home = lookupvar(homestr); |
4805 | } else { | 4789 | } else { |
4806 | if ((pw = getpwnam(name)) == NULL) | 4790 | pw = getpwnam(name); |
4791 | if (pw == NULL) | ||
4807 | goto lose; | 4792 | goto lose; |
4808 | home = pw->pw_dir; | 4793 | home = pw->pw_dir; |
4809 | } | 4794 | } |
@@ -4814,7 +4799,7 @@ done: | |||
4814 | strtodest(home, SQSYNTAX, quotes); | 4799 | strtodest(home, SQSYNTAX, quotes); |
4815 | recordregion(startloc, expdest - (char *)stackblock(), 0); | 4800 | recordregion(startloc, expdest - (char *)stackblock(), 0); |
4816 | return p; | 4801 | return p; |
4817 | lose: | 4802 | lose: |
4818 | *p = c; | 4803 | *p = c; |
4819 | return startp; | 4804 | return startp; |
4820 | } | 4805 | } |
@@ -4922,10 +4907,10 @@ expari(int quotes) | |||
4922 | } | 4907 | } |
4923 | #endif | 4908 | #endif |
4924 | 4909 | ||
4910 | |||
4925 | /* | 4911 | /* |
4926 | * Expand stuff in backwards quotes. | 4912 | * Expand stuff in backwards quotes. |
4927 | */ | 4913 | */ |
4928 | |||
4929 | static void | 4914 | static void |
4930 | expbackq(union node *cmd, int quoted, int quotes) | 4915 | expbackq(union node *cmd, int quoted, int quotes) |
4931 | { | 4916 | { |
@@ -4952,7 +4937,7 @@ expbackq(union node *cmd, int quoted, int quotes) | |||
4952 | goto read; | 4937 | goto read; |
4953 | for (;;) { | 4938 | for (;;) { |
4954 | memtodest(p, i, syntax, quotes); | 4939 | memtodest(p, i, syntax, quotes); |
4955 | read: | 4940 | read: |
4956 | if (in.fd < 0) | 4941 | if (in.fd < 0) |
4957 | break; | 4942 | break; |
4958 | i = safe_read(in.fd, buf, sizeof(buf)); | 4943 | i = safe_read(in.fd, buf, sizeof(buf)); |
@@ -5146,7 +5131,7 @@ evalvar(char *p, int flag) | |||
5146 | startloc = expdest - (char *)stackblock(); | 5131 | startloc = expdest - (char *)stackblock(); |
5147 | p = strchr(p, '=') + 1; | 5132 | p = strchr(p, '=') + 1; |
5148 | 5133 | ||
5149 | again: | 5134 | again: |
5150 | varlen = varvalue(var, varflags, flag); | 5135 | varlen = varvalue(var, varflags, flag); |
5151 | if (varflags & VSNUL) | 5136 | if (varflags & VSNUL) |
5152 | varlen--; | 5137 | varlen--; |
@@ -5157,7 +5142,7 @@ again: | |||
5157 | } | 5142 | } |
5158 | 5143 | ||
5159 | if (subtype == VSMINUS) { | 5144 | if (subtype == VSMINUS) { |
5160 | vsplus: | 5145 | vsplus: |
5161 | if (varlen < 0) { | 5146 | if (varlen < 0) { |
5162 | argstr( | 5147 | argstr( |
5163 | p, flag | EXP_TILDE | | 5148 | p, flag | EXP_TILDE | |
@@ -5199,7 +5184,7 @@ vsplus: | |||
5199 | if (subtype == VSNORMAL) { | 5184 | if (subtype == VSNORMAL) { |
5200 | if (!easy) | 5185 | if (!easy) |
5201 | goto end; | 5186 | goto end; |
5202 | record: | 5187 | record: |
5203 | recordregion(startloc, expdest - (char *)stackblock(), quoted); | 5188 | recordregion(startloc, expdest - (char *)stackblock(), quoted); |
5204 | goto end; | 5189 | goto end; |
5205 | } | 5190 | } |
@@ -5235,11 +5220,12 @@ record: | |||
5235 | goto record; | 5220 | goto record; |
5236 | } | 5221 | } |
5237 | 5222 | ||
5238 | end: | 5223 | end: |
5239 | if (subtype != VSNORMAL) { /* skip to end of alternative */ | 5224 | if (subtype != VSNORMAL) { /* skip to end of alternative */ |
5240 | int nesting = 1; | 5225 | int nesting = 1; |
5241 | for (;;) { | 5226 | for (;;) { |
5242 | if ((c = *p++) == CTLESC) | 5227 | c = *p++; |
5228 | if (c == CTLESC) | ||
5243 | p++; | 5229 | p++; |
5244 | else if (c == CTLBACKQ || c == (CTLBACKQ|CTLQUOTE)) { | 5230 | else if (c == CTLBACKQ || c == (CTLBACKQ|CTLQUOTE)) { |
5245 | if (varlen >= 0) | 5231 | if (varlen >= 0) |
@@ -5260,7 +5246,6 @@ end: | |||
5260 | /* | 5246 | /* |
5261 | * Put a string on the stack. | 5247 | * Put a string on the stack. |
5262 | */ | 5248 | */ |
5263 | |||
5264 | static void | 5249 | static void |
5265 | memtodest(const char *p, size_t len, int syntax, int quotes) { | 5250 | memtodest(const char *p, size_t len, int syntax, int quotes) { |
5266 | char *q = expdest; | 5251 | char *q = expdest; |
@@ -5290,7 +5275,6 @@ strtodest(const char *p, int syntax, int quotes) | |||
5290 | /* | 5275 | /* |
5291 | * Add the value of a specialized variable to the stack string. | 5276 | * Add the value of a specialized variable to the stack string. |
5292 | */ | 5277 | */ |
5293 | |||
5294 | static ssize_t | 5278 | static ssize_t |
5295 | varvalue(char *name, int varflags, int flags) | 5279 | varvalue(char *name, int varflags, int flags) |
5296 | { | 5280 | { |
@@ -5324,7 +5308,7 @@ varvalue(char *name, int varflags, int flags) | |||
5324 | num = backgndpid; | 5308 | num = backgndpid; |
5325 | if (num == 0) | 5309 | if (num == 0) |
5326 | return -1; | 5310 | return -1; |
5327 | numvar: | 5311 | numvar: |
5328 | len = cvtnum(num); | 5312 | len = cvtnum(num); |
5329 | break; | 5313 | break; |
5330 | case '-': | 5314 | case '-': |
@@ -5345,8 +5329,9 @@ numvar: | |||
5345 | sep = ifsset() ? SC2INT(ifsval()[0]) : ' '; | 5329 | sep = ifsset() ? SC2INT(ifsval()[0]) : ' '; |
5346 | if (quotes && (SIT(sep, syntax) == CCTL || SIT(sep, syntax) == CBACK)) | 5330 | if (quotes && (SIT(sep, syntax) == CCTL || SIT(sep, syntax) == CBACK)) |
5347 | sepq = 1; | 5331 | sepq = 1; |
5348 | param: | 5332 | param: |
5349 | if (!(ap = shellparam.p)) | 5333 | ap = shellparam.p; |
5334 | if (!ap) | ||
5350 | return -1; | 5335 | return -1; |
5351 | while ((p = *ap++)) { | 5336 | while ((p = *ap++)) { |
5352 | size_t partlen; | 5337 | size_t partlen; |
@@ -5389,7 +5374,7 @@ param: | |||
5389 | goto value; | 5374 | goto value; |
5390 | default: | 5375 | default: |
5391 | p = lookupvar(name); | 5376 | p = lookupvar(name); |
5392 | value: | 5377 | value: |
5393 | if (!p) | 5378 | if (!p) |
5394 | return -1; | 5379 | return -1; |
5395 | 5380 | ||
@@ -5409,7 +5394,6 @@ value: | |||
5409 | * Record the fact that we have to scan this region of the | 5394 | * Record the fact that we have to scan this region of the |
5410 | * string for IFS characters. | 5395 | * string for IFS characters. |
5411 | */ | 5396 | */ |
5412 | |||
5413 | static void | 5397 | static void |
5414 | recordregion(int start, int end, int nulonly) | 5398 | recordregion(int start, int end, int nulonly) |
5415 | { | 5399 | { |
@@ -5513,7 +5497,7 @@ ifsbreakup(char *string, struct arglist *arglist) | |||
5513 | if (!*start) | 5497 | if (!*start) |
5514 | return; | 5498 | return; |
5515 | 5499 | ||
5516 | add: | 5500 | add: |
5517 | sp = (struct strlist *)stalloc(sizeof(*sp)); | 5501 | sp = (struct strlist *)stalloc(sizeof(*sp)); |
5518 | sp->text = start; | 5502 | sp->text = start; |
5519 | *arglist->lastp = sp; | 5503 | *arglist->lastp = sp; |
@@ -5580,7 +5564,7 @@ expandmeta(struct strlist *str, int flag) | |||
5580 | /* | 5564 | /* |
5581 | * no matches | 5565 | * no matches |
5582 | */ | 5566 | */ |
5583 | nometa: | 5567 | nometa: |
5584 | *exparg.lastp = str; | 5568 | *exparg.lastp = str; |
5585 | rmescapes(str->text); | 5569 | rmescapes(str->text); |
5586 | exparg.lastp = &str->next; | 5570 | exparg.lastp = &str->next; |
@@ -5595,10 +5579,10 @@ nometa: | |||
5595 | } | 5579 | } |
5596 | } | 5580 | } |
5597 | 5581 | ||
5582 | |||
5598 | /* | 5583 | /* |
5599 | * Add a file name to the list. | 5584 | * Add a file name to the list. |
5600 | */ | 5585 | */ |
5601 | |||
5602 | static void | 5586 | static void |
5603 | addfname(const char *name) | 5587 | addfname(const char *name) |
5604 | { | 5588 | { |
@@ -5614,7 +5598,6 @@ addfname(const char *name) | |||
5614 | /* | 5598 | /* |
5615 | * Do metacharacter (i.e. *, ?, [...]) expansion. | 5599 | * Do metacharacter (i.e. *, ?, [...]) expansion. |
5616 | */ | 5600 | */ |
5617 | |||
5618 | static void | 5601 | static void |
5619 | expmeta(char *enddir, char *name) | 5602 | expmeta(char *enddir, char *name) |
5620 | { | 5603 | { |
@@ -5656,7 +5639,7 @@ expmeta(char *enddir, char *name) | |||
5656 | start = p + 1; | 5639 | start = p + 1; |
5657 | } | 5640 | } |
5658 | } | 5641 | } |
5659 | out: | 5642 | out: |
5660 | if (metaflag == 0) { /* we've reached the end of the file name */ | 5643 | if (metaflag == 0) { /* we've reached the end of the file name */ |
5661 | if (enddir != expdir) | 5644 | if (enddir != expdir) |
5662 | metaflag++; | 5645 | metaflag++; |
@@ -5687,7 +5670,8 @@ out: | |||
5687 | cp = expdir; | 5670 | cp = expdir; |
5688 | enddir[-1] = '\0'; | 5671 | enddir[-1] = '\0'; |
5689 | } | 5672 | } |
5690 | if ((dirp = opendir(cp)) == NULL) | 5673 | dirp = opendir(cp); |
5674 | if (dirp == NULL) | ||
5691 | return; | 5675 | return; |
5692 | if (enddir != expdir) | 5676 | if (enddir != expdir) |
5693 | enddir[-1] = '/'; | 5677 | enddir[-1] = '/'; |
@@ -5723,12 +5707,12 @@ out: | |||
5723 | endname[-1] = '/'; | 5707 | endname[-1] = '/'; |
5724 | } | 5708 | } |
5725 | 5709 | ||
5710 | |||
5726 | /* | 5711 | /* |
5727 | * Sort the results of file name expansion. It calculates the number of | 5712 | * Sort the results of file name expansion. It calculates the number of |
5728 | * strings to sort and then calls msort (short for merge sort) to do the | 5713 | * strings to sort and then calls msort (short for merge sort) to do the |
5729 | * work. | 5714 | * work. |
5730 | */ | 5715 | */ |
5731 | |||
5732 | static struct strlist * | 5716 | static struct strlist * |
5733 | expsort(struct strlist *str) | 5717 | expsort(struct strlist *str) |
5734 | { | 5718 | { |
@@ -5771,14 +5755,16 @@ msort(struct strlist *list, int len) | |||
5771 | { | 5755 | { |
5772 | *lpp = p; | 5756 | *lpp = p; |
5773 | lpp = &p->next; | 5757 | lpp = &p->next; |
5774 | if ((p = *lpp) == NULL) { | 5758 | p = *lpp; |
5759 | if (p == NULL) { | ||
5775 | *lpp = q; | 5760 | *lpp = q; |
5776 | break; | 5761 | break; |
5777 | } | 5762 | } |
5778 | } else { | 5763 | } else { |
5779 | *lpp = q; | 5764 | *lpp = q; |
5780 | lpp = &q->next; | 5765 | lpp = &q->next; |
5781 | if ((q = *lpp) == NULL) { | 5766 | q = *lpp; |
5767 | if (q == NULL) { | ||
5782 | *lpp = p; | 5768 | *lpp = p; |
5783 | break; | 5769 | break; |
5784 | } | 5770 | } |
@@ -5791,7 +5777,6 @@ msort(struct strlist *list, int len) | |||
5791 | /* | 5777 | /* |
5792 | * Returns true if the pattern matches the string. | 5778 | * Returns true if the pattern matches the string. |
5793 | */ | 5779 | */ |
5794 | |||
5795 | static int patmatch(char *pattern, const char *string) | 5780 | static int patmatch(char *pattern, const char *string) |
5796 | { | 5781 | { |
5797 | return pmatch(preglob(pattern, 0, 0), string); | 5782 | return pmatch(preglob(pattern, 0, 0), string); |
@@ -5801,7 +5786,6 @@ static int patmatch(char *pattern, const char *string) | |||
5801 | /* | 5786 | /* |
5802 | * Remove any CTLESC characters from a string. | 5787 | * Remove any CTLESC characters from a string. |
5803 | */ | 5788 | */ |
5804 | |||
5805 | static char * | 5789 | static char * |
5806 | _rmescapes(char *str, int flag) | 5790 | _rmescapes(char *str, int flag) |
5807 | { | 5791 | { |
@@ -5855,7 +5839,7 @@ _rmescapes(char *str, int flag) | |||
5855 | } | 5839 | } |
5856 | } | 5840 | } |
5857 | notescaped = globbing; | 5841 | notescaped = globbing; |
5858 | copy: | 5842 | copy: |
5859 | *q++ = *p++; | 5843 | *q++ = *p++; |
5860 | } | 5844 | } |
5861 | *q = '\0'; | 5845 | *q = '\0'; |
@@ -5870,8 +5854,7 @@ copy: | |||
5870 | /* | 5854 | /* |
5871 | * See if a pattern matches in a case statement. | 5855 | * See if a pattern matches in a case statement. |
5872 | */ | 5856 | */ |
5873 | 5857 | static int | |
5874 | int | ||
5875 | casematch(union node *pattern, char *val) | 5858 | casematch(union node *pattern, char *val) |
5876 | { | 5859 | { |
5877 | struct stackmark smark; | 5860 | struct stackmark smark; |
@@ -5888,10 +5871,10 @@ casematch(union node *pattern, char *val) | |||
5888 | return result; | 5871 | return result; |
5889 | } | 5872 | } |
5890 | 5873 | ||
5874 | |||
5891 | /* | 5875 | /* |
5892 | * Our own itoa(). | 5876 | * Our own itoa(). |
5893 | */ | 5877 | */ |
5894 | |||
5895 | static int | 5878 | static int |
5896 | cvtnum(arith_t num) | 5879 | cvtnum(arith_t num) |
5897 | { | 5880 | { |
@@ -6043,7 +6026,7 @@ static int preadfd(void) | |||
6043 | char *buf = parsefile->buf; | 6026 | char *buf = parsefile->buf; |
6044 | parsenextc = buf; | 6027 | parsenextc = buf; |
6045 | 6028 | ||
6046 | retry: | 6029 | retry: |
6047 | #if ENABLE_FEATURE_EDITING | 6030 | #if ENABLE_FEATURE_EDITING |
6048 | if (!iflag || parsefile->fd) | 6031 | if (!iflag || parsefile->fd) |
6049 | nr = safe_read(parsefile->fd, buf, BUFSIZ - 1); | 6032 | nr = safe_read(parsefile->fd, buf, BUFSIZ - 1); |
@@ -6095,8 +6078,7 @@ retry: | |||
6095 | * 3) If the is more stuff in this buffer, use it else call read to fill it. | 6078 | * 3) If the is more stuff in this buffer, use it else call read to fill it. |
6096 | * 4) Process input up to the next newline, deleting nul characters. | 6079 | * 4) Process input up to the next newline, deleting nul characters. |
6097 | */ | 6080 | */ |
6098 | 6081 | static int | |
6099 | int | ||
6100 | preadbuffer(void) | 6082 | preadbuffer(void) |
6101 | { | 6083 | { |
6102 | char *q; | 6084 | char *q; |
@@ -6120,8 +6102,9 @@ preadbuffer(void) | |||
6120 | 6102 | ||
6121 | more = parselleft; | 6103 | more = parselleft; |
6122 | if (more <= 0) { | 6104 | if (more <= 0) { |
6123 | again: | 6105 | again: |
6124 | if ((more = preadfd()) <= 0) { | 6106 | more = preadfd(); |
6107 | if (more <= 0) { | ||
6125 | parselleft = parsenleft = EOF_NLEFT; | 6108 | parselleft = parsenleft = EOF_NLEFT; |
6126 | return PEOF; | 6109 | return PEOF; |
6127 | } | 6110 | } |
@@ -6171,8 +6154,7 @@ again: | |||
6171 | * Undo the last call to pgetc. Only one character may be pushed back. | 6154 | * Undo the last call to pgetc. Only one character may be pushed back. |
6172 | * PEOF may be pushed back. | 6155 | * PEOF may be pushed back. |
6173 | */ | 6156 | */ |
6174 | 6157 | static void | |
6175 | void | ||
6176 | pungetc(void) | 6158 | pungetc(void) |
6177 | { | 6159 | { |
6178 | parsenleft++; | 6160 | parsenleft++; |
@@ -6183,7 +6165,7 @@ pungetc(void) | |||
6183 | * Push a string back onto the input at this current parsefile level. | 6165 | * Push a string back onto the input at this current parsefile level. |
6184 | * We handle aliases this way. | 6166 | * We handle aliases this way. |
6185 | */ | 6167 | */ |
6186 | void | 6168 | static void |
6187 | pushstring(char *s, void *ap) | 6169 | pushstring(char *s, void *ap) |
6188 | { | 6170 | { |
6189 | struct strpush *sp; | 6171 | struct strpush *sp; |
@@ -6212,7 +6194,7 @@ pushstring(char *s, void *ap) | |||
6212 | INTON; | 6194 | INTON; |
6213 | } | 6195 | } |
6214 | 6196 | ||
6215 | void | 6197 | static void |
6216 | popstring(void) | 6198 | popstring(void) |
6217 | { | 6199 | { |
6218 | struct strpush *sp = parsefile->strpush; | 6200 | struct strpush *sp = parsefile->strpush; |
@@ -6241,11 +6223,11 @@ popstring(void) | |||
6241 | INTON; | 6223 | INTON; |
6242 | } | 6224 | } |
6243 | 6225 | ||
6226 | |||
6244 | /* | 6227 | /* |
6245 | * Set the input to take input from a file. If push is set, push the | 6228 | * Set the input to take input from a file. If push is set, push the |
6246 | * old input onto the stack first. | 6229 | * old input onto the stack first. |
6247 | */ | 6230 | */ |
6248 | |||
6249 | static int | 6231 | static int |
6250 | setinputfile(const char *fname, int flags) | 6232 | setinputfile(const char *fname, int flags) |
6251 | { | 6233 | { |
@@ -6253,7 +6235,8 @@ setinputfile(const char *fname, int flags) | |||
6253 | int fd2; | 6235 | int fd2; |
6254 | 6236 | ||
6255 | INTOFF; | 6237 | INTOFF; |
6256 | if ((fd = open(fname, O_RDONLY)) < 0) { | 6238 | fd = open(fname, O_RDONLY); |
6239 | if (fd < 0) { | ||
6257 | if (flags & INPUT_NOFILE_OK) | 6240 | if (flags & INPUT_NOFILE_OK) |
6258 | goto out; | 6241 | goto out; |
6259 | sh_error("Can't open %s", fname); | 6242 | sh_error("Can't open %s", fname); |
@@ -6266,7 +6249,7 @@ setinputfile(const char *fname, int flags) | |||
6266 | fd = fd2; | 6249 | fd = fd2; |
6267 | } | 6250 | } |
6268 | setinputfd(fd, flags & INPUT_PUSH_FILE); | 6251 | setinputfd(fd, flags & INPUT_PUSH_FILE); |
6269 | out: | 6252 | out: |
6270 | INTON; | 6253 | INTON; |
6271 | return fd; | 6254 | return fd; |
6272 | } | 6255 | } |
@@ -6276,7 +6259,6 @@ out: | |||
6276 | * Like setinputfile, but takes an open file descriptor. Call this with | 6259 | * Like setinputfile, but takes an open file descriptor. Call this with |
6277 | * interrupts off. | 6260 | * interrupts off. |
6278 | */ | 6261 | */ |
6279 | |||
6280 | static void | 6262 | static void |
6281 | setinputfd(int fd, int push) | 6263 | setinputfd(int fd, int push) |
6282 | { | 6264 | { |
@@ -6296,7 +6278,6 @@ setinputfd(int fd, int push) | |||
6296 | /* | 6278 | /* |
6297 | * Like setinputfile, but takes input from a string. | 6279 | * Like setinputfile, but takes input from a string. |
6298 | */ | 6280 | */ |
6299 | |||
6300 | static void | 6281 | static void |
6301 | setinputstring(char *string) | 6282 | setinputstring(char *string) |
6302 | { | 6283 | { |
@@ -6314,7 +6295,6 @@ setinputstring(char *string) | |||
6314 | * To handle the "." command, a stack of input files is used. Pushfile | 6295 | * To handle the "." command, a stack of input files is used. Pushfile |
6315 | * adds a new entry to the stack and popfile restores the previous level. | 6296 | * adds a new entry to the stack and popfile restores the previous level. |
6316 | */ | 6297 | */ |
6317 | |||
6318 | static void | 6298 | static void |
6319 | pushfile(void) | 6299 | pushfile(void) |
6320 | { | 6300 | { |
@@ -6358,7 +6338,6 @@ popfile(void) | |||
6358 | /* | 6338 | /* |
6359 | * Return to top level. | 6339 | * Return to top level. |
6360 | */ | 6340 | */ |
6361 | |||
6362 | static void | 6341 | static void |
6363 | popallfiles(void) | 6342 | popallfiles(void) |
6364 | { | 6343 | { |
@@ -6371,7 +6350,6 @@ popallfiles(void) | |||
6371 | * Close the file(s) that the shell is reading commands from. Called | 6350 | * Close the file(s) that the shell is reading commands from. Called |
6372 | * after a fork is done. | 6351 | * after a fork is done. |
6373 | */ | 6352 | */ |
6374 | |||
6375 | static void | 6353 | static void |
6376 | closescript(void) | 6354 | closescript(void) |
6377 | { | 6355 | { |
@@ -6484,8 +6462,7 @@ set_curjob(struct job *jp, unsigned mode) | |||
6484 | * | 6462 | * |
6485 | * Called with interrupts off. | 6463 | * Called with interrupts off. |
6486 | */ | 6464 | */ |
6487 | 6465 | static void | |
6488 | void | ||
6489 | setjobctl(int on) | 6466 | setjobctl(int on) |
6490 | { | 6467 | { |
6491 | int fd; | 6468 | int fd; |
@@ -6511,8 +6488,9 @@ setjobctl(int on) | |||
6511 | goto out; | 6488 | goto out; |
6512 | fcntl(fd, F_SETFD, FD_CLOEXEC); | 6489 | fcntl(fd, F_SETFD, FD_CLOEXEC); |
6513 | do { /* while we are in the background */ | 6490 | do { /* while we are in the background */ |
6514 | if ((pgrp = tcgetpgrp(fd)) < 0) { | 6491 | pgrp = tcgetpgrp(fd); |
6515 | out: | 6492 | if (pgrp < 0) { |
6493 | out: | ||
6516 | sh_warnx("can't access tty; job control turned off"); | 6494 | sh_warnx("can't access tty; job control turned off"); |
6517 | mflag = on = 0; | 6495 | mflag = on = 0; |
6518 | goto close; | 6496 | goto close; |
@@ -6538,7 +6516,7 @@ out: | |||
6538 | setsignal(SIGTSTP); | 6516 | setsignal(SIGTSTP); |
6539 | setsignal(SIGTTOU); | 6517 | setsignal(SIGTTOU); |
6540 | setsignal(SIGTTIN); | 6518 | setsignal(SIGTTIN); |
6541 | close: | 6519 | close: |
6542 | close(fd); | 6520 | close(fd); |
6543 | fd = -1; | 6521 | fd = -1; |
6544 | } | 6522 | } |
@@ -6556,7 +6534,7 @@ killcmd(int argc, char **argv) | |||
6556 | struct job *jp; | 6534 | struct job *jp; |
6557 | 6535 | ||
6558 | if (argc <= 1) { | 6536 | if (argc <= 1) { |
6559 | usage: | 6537 | usage: |
6560 | sh_error( | 6538 | sh_error( |
6561 | "Usage: kill [-s sigspec | -signum | -sigspec] [pid | job]... or\n" | 6539 | "Usage: kill [-s sigspec | -signum | -sigspec] [pid | job]... or\n" |
6562 | "kill -l [exitstatus]" | 6540 | "kill -l [exitstatus]" |
@@ -6697,7 +6675,7 @@ restartjob(struct job *jp, int mode) | |||
6697 | ps->status = -1; | 6675 | ps->status = -1; |
6698 | } | 6676 | } |
6699 | } while (ps++, --i); | 6677 | } while (ps++, --i); |
6700 | out: | 6678 | out: |
6701 | status = (mode == FORK_FG) ? waitforjob(jp) : 0; | 6679 | status = (mode == FORK_FG) ? waitforjob(jp) : 0; |
6702 | INTON; | 6680 | INTON; |
6703 | return status; | 6681 | return status; |
@@ -6738,8 +6716,7 @@ sprint_status(char *s, int status, int sigonly) | |||
6738 | else | 6716 | else |
6739 | col = fmtstr(s, 16, "Done"); | 6717 | col = fmtstr(s, 16, "Done"); |
6740 | } | 6718 | } |
6741 | 6719 | out: | |
6742 | out: | ||
6743 | return col; | 6720 | return col; |
6744 | } | 6721 | } |
6745 | 6722 | ||
@@ -6791,8 +6768,7 @@ showjob(FILE *out, struct job *jp, int mode) | |||
6791 | do { | 6768 | do { |
6792 | /* for each process */ | 6769 | /* for each process */ |
6793 | col = fmtstr(s, 48, " |\n%*c%d ", indent, ' ', ps->pid) - 3; | 6770 | col = fmtstr(s, 48, " |\n%*c%d ", indent, ' ', ps->pid) - 3; |
6794 | 6771 | start: | |
6795 | start: | ||
6796 | fprintf(out, "%s%*c%s", | 6772 | fprintf(out, "%s%*c%s", |
6797 | s, 33 - col >= 0 ? 33 - col : 0, ' ', ps->cmd | 6773 | s, 33 - col >= 0 ? 33 - col : 0, ' ', ps->cmd |
6798 | ); | 6774 | ); |
@@ -6845,7 +6821,6 @@ jobscmd(int argc, char **argv) | |||
6845 | * Print a list of jobs. If "change" is nonzero, only print jobs whose | 6821 | * Print a list of jobs. If "change" is nonzero, only print jobs whose |
6846 | * statuses have changed since the last call to showjobs. | 6822 | * statuses have changed since the last call to showjobs. |
6847 | */ | 6823 | */ |
6848 | |||
6849 | static void | 6824 | static void |
6850 | showjobs(FILE *out, int mode) | 6825 | showjobs(FILE *out, int mode) |
6851 | { | 6826 | { |
@@ -6864,10 +6839,10 @@ showjobs(FILE *out, int mode) | |||
6864 | } | 6839 | } |
6865 | #endif /* JOBS */ | 6840 | #endif /* JOBS */ |
6866 | 6841 | ||
6842 | |||
6867 | /* | 6843 | /* |
6868 | * Mark a job structure as unused. | 6844 | * Mark a job structure as unused. |
6869 | */ | 6845 | */ |
6870 | |||
6871 | static void | 6846 | static void |
6872 | freejob(struct job *jp) | 6847 | freejob(struct job *jp) |
6873 | { | 6848 | { |
@@ -6928,7 +6903,7 @@ waitcmd(int argc, char **argv) | |||
6928 | if (job->ps[job->nprocs - 1].pid == pid) | 6903 | if (job->ps[job->nprocs - 1].pid == pid) |
6929 | break; | 6904 | break; |
6930 | job = job->prev_job; | 6905 | job = job->prev_job; |
6931 | start: | 6906 | start: |
6932 | if (!job) | 6907 | if (!job) |
6933 | goto repeat; | 6908 | goto repeat; |
6934 | } while (1); | 6909 | } while (1); |
@@ -6939,11 +6914,11 @@ start: | |||
6939 | dowait(DOWAIT_BLOCK, 0); | 6914 | dowait(DOWAIT_BLOCK, 0); |
6940 | job->waited = 1; | 6915 | job->waited = 1; |
6941 | retval = getstatus(job); | 6916 | retval = getstatus(job); |
6942 | repeat: | 6917 | repeat: |
6943 | ; | 6918 | ; |
6944 | } while (*++argv); | 6919 | } while (*++argv); |
6945 | 6920 | ||
6946 | out: | 6921 | out: |
6947 | return retval; | 6922 | return retval; |
6948 | } | 6923 | } |
6949 | 6924 | ||
@@ -6951,7 +6926,6 @@ out: | |||
6951 | /* | 6926 | /* |
6952 | * Convert a job name to a job structure. | 6927 | * Convert a job name to a job structure. |
6953 | */ | 6928 | */ |
6954 | |||
6955 | static struct job * | 6929 | static struct job * |
6956 | getjob(const char *name, int getctl) | 6930 | getjob(const char *name, int getctl) |
6957 | { | 6931 | { |
@@ -6977,14 +6951,14 @@ getjob(const char *name, int getctl) | |||
6977 | 6951 | ||
6978 | if (!p[1]) { | 6952 | if (!p[1]) { |
6979 | if (c == '+' || c == '%') { | 6953 | if (c == '+' || c == '%') { |
6980 | currentjob: | 6954 | currentjob: |
6981 | err_msg = "No current job"; | 6955 | err_msg = "No current job"; |
6982 | goto check; | 6956 | goto check; |
6983 | } else if (c == '-') { | 6957 | } else if (c == '-') { |
6984 | if (jp) | 6958 | if (jp) |
6985 | jp = jp->prev_job; | 6959 | jp = jp->prev_job; |
6986 | err_msg = "No previous job"; | 6960 | err_msg = "No previous job"; |
6987 | check: | 6961 | check: |
6988 | if (!jp) | 6962 | if (!jp) |
6989 | goto err; | 6963 | goto err; |
6990 | goto gotit; | 6964 | goto gotit; |
@@ -7020,14 +6994,14 @@ check: | |||
7020 | jp = jp->prev_job; | 6994 | jp = jp->prev_job; |
7021 | } | 6995 | } |
7022 | 6996 | ||
7023 | gotit: | 6997 | gotit: |
7024 | #if JOBS | 6998 | #if JOBS |
7025 | err_msg = "job %s not created under job control"; | 6999 | err_msg = "job %s not created under job control"; |
7026 | if (getctl && jp->jobctl == 0) | 7000 | if (getctl && jp->jobctl == 0) |
7027 | goto err; | 7001 | goto err; |
7028 | #endif | 7002 | #endif |
7029 | return jp; | 7003 | return jp; |
7030 | err: | 7004 | err: |
7031 | sh_error(err_msg, name); | 7005 | sh_error(err_msg, name); |
7032 | } | 7006 | } |
7033 | 7007 | ||
@@ -7136,7 +7110,6 @@ growjobtab(void) | |||
7136 | * | 7110 | * |
7137 | * Called with interrupts off. | 7111 | * Called with interrupts off. |
7138 | */ | 7112 | */ |
7139 | |||
7140 | static void forkchild(struct job *jp, union node *n, int mode) | 7113 | static void forkchild(struct job *jp, union node *n, int mode) |
7141 | { | 7114 | { |
7142 | int oldlvl; | 7115 | int oldlvl; |
@@ -7240,6 +7213,7 @@ forkshell(struct job *jp, union node *n, int mode) | |||
7240 | return pid; | 7213 | return pid; |
7241 | } | 7214 | } |
7242 | 7215 | ||
7216 | |||
7243 | /* | 7217 | /* |
7244 | * Wait for job to finish. | 7218 | * Wait for job to finish. |
7245 | * | 7219 | * |
@@ -7260,8 +7234,7 @@ forkshell(struct job *jp, union node *n, int mode) | |||
7260 | * | 7234 | * |
7261 | * Called with interrupts off. | 7235 | * Called with interrupts off. |
7262 | */ | 7236 | */ |
7263 | 7237 | static int | |
7264 | int | ||
7265 | waitforjob(struct job *jp) | 7238 | waitforjob(struct job *jp) |
7266 | { | 7239 | { |
7267 | int st; | 7240 | int st; |
@@ -7320,7 +7293,6 @@ waitforjob(struct job *jp) | |||
7320 | * (as opposed to running a builtin command or just typing return), | 7293 | * (as opposed to running a builtin command or just typing return), |
7321 | * and the jobs command may give out of date information. | 7294 | * and the jobs command may give out of date information. |
7322 | */ | 7295 | */ |
7323 | |||
7324 | static int waitproc(int block, int *status) | 7296 | static int waitproc(int block, int *status) |
7325 | { | 7297 | { |
7326 | int flags = 0; | 7298 | int flags = 0; |
@@ -7334,10 +7306,10 @@ static int waitproc(int block, int *status) | |||
7334 | return wait3(status, flags, (struct rusage *)NULL); | 7306 | return wait3(status, flags, (struct rusage *)NULL); |
7335 | } | 7307 | } |
7336 | 7308 | ||
7309 | |||
7337 | /* | 7310 | /* |
7338 | * Wait for a process to terminate. | 7311 | * Wait for a process to terminate. |
7339 | */ | 7312 | */ |
7340 | |||
7341 | static int | 7313 | static int |
7342 | dowait(int block, struct job *job) | 7314 | dowait(int block, struct job *job) |
7343 | { | 7315 | { |
@@ -7391,7 +7363,7 @@ dowait(int block, struct job *job) | |||
7391 | jobless--; | 7363 | jobless--; |
7392 | goto out; | 7364 | goto out; |
7393 | 7365 | ||
7394 | gotjob: | 7366 | gotjob: |
7395 | if (state != JOBRUNNING) { | 7367 | if (state != JOBRUNNING) { |
7396 | thisjob->changed = 1; | 7368 | thisjob->changed = 1; |
7397 | 7369 | ||
@@ -7407,7 +7379,7 @@ gotjob: | |||
7407 | } | 7379 | } |
7408 | } | 7380 | } |
7409 | 7381 | ||
7410 | out: | 7382 | out: |
7411 | INTON; | 7383 | INTON; |
7412 | 7384 | ||
7413 | if (thisjob && thisjob == job) { | 7385 | if (thisjob && thisjob == job) { |
@@ -7428,7 +7400,6 @@ out: | |||
7428 | /* | 7400 | /* |
7429 | * return 1 if there are stopped jobs, otherwise 0 | 7401 | * return 1 if there are stopped jobs, otherwise 0 |
7430 | */ | 7402 | */ |
7431 | |||
7432 | int | 7403 | int |
7433 | stoppedjobs(void) | 7404 | stoppedjobs(void) |
7434 | { | 7405 | { |
@@ -7453,7 +7424,6 @@ out: | |||
7453 | * Return a string identifying a command (to be printed by the | 7424 | * Return a string identifying a command (to be printed by the |
7454 | * jobs command). | 7425 | * jobs command). |
7455 | */ | 7426 | */ |
7456 | |||
7457 | #if JOBS | 7427 | #if JOBS |
7458 | static char *cmdnextc; | 7428 | static char *cmdnextc; |
7459 | 7429 | ||
@@ -7503,7 +7473,7 @@ cmdtxt(union node *n) | |||
7503 | goto binop; | 7473 | goto binop; |
7504 | case NOR: | 7474 | case NOR: |
7505 | p = " || "; | 7475 | p = " || "; |
7506 | binop: | 7476 | binop: |
7507 | cmdtxt(n->nbinary.ch1); | 7477 | cmdtxt(n->nbinary.ch1); |
7508 | cmdputs(p); | 7478 | cmdputs(p); |
7509 | n = n->nbinary.ch2; | 7479 | n = n->nbinary.ch2; |
@@ -7515,7 +7485,7 @@ binop: | |||
7515 | case NNOT: | 7485 | case NNOT: |
7516 | cmdputs("!"); | 7486 | cmdputs("!"); |
7517 | n = n->nnot.com; | 7487 | n = n->nnot.com; |
7518 | donode: | 7488 | donode: |
7519 | cmdtxt(n); | 7489 | cmdtxt(n); |
7520 | break; | 7490 | break; |
7521 | case NIF: | 7491 | case NIF: |
@@ -7540,14 +7510,14 @@ donode: | |||
7540 | goto until; | 7510 | goto until; |
7541 | case NUNTIL: | 7511 | case NUNTIL: |
7542 | p = "until "; | 7512 | p = "until "; |
7543 | until: | 7513 | until: |
7544 | cmdputs(p); | 7514 | cmdputs(p); |
7545 | cmdtxt(n->nbinary.ch1); | 7515 | cmdtxt(n->nbinary.ch1); |
7546 | n = n->nbinary.ch2; | 7516 | n = n->nbinary.ch2; |
7547 | p = "; done"; | 7517 | p = "; done"; |
7548 | dodo: | 7518 | dodo: |
7549 | cmdputs("; do "); | 7519 | cmdputs("; do "); |
7550 | dotail: | 7520 | dotail: |
7551 | cmdtxt(n); | 7521 | cmdtxt(n); |
7552 | goto dotail2; | 7522 | goto dotail2; |
7553 | case NFOR: | 7523 | case NFOR: |
@@ -7568,7 +7538,7 @@ dotail: | |||
7568 | break; | 7538 | break; |
7569 | case NARG: | 7539 | case NARG: |
7570 | p = n->narg.text; | 7540 | p = n->narg.text; |
7571 | dotail2: | 7541 | dotail2: |
7572 | cmdputs(p); | 7542 | cmdputs(p); |
7573 | break; | 7543 | break; |
7574 | case NHERE: | 7544 | case NHERE: |
@@ -7607,7 +7577,7 @@ dotail2: | |||
7607 | goto redir; | 7577 | goto redir; |
7608 | case NFROMTO: | 7578 | case NFROMTO: |
7609 | p = "<>"; | 7579 | p = "<>"; |
7610 | redir: | 7580 | redir: |
7611 | s[0] = n->nfile.fd + '0'; | 7581 | s[0] = n->nfile.fd + '0'; |
7612 | s[1] = '\0'; | 7582 | s[1] = '\0'; |
7613 | cmdputs(s); | 7583 | cmdputs(s); |
@@ -7714,10 +7684,10 @@ cmdputs(const char *s) | |||
7714 | break; | 7684 | break; |
7715 | } | 7685 | } |
7716 | USTPUTC(c, nextc); | 7686 | USTPUTC(c, nextc); |
7717 | checkstr: | 7687 | checkstr: |
7718 | if (!str) | 7688 | if (!str) |
7719 | continue; | 7689 | continue; |
7720 | dostr: | 7690 | dostr: |
7721 | while ((c = *str++)) { | 7691 | while ((c = *str++)) { |
7722 | USTPUTC(c, nextc); | 7692 | USTPUTC(c, nextc); |
7723 | } | 7693 | } |
@@ -7793,14 +7763,12 @@ static time_t mailtime[MAXMBOXES]; | |||
7793 | static int mail_var_path_changed; | 7763 | static int mail_var_path_changed; |
7794 | 7764 | ||
7795 | 7765 | ||
7796 | |||
7797 | /* | 7766 | /* |
7798 | * Print appropriate message(s) if mail has arrived. | 7767 | * Print appropriate message(s) if mail has arrived. |
7799 | * If mail_var_path_changed is set, | 7768 | * If mail_var_path_changed is set, |
7800 | * then the value of MAIL has mail_var_path_changed, | 7769 | * then the value of MAIL has mail_var_path_changed, |
7801 | * so we just update the values. | 7770 | * so we just update the values. |
7802 | */ | 7771 | */ |
7803 | |||
7804 | static void | 7772 | static void |
7805 | chkmail(void) | 7773 | chkmail(void) |
7806 | { | 7774 | { |
@@ -7869,7 +7837,6 @@ static void read_profile(const char *); | |||
7869 | * exception occurs. When an exception occurs the variable "state" | 7837 | * exception occurs. When an exception occurs the variable "state" |
7870 | * is used to figure out how far we had gotten. | 7838 | * is used to figure out how far we had gotten. |
7871 | */ | 7839 | */ |
7872 | |||
7873 | int ash_main(int argc, char **argv); | 7840 | int ash_main(int argc, char **argv); |
7874 | int ash_main(int argc, char **argv) | 7841 | int ash_main(int argc, char **argv) |
7875 | { | 7842 | { |
@@ -7949,11 +7916,11 @@ int ash_main(int argc, char **argv) | |||
7949 | if (isloginsh) { | 7916 | if (isloginsh) { |
7950 | state = 1; | 7917 | state = 1; |
7951 | read_profile("/etc/profile"); | 7918 | read_profile("/etc/profile"); |
7952 | state1: | 7919 | state1: |
7953 | state = 2; | 7920 | state = 2; |
7954 | read_profile(".profile"); | 7921 | read_profile(".profile"); |
7955 | } | 7922 | } |
7956 | state2: | 7923 | state2: |
7957 | state = 3; | 7924 | state = 3; |
7958 | if ( | 7925 | if ( |
7959 | #ifndef linux | 7926 | #ifndef linux |
@@ -7961,11 +7928,12 @@ state2: | |||
7961 | #endif | 7928 | #endif |
7962 | iflag | 7929 | iflag |
7963 | ) { | 7930 | ) { |
7964 | if ((shinit = lookupvar("ENV")) != NULL && *shinit != '\0') { | 7931 | shinit = lookupvar("ENV"); |
7932 | if (shinit != NULL && *shinit != '\0') { | ||
7965 | read_profile(shinit); | 7933 | read_profile(shinit); |
7966 | } | 7934 | } |
7967 | } | 7935 | } |
7968 | state3: | 7936 | state3: |
7969 | state = 4; | 7937 | state = 4; |
7970 | if (minusc) | 7938 | if (minusc) |
7971 | evalstring(minusc, 0); | 7939 | evalstring(minusc, 0); |
@@ -8000,7 +7968,6 @@ state3: | |||
8000 | * Read and execute commands. "Top" is nonzero for the top level command | 7968 | * Read and execute commands. "Top" is nonzero for the top level command |
8001 | * loop; it turns on prompting if the shell is interactive. | 7969 | * loop; it turns on prompting if the shell is interactive. |
8002 | */ | 7970 | */ |
8003 | |||
8004 | static int | 7971 | static int |
8005 | cmdloop(int top) | 7972 | cmdloop(int top) |
8006 | { | 7973 | { |
@@ -8057,7 +8024,6 @@ cmdloop(int top) | |||
8057 | /* | 8024 | /* |
8058 | * Read /etc/profile or .profile. Return on error. | 8025 | * Read /etc/profile or .profile. Return on error. |
8059 | */ | 8026 | */ |
8060 | |||
8061 | static void | 8027 | static void |
8062 | read_profile(const char *name) | 8028 | read_profile(const char *name) |
8063 | { | 8029 | { |
@@ -8077,7 +8043,6 @@ read_profile(const char *name) | |||
8077 | /* | 8043 | /* |
8078 | * Read a file containing shell functions. | 8044 | * Read a file containing shell functions. |
8079 | */ | 8045 | */ |
8080 | |||
8081 | static void | 8046 | static void |
8082 | readcmdfile(char *name) | 8047 | readcmdfile(char *name) |
8083 | { | 8048 | { |
@@ -8091,7 +8056,6 @@ readcmdfile(char *name) | |||
8091 | * Take commands from a file. To be compatible we should do a path | 8056 | * Take commands from a file. To be compatible we should do a path |
8092 | * search for the file, which is necessary to find sub-commands. | 8057 | * search for the file, which is necessary to find sub-commands. |
8093 | */ | 8058 | */ |
8094 | |||
8095 | static char * find_dot_file(char *name) | 8059 | static char * find_dot_file(char *name) |
8096 | { | 8060 | { |
8097 | char *fullname; | 8061 | char *fullname; |
@@ -8186,7 +8150,6 @@ testcmd(int argc, char **argv) | |||
8186 | /* | 8150 | /* |
8187 | * Same for malloc, realloc, but returns an error when out of space. | 8151 | * Same for malloc, realloc, but returns an error when out of space. |
8188 | */ | 8152 | */ |
8189 | |||
8190 | static pointer | 8153 | static pointer |
8191 | ckrealloc(pointer p, size_t nbytes) | 8154 | ckrealloc(pointer p, size_t nbytes) |
8192 | { | 8155 | { |
@@ -8205,7 +8168,6 @@ ckmalloc(size_t nbytes) | |||
8205 | /* | 8168 | /* |
8206 | * Make a copy of a string in safe storage. | 8169 | * Make a copy of a string in safe storage. |
8207 | */ | 8170 | */ |
8208 | |||
8209 | static char * | 8171 | static char * |
8210 | savestr(const char *s) | 8172 | savestr(const char *s) |
8211 | { | 8173 | { |
@@ -8224,8 +8186,6 @@ savestr(const char *s) | |||
8224 | * The size 504 was chosen because the Ultrix malloc handles that size | 8186 | * The size 504 was chosen because the Ultrix malloc handles that size |
8225 | * well. | 8187 | * well. |
8226 | */ | 8188 | */ |
8227 | |||
8228 | |||
8229 | static pointer | 8189 | static pointer |
8230 | stalloc(size_t nbytes) | 8190 | stalloc(size_t nbytes) |
8231 | { | 8191 | { |
@@ -8260,7 +8220,7 @@ stalloc(size_t nbytes) | |||
8260 | } | 8220 | } |
8261 | 8221 | ||
8262 | 8222 | ||
8263 | void | 8223 | static void |
8264 | stunalloc(pointer p) | 8224 | stunalloc(pointer p) |
8265 | { | 8225 | { |
8266 | #if DEBUG | 8226 | #if DEBUG |
@@ -8274,7 +8234,7 @@ stunalloc(pointer p) | |||
8274 | } | 8234 | } |
8275 | 8235 | ||
8276 | 8236 | ||
8277 | void | 8237 | static void |
8278 | setstackmark(struct stackmark *mark) | 8238 | setstackmark(struct stackmark *mark) |
8279 | { | 8239 | { |
8280 | mark->stackp = stackp; | 8240 | mark->stackp = stackp; |
@@ -8285,7 +8245,7 @@ setstackmark(struct stackmark *mark) | |||
8285 | } | 8245 | } |
8286 | 8246 | ||
8287 | 8247 | ||
8288 | void | 8248 | static void |
8289 | popstackmark(struct stackmark *mark) | 8249 | popstackmark(struct stackmark *mark) |
8290 | { | 8250 | { |
8291 | struct stack_block *sp; | 8251 | struct stack_block *sp; |
@@ -8313,8 +8273,7 @@ popstackmark(struct stackmark *mark) | |||
8313 | * possibly moving it (like realloc). Grabstackblock actually allocates the | 8273 | * possibly moving it (like realloc). Grabstackblock actually allocates the |
8314 | * part of the block that has been used. | 8274 | * part of the block that has been used. |
8315 | */ | 8275 | */ |
8316 | 8276 | static void | |
8317 | void | ||
8318 | growstackblock(void) | 8277 | growstackblock(void) |
8319 | { | 8278 | { |
8320 | size_t newlen; | 8279 | size_t newlen; |
@@ -8374,6 +8333,7 @@ static void grabstackblock(size_t len) | |||
8374 | stacknleft -= len; | 8333 | stacknleft -= len; |
8375 | } | 8334 | } |
8376 | 8335 | ||
8336 | |||
8377 | /* | 8337 | /* |
8378 | * The following routines are somewhat easier to use than the above. | 8338 | * The following routines are somewhat easier to use than the above. |
8379 | * The user declares a variable of type STACKSTR, which may be declared | 8339 | * The user declares a variable of type STACKSTR, which may be declared |
@@ -8391,8 +8351,7 @@ static void grabstackblock(size_t len) | |||
8391 | * CHECKSTACKSPACE can be called before USTPUTC to ensure that there | 8351 | * CHECKSTACKSPACE can be called before USTPUTC to ensure that there |
8392 | * is space for at least one character. | 8352 | * is space for at least one character. |
8393 | */ | 8353 | */ |
8394 | 8354 | static void * | |
8395 | void * | ||
8396 | growstackstr(void) | 8355 | growstackstr(void) |
8397 | { | 8356 | { |
8398 | size_t len = stackblocksize(); | 8357 | size_t len = stackblocksize(); |
@@ -8407,8 +8366,7 @@ growstackstr(void) | |||
8407 | /* | 8366 | /* |
8408 | * Called from CHECKSTRSPACE. | 8367 | * Called from CHECKSTRSPACE. |
8409 | */ | 8368 | */ |
8410 | 8369 | static char * | |
8411 | char * | ||
8412 | makestrspace(size_t newlen, char *p) | 8370 | makestrspace(size_t newlen, char *p) |
8413 | { | 8371 | { |
8414 | size_t len = p - stacknxt; | 8372 | size_t len = p - stacknxt; |
@@ -8426,7 +8384,7 @@ makestrspace(size_t newlen, char *p) | |||
8426 | return stackblock() + len; | 8384 | return stackblock() + len; |
8427 | } | 8385 | } |
8428 | 8386 | ||
8429 | char * | 8387 | static char * |
8430 | stnputs(const char *s, size_t n, char *p) | 8388 | stnputs(const char *s, size_t n, char *p) |
8431 | { | 8389 | { |
8432 | p = makestrspace(n, p); | 8390 | p = makestrspace(n, p); |
@@ -8434,7 +8392,7 @@ stnputs(const char *s, size_t n, char *p) | |||
8434 | return p; | 8392 | return p; |
8435 | } | 8393 | } |
8436 | 8394 | ||
8437 | char * | 8395 | static char * |
8438 | stputs(const char *s, char *p) | 8396 | stputs(const char *s, char *p) |
8439 | { | 8397 | { |
8440 | return stnputs(s, strlen(s), p); | 8398 | return stnputs(s, strlen(s), p); |
@@ -8452,8 +8410,7 @@ stputs(const char *s, char *p) | |||
8452 | /* | 8410 | /* |
8453 | * prefix -- see if pfx is a prefix of string. | 8411 | * prefix -- see if pfx is a prefix of string. |
8454 | */ | 8412 | */ |
8455 | 8413 | static char * | |
8456 | char * | ||
8457 | prefix(const char *string, const char *pfx) | 8414 | prefix(const char *string, const char *pfx) |
8458 | { | 8415 | { |
8459 | while (*pfx) { | 8416 | while (*pfx) { |
@@ -8468,11 +8425,9 @@ prefix(const char *string, const char *pfx) | |||
8468 | * Convert a string of digits to an integer, printing an error message on | 8425 | * Convert a string of digits to an integer, printing an error message on |
8469 | * failure. | 8426 | * failure. |
8470 | */ | 8427 | */ |
8471 | 8428 | static int | |
8472 | int | ||
8473 | number(const char *s) | 8429 | number(const char *s) |
8474 | { | 8430 | { |
8475 | |||
8476 | if (! is_number(s)) | 8431 | if (! is_number(s)) |
8477 | sh_error(illnum, s); | 8432 | sh_error(illnum, s); |
8478 | return atoi(s); | 8433 | return atoi(s); |
@@ -8482,8 +8437,7 @@ number(const char *s) | |||
8482 | /* | 8437 | /* |
8483 | * Check for a valid number. This should be elsewhere. | 8438 | * Check for a valid number. This should be elsewhere. |
8484 | */ | 8439 | */ |
8485 | 8440 | static int | |
8486 | int | ||
8487 | is_number(const char *p) | 8441 | is_number(const char *p) |
8488 | { | 8442 | { |
8489 | do { | 8443 | do { |
@@ -8498,9 +8452,9 @@ is_number(const char *p) | |||
8498 | * Produce a possibly single quoted string suitable as input to the shell. | 8452 | * Produce a possibly single quoted string suitable as input to the shell. |
8499 | * The return string is allocated on the stack. | 8453 | * The return string is allocated on the stack. |
8500 | */ | 8454 | */ |
8501 | 8455 | static char * | |
8502 | char * | 8456 | single_quote(const char *s) |
8503 | single_quote(const char *s) { | 8457 | { |
8504 | char *p; | 8458 | char *p; |
8505 | 8459 | ||
8506 | STARTSTACKSTR(p); | 8460 | STARTSTACKSTR(p); |
@@ -8539,11 +8493,11 @@ single_quote(const char *s) { | |||
8539 | return stackblock(); | 8493 | return stackblock(); |
8540 | } | 8494 | } |
8541 | 8495 | ||
8496 | |||
8542 | /* | 8497 | /* |
8543 | * Like strdup but works with the ash stack. | 8498 | * Like strdup but works with the ash stack. |
8544 | */ | 8499 | */ |
8545 | 8500 | static char * | |
8546 | char * | ||
8547 | sstrdup(const char *p) | 8501 | sstrdup(const char *p) |
8548 | { | 8502 | { |
8549 | size_t len = strlen(p) + 1; | 8503 | size_t len = strlen(p) + 1; |
@@ -8764,7 +8718,6 @@ nodesavestr(char *s) | |||
8764 | /* | 8718 | /* |
8765 | * Free a parse tree. | 8719 | * Free a parse tree. |
8766 | */ | 8720 | */ |
8767 | |||
8768 | static void | 8721 | static void |
8769 | freefunc(struct funcnode *f) | 8722 | freefunc(struct funcnode *f) |
8770 | { | 8723 | { |
@@ -8780,8 +8733,7 @@ static void setoption(int, int); | |||
8780 | /* | 8733 | /* |
8781 | * Process the shell command line arguments. | 8734 | * Process the shell command line arguments. |
8782 | */ | 8735 | */ |
8783 | 8736 | static void | |
8784 | void | ||
8785 | procargs(int argc, char **argv) | 8737 | procargs(int argc, char **argv) |
8786 | { | 8738 | { |
8787 | int i; | 8739 | int i; |
@@ -8820,7 +8772,7 @@ procargs(int argc, char **argv) | |||
8820 | goto setarg0; | 8772 | goto setarg0; |
8821 | } else if (!sflag) { | 8773 | } else if (!sflag) { |
8822 | setinputfile(*xargv, 0); | 8774 | setinputfile(*xargv, 0); |
8823 | setarg0: | 8775 | setarg0: |
8824 | arg0 = *xargv++; | 8776 | arg0 = *xargv++; |
8825 | commandname = arg0; | 8777 | commandname = arg0; |
8826 | } | 8778 | } |
@@ -8839,7 +8791,7 @@ setarg0: | |||
8839 | } | 8791 | } |
8840 | 8792 | ||
8841 | 8793 | ||
8842 | void | 8794 | static void |
8843 | optschanged(void) | 8795 | optschanged(void) |
8844 | { | 8796 | { |
8845 | #if DEBUG | 8797 | #if DEBUG |
@@ -8869,11 +8821,11 @@ static void minus_o(char *name, int val) | |||
8869 | } | 8821 | } |
8870 | } | 8822 | } |
8871 | 8823 | ||
8824 | |||
8872 | /* | 8825 | /* |
8873 | * Process shell options. The global variable argptr contains a pointer | 8826 | * Process shell options. The global variable argptr contains a pointer |
8874 | * to the argument list; we advance it past the options. | 8827 | * to the argument list; we advance it past the options. |
8875 | */ | 8828 | */ |
8876 | |||
8877 | static void | 8829 | static void |
8878 | options(int cmdline) | 8830 | options(int cmdline) |
8879 | { | 8831 | { |
@@ -8885,7 +8837,8 @@ options(int cmdline) | |||
8885 | minusc = NULL; | 8837 | minusc = NULL; |
8886 | while ((p = *argptr) != NULL) { | 8838 | while ((p = *argptr) != NULL) { |
8887 | argptr++; | 8839 | argptr++; |
8888 | if ((c = *p++) == '-') { | 8840 | c = *p++; |
8841 | if (c == '-') { | ||
8889 | val = 1; | 8842 | val = 1; |
8890 | if (p[0] == '\0' || LONE_DASH(p)) { | 8843 | if (p[0] == '\0' || LONE_DASH(p)) { |
8891 | if (!cmdline) { | 8844 | if (!cmdline) { |
@@ -8941,8 +8894,7 @@ setoption(int flag, int val) | |||
8941 | /* | 8894 | /* |
8942 | * Set the shell parameters. | 8895 | * Set the shell parameters. |
8943 | */ | 8896 | */ |
8944 | 8897 | static void | |
8945 | void | ||
8946 | setparam(char **argv) | 8898 | setparam(char **argv) |
8947 | { | 8899 | { |
8948 | char **newparam; | 8900 | char **newparam; |
@@ -8969,8 +8921,7 @@ setparam(char **argv) | |||
8969 | /* | 8921 | /* |
8970 | * Free the list of positional parameters. | 8922 | * Free the list of positional parameters. |
8971 | */ | 8923 | */ |
8972 | 8924 | static void | |
8973 | void | ||
8974 | freeparam(volatile struct shparam *param) | 8925 | freeparam(volatile struct shparam *param) |
8975 | { | 8926 | { |
8976 | char **ap; | 8927 | char **ap; |
@@ -8986,8 +8937,7 @@ freeparam(volatile struct shparam *param) | |||
8986 | /* | 8937 | /* |
8987 | * The shift builtin command. | 8938 | * The shift builtin command. |
8988 | */ | 8939 | */ |
8989 | 8940 | static int | |
8990 | int | ||
8991 | shiftcmd(int argc, char **argv) | 8941 | shiftcmd(int argc, char **argv) |
8992 | { | 8942 | { |
8993 | int n; | 8943 | int n; |
@@ -9018,8 +8968,7 @@ shiftcmd(int argc, char **argv) | |||
9018 | /* | 8968 | /* |
9019 | * The set command builtin. | 8969 | * The set command builtin. |
9020 | */ | 8970 | */ |
9021 | 8971 | static int | |
9022 | int | ||
9023 | setcmd(int argc, char **argv) | 8972 | setcmd(int argc, char **argv) |
9024 | { | 8973 | { |
9025 | if (argc == 1) | 8974 | if (argc == 1) |
@@ -9103,7 +9052,7 @@ getopts(char *optstr, char *optvar, char **optfirst, int *param_optind, int *opt | |||
9103 | /* Current word is done, advance */ | 9052 | /* Current word is done, advance */ |
9104 | p = *optnext; | 9053 | p = *optnext; |
9105 | if (p == NULL || *p != '-' || *++p == '\0') { | 9054 | if (p == NULL || *p != '-' || *++p == '\0') { |
9106 | atend: | 9055 | atend: |
9107 | p = NULL; | 9056 | p = NULL; |
9108 | done = 1; | 9057 | done = 1; |
9109 | goto out; | 9058 | goto out; |
@@ -9152,8 +9101,7 @@ atend: | |||
9152 | p = NULL; | 9101 | p = NULL; |
9153 | } else | 9102 | } else |
9154 | err |= setvarsafe("OPTARG", nullstr, 0); | 9103 | err |= setvarsafe("OPTARG", nullstr, 0); |
9155 | 9104 | out: | |
9156 | out: | ||
9157 | *optoff = p ? p - *(optnext - 1) : -1; | 9105 | *optoff = p ? p - *(optnext - 1) : -1; |
9158 | *param_optind = optnext - optfirst + 1; | 9106 | *param_optind = optnext - optfirst + 1; |
9159 | fmtstr(s, sizeof(s), "%d", *param_optind); | 9107 | fmtstr(s, sizeof(s), "%d", *param_optind); |
@@ -9170,14 +9118,14 @@ out: | |||
9170 | return done; | 9118 | return done; |
9171 | } | 9119 | } |
9172 | 9120 | ||
9121 | |||
9173 | /* | 9122 | /* |
9174 | * The getopts builtin. Shellparam.optnext points to the next argument | 9123 | * The getopts builtin. Shellparam.optnext points to the next argument |
9175 | * to be processed. Shellparam.optptr points to the next character to | 9124 | * to be processed. Shellparam.optptr points to the next character to |
9176 | * be processed in the current argument. If shellparam.optnext is NULL, | 9125 | * be processed in the current argument. If shellparam.optnext is NULL, |
9177 | * then it's the first time getopts has been called. | 9126 | * then it's the first time getopts has been called. |
9178 | */ | 9127 | */ |
9179 | 9128 | static int | |
9180 | int | ||
9181 | getoptscmd(int argc, char **argv) | 9129 | getoptscmd(int argc, char **argv) |
9182 | { | 9130 | { |
9183 | char **optbase; | 9131 | char **optbase; |
@@ -9190,8 +9138,7 @@ getoptscmd(int argc, char **argv) | |||
9190 | shellparam.optind = 1; | 9138 | shellparam.optind = 1; |
9191 | shellparam.optoff = -1; | 9139 | shellparam.optoff = -1; |
9192 | } | 9140 | } |
9193 | } | 9141 | } else { |
9194 | else { | ||
9195 | optbase = &argv[3]; | 9142 | optbase = &argv[3]; |
9196 | if (shellparam.optind > argc - 2) { | 9143 | if (shellparam.optind > argc - 2) { |
9197 | shellparam.optind = 1; | 9144 | shellparam.optind = 1; |
@@ -9214,7 +9161,6 @@ getoptscmd(int argc, char **argv) | |||
9214 | * other arguments are unnecessary. It return the character, or '\0' on | 9161 | * other arguments are unnecessary. It return the character, or '\0' on |
9215 | * end of input. | 9162 | * end of input. |
9216 | */ | 9163 | */ |
9217 | |||
9218 | static int | 9164 | static int |
9219 | nextopt(const char *optstring) | 9165 | nextopt(const char *optstring) |
9220 | { | 9166 | { |
@@ -9222,7 +9168,8 @@ nextopt(const char *optstring) | |||
9222 | const char *q; | 9168 | const char *q; |
9223 | char c; | 9169 | char c; |
9224 | 9170 | ||
9225 | if ((p = optptr) == NULL || *p == '\0') { | 9171 | p = optptr; |
9172 | if (p == NULL || *p == '\0') { | ||
9226 | p = *argptr; | 9173 | p = *argptr; |
9227 | if (p == NULL || *p != '-' || *++p == '\0') | 9174 | if (p == NULL || *p != '-' || *++p == '\0') |
9228 | return '\0'; | 9175 | return '\0'; |
@@ -9250,7 +9197,7 @@ nextopt(const char *optstring) | |||
9250 | 9197 | ||
9251 | /* output.c */ | 9198 | /* output.c */ |
9252 | 9199 | ||
9253 | void | 9200 | static void |
9254 | outstr(const char *p, FILE *file) | 9201 | outstr(const char *p, FILE *file) |
9255 | { | 9202 | { |
9256 | INTOFF; | 9203 | INTOFF; |
@@ -9258,7 +9205,7 @@ outstr(const char *p, FILE *file) | |||
9258 | INTON; | 9205 | INTON; |
9259 | } | 9206 | } |
9260 | 9207 | ||
9261 | void | 9208 | static void |
9262 | flushall(void) | 9209 | flushall(void) |
9263 | { | 9210 | { |
9264 | INTOFF; | 9211 | INTOFF; |
@@ -9267,7 +9214,7 @@ flushall(void) | |||
9267 | INTON; | 9214 | INTON; |
9268 | } | 9215 | } |
9269 | 9216 | ||
9270 | void | 9217 | static void |
9271 | flusherr(void) | 9218 | flusherr(void) |
9272 | { | 9219 | { |
9273 | INTOFF; | 9220 | INTOFF; |
@@ -9300,7 +9247,7 @@ out1fmt(const char *fmt, ...) | |||
9300 | } | 9247 | } |
9301 | 9248 | ||
9302 | 9249 | ||
9303 | int | 9250 | static int |
9304 | fmtstr(char *outbuf, size_t length, const char *fmt, ...) | 9251 | fmtstr(char *outbuf, size_t length, const char *fmt, ...) |
9305 | { | 9252 | { |
9306 | va_list ap; | 9253 | va_list ap; |
@@ -9359,7 +9306,6 @@ static void setprompt(int); | |||
9359 | * Read and parse a command. Returns NEOF on end of file. (NULL is a | 9306 | * Read and parse a command. Returns NEOF on end of file. (NULL is a |
9360 | * valid parse tree indicating a blank line.) | 9307 | * valid parse tree indicating a blank line.) |
9361 | */ | 9308 | */ |
9362 | |||
9363 | union node * | 9309 | union node * |
9364 | parsecmd(int interact) | 9310 | parsecmd(int interact) |
9365 | { | 9311 | { |
@@ -9408,8 +9354,7 @@ list(int nlflag) | |||
9408 | } | 9354 | } |
9409 | if (n1 == NULL) { | 9355 | if (n1 == NULL) { |
9410 | n1 = n2; | 9356 | n1 = n2; |
9411 | } | 9357 | } else { |
9412 | else { | ||
9413 | n3 = (union node *)stalloc(sizeof(struct nbinary)); | 9358 | n3 = (union node *)stalloc(sizeof(struct nbinary)); |
9414 | n3->type = NSEMI; | 9359 | n3->type = NSEMI; |
9415 | n3->nbinary.ch1 = n1; | 9360 | n3->nbinary.ch1 = n1; |
@@ -9457,7 +9402,8 @@ andor(void) | |||
9457 | 9402 | ||
9458 | n1 = pipeline(); | 9403 | n1 = pipeline(); |
9459 | for (;;) { | 9404 | for (;;) { |
9460 | if ((t = readtoken()) == TAND) { | 9405 | t = readtoken(); |
9406 | if (t == TAND) { | ||
9461 | t = NAND; | 9407 | t = NAND; |
9462 | } else if (t == TOR) { | 9408 | } else if (t == TOR) { |
9463 | t = NOR; | 9409 | t = NOR; |
@@ -9633,7 +9579,7 @@ command(void) | |||
9633 | if (lasttoken != TIN) | 9579 | if (lasttoken != TIN) |
9634 | synexpect(TIN); | 9580 | synexpect(TIN); |
9635 | cpp = &n1->ncase.cases; | 9581 | cpp = &n1->ncase.cases; |
9636 | next_case: | 9582 | next_case: |
9637 | checkkwd = CHKNL | CHKKWD; | 9583 | checkkwd = CHKNL | CHKKWD; |
9638 | t = readtoken(); | 9584 | t = readtoken(); |
9639 | while (t != TESAC) { | 9585 | while (t != TESAC) { |
@@ -9660,7 +9606,8 @@ next_case: | |||
9660 | cpp = &cp->nclist.next; | 9606 | cpp = &cp->nclist.next; |
9661 | 9607 | ||
9662 | checkkwd = CHKNL | CHKKWD; | 9608 | checkkwd = CHKNL | CHKKWD; |
9663 | if ((t = readtoken()) != TESAC) { | 9609 | t = readtoken(); |
9610 | if (t != TESAC) { | ||
9664 | if (t != TENDCASE) | 9611 | if (t != TENDCASE) |
9665 | synexpect(TENDCASE); | 9612 | synexpect(TENDCASE); |
9666 | else | 9613 | else |
@@ -9689,7 +9636,7 @@ next_case: | |||
9689 | if (readtoken() != t) | 9636 | if (readtoken() != t) |
9690 | synexpect(t); | 9637 | synexpect(t); |
9691 | 9638 | ||
9692 | redir: | 9639 | redir: |
9693 | /* Now check for redirection which may follow command */ | 9640 | /* Now check for redirection which may follow command */ |
9694 | checkkwd = CHKKWD | CHKALIAS; | 9641 | checkkwd = CHKKWD | CHKALIAS; |
9695 | rpp = rpp2; | 9642 | rpp = rpp2; |
@@ -9709,7 +9656,6 @@ redir: | |||
9709 | } | 9656 | } |
9710 | n1->nredir.redirect = redir; | 9657 | n1->nredir.redirect = redir; |
9711 | } | 9658 | } |
9712 | |||
9713 | return n1; | 9659 | return n1; |
9714 | } | 9660 | } |
9715 | 9661 | ||
@@ -9782,7 +9728,7 @@ simplecmd(void) { | |||
9782 | goto out; | 9728 | goto out; |
9783 | } | 9729 | } |
9784 | } | 9730 | } |
9785 | out: | 9731 | out: |
9786 | *app = NULL; | 9732 | *app = NULL; |
9787 | *vpp = NULL; | 9733 | *vpp = NULL; |
9788 | *rpp = NULL; | 9734 | *rpp = NULL; |
@@ -9807,7 +9753,7 @@ makename(void) | |||
9807 | return n; | 9753 | return n; |
9808 | } | 9754 | } |
9809 | 9755 | ||
9810 | void fixredir(union node *n, const char *text, int err) | 9756 | static void fixredir(union node *n, const char *text, int err) |
9811 | { | 9757 | { |
9812 | TRACE(("Fix redir %s %d\n", text, err)); | 9758 | TRACE(("Fix redir %s %d\n", text, err)); |
9813 | if (!err) | 9759 | if (!err) |
@@ -9842,7 +9788,7 @@ parsefname(void) | |||
9842 | if (quoteflag == 0) | 9788 | if (quoteflag == 0) |
9843 | n->type = NXHERE; | 9789 | n->type = NXHERE; |
9844 | TRACE(("Here document %d\n", n->type)); | 9790 | TRACE(("Here document %d\n", n->type)); |
9845 | if (! noexpand(wordtext) || (i = strlen(wordtext)) == 0 || i > EOFMARKLEN) | 9791 | if (!noexpand(wordtext) || (i = strlen(wordtext)) == 0 || i > EOFMARKLEN) |
9846 | synerror("Illegal eof marker for << redirection"); | 9792 | synerror("Illegal eof marker for << redirection"); |
9847 | rmescapes(wordtext); | 9793 | rmescapes(wordtext); |
9848 | here->eofmark = wordtext; | 9794 | here->eofmark = wordtext; |
@@ -9850,7 +9796,7 @@ parsefname(void) | |||
9850 | if (heredoclist == NULL) | 9796 | if (heredoclist == NULL) |
9851 | heredoclist = here; | 9797 | heredoclist = here; |
9852 | else { | 9798 | else { |
9853 | for (p = heredoclist ; p->next ; p = p->next); | 9799 | for (p = heredoclist; p->next; p = p->next); |
9854 | p->next = here; | 9800 | p->next = here; |
9855 | } | 9801 | } |
9856 | } else if (n->type == NTOFD || n->type == NFROMFD) { | 9802 | } else if (n->type == NTOFD || n->type == NFROMFD) { |
@@ -9864,7 +9810,6 @@ parsefname(void) | |||
9864 | /* | 9810 | /* |
9865 | * Input any here documents. | 9811 | * Input any here documents. |
9866 | */ | 9812 | */ |
9867 | |||
9868 | static void | 9813 | static void |
9869 | parseheredoc(void) | 9814 | parseheredoc(void) |
9870 | { | 9815 | { |
@@ -9908,7 +9853,7 @@ readtoken(void) | |||
9908 | #endif | 9853 | #endif |
9909 | 9854 | ||
9910 | #if ENABLE_ASH_ALIAS | 9855 | #if ENABLE_ASH_ALIAS |
9911 | top: | 9856 | top: |
9912 | #endif | 9857 | #endif |
9913 | 9858 | ||
9914 | t = xxreadtoken(); | 9859 | t = xxreadtoken(); |
@@ -9933,7 +9878,8 @@ top: | |||
9933 | if (checkkwd & CHKKWD) { | 9878 | if (checkkwd & CHKKWD) { |
9934 | const char *const *pp; | 9879 | const char *const *pp; |
9935 | 9880 | ||
9936 | if ((pp = findkwd(wordtext))) { | 9881 | pp = findkwd(wordtext); |
9882 | if (pp) { | ||
9937 | lasttoken = t = pp - tokname_array; | 9883 | lasttoken = t = pp - tokname_array; |
9938 | TRACE(("keyword %s recognized\n", tokname(t))); | 9884 | TRACE(("keyword %s recognized\n", tokname(t))); |
9939 | goto out; | 9885 | goto out; |
@@ -9943,7 +9889,8 @@ top: | |||
9943 | if (checkkwd & CHKALIAS) { | 9889 | if (checkkwd & CHKALIAS) { |
9944 | #if ENABLE_ASH_ALIAS | 9890 | #if ENABLE_ASH_ALIAS |
9945 | struct alias *ap; | 9891 | struct alias *ap; |
9946 | if ((ap = lookupalias(wordtext, 1)) != NULL) { | 9892 | ap = lookupalias(wordtext, 1); |
9893 | if (ap != NULL) { | ||
9947 | if (*ap->val) { | 9894 | if (*ap->val) { |
9948 | pushstring(ap->val, ap); | 9895 | pushstring(ap->val, ap); |
9949 | } | 9896 | } |
@@ -9951,7 +9898,7 @@ top: | |||
9951 | } | 9898 | } |
9952 | #endif | 9899 | #endif |
9953 | } | 9900 | } |
9954 | out: | 9901 | out: |
9955 | checkkwd = 0; | 9902 | checkkwd = 0; |
9956 | #if DEBUG | 9903 | #if DEBUG |
9957 | if (!alreadyseen) | 9904 | if (!alreadyseen) |
@@ -10054,11 +10001,10 @@ static int xxreadtoken(void) | |||
10054 | } | 10001 | } |
10055 | } | 10002 | } |
10056 | } | 10003 | } |
10057 | |||
10058 | return lasttoken = xxreadtoken_tokens[p - xxreadtoken_chars]; | 10004 | return lasttoken = xxreadtoken_tokens[p - xxreadtoken_chars]; |
10059 | } | 10005 | } |
10060 | } | 10006 | } |
10061 | } | 10007 | } /* for */ |
10062 | } | 10008 | } |
10063 | 10009 | ||
10064 | 10010 | ||
@@ -10128,7 +10074,7 @@ xxreadtoken(void) | |||
10128 | goto breakloop; | 10074 | goto breakloop; |
10129 | } | 10075 | } |
10130 | } | 10076 | } |
10131 | breakloop: | 10077 | breakloop: |
10132 | return readtoken1(c, BASESYNTAX, (char *)NULL, 0); | 10078 | return readtoken1(c, BASESYNTAX, (char *)NULL, 0); |
10133 | #undef RETURN | 10079 | #undef RETURN |
10134 | } | 10080 | } |
@@ -10372,7 +10318,6 @@ readtoken1(int firstc, int syntax, char *eofmark, int striptabs) | |||
10372 | * is called, c is set to the first character of the next input line. If | 10318 | * is called, c is set to the first character of the next input line. If |
10373 | * we are at the end of the here document, this routine sets the c to PEOF. | 10319 | * we are at the end of the here document, this routine sets the c to PEOF. |
10374 | */ | 10320 | */ |
10375 | |||
10376 | checkend: { | 10321 | checkend: { |
10377 | if (eofmark) { | 10322 | if (eofmark) { |
10378 | #if ENABLE_ASH_ALIAS | 10323 | #if ENABLE_ASH_ALIAS |
@@ -10410,7 +10355,6 @@ checkend: { | |||
10410 | * specifying the fd to be redirected. The variable "c" contains the | 10355 | * specifying the fd to be redirected. The variable "c" contains the |
10411 | * first character of the redirection operator. | 10356 | * first character of the redirection operator. |
10412 | */ | 10357 | */ |
10413 | |||
10414 | parseredir: { | 10358 | parseredir: { |
10415 | char fd = *out; | 10359 | char fd = *out; |
10416 | union node *np; | 10360 | union node *np; |
@@ -10431,7 +10375,8 @@ parseredir: { | |||
10431 | } | 10375 | } |
10432 | } else { /* c == '<' */ | 10376 | } else { /* c == '<' */ |
10433 | np->nfile.fd = 0; | 10377 | np->nfile.fd = 0; |
10434 | switch (c = pgetc()) { | 10378 | c = pgetc(); |
10379 | switch (c) { | ||
10435 | case '<': | 10380 | case '<': |
10436 | if (sizeof(struct nfile) != sizeof(struct nhere)) { | 10381 | if (sizeof(struct nfile) != sizeof(struct nhere)) { |
10437 | np = (union node *)stalloc(sizeof(struct nhere)); | 10382 | np = (union node *)stalloc(sizeof(struct nhere)); |
@@ -10440,7 +10385,8 @@ parseredir: { | |||
10440 | np->type = NHERE; | 10385 | np->type = NHERE; |
10441 | heredoc = (struct heredoc *)stalloc(sizeof(struct heredoc)); | 10386 | heredoc = (struct heredoc *)stalloc(sizeof(struct heredoc)); |
10442 | heredoc->here = np; | 10387 | heredoc->here = np; |
10443 | if ((c = pgetc()) == '-') { | 10388 | c = pgetc(); |
10389 | if (c == '-') { | ||
10444 | heredoc->striptabs = 1; | 10390 | heredoc->striptabs = 1; |
10445 | } else { | 10391 | } else { |
10446 | heredoc->striptabs = 0; | 10392 | heredoc->striptabs = 0; |
@@ -10473,7 +10419,6 @@ parseredir: { | |||
10473 | * Parse a substitution. At this point, we have read the dollar sign | 10419 | * Parse a substitution. At this point, we have read the dollar sign |
10474 | * and nothing else. | 10420 | * and nothing else. |
10475 | */ | 10421 | */ |
10476 | |||
10477 | parsesub: { | 10422 | parsesub: { |
10478 | int subtype; | 10423 | int subtype; |
10479 | int typeloc; | 10424 | int typeloc; |
@@ -10507,12 +10452,12 @@ parsesub: { | |||
10507 | if (c == '{') { | 10452 | if (c == '{') { |
10508 | c = pgetc(); | 10453 | c = pgetc(); |
10509 | if (c == '#') { | 10454 | if (c == '#') { |
10510 | if ((c = pgetc()) == '}') | 10455 | c = pgetc(); |
10456 | if (c == '}') | ||
10511 | c = '#'; | 10457 | c = '#'; |
10512 | else | 10458 | else |
10513 | subtype = VSLENGTH; | 10459 | subtype = VSLENGTH; |
10514 | } | 10460 | } else |
10515 | else | ||
10516 | subtype = 0; | 10461 | subtype = 0; |
10517 | } | 10462 | } |
10518 | if (c > PEOA_OR_PEOF && is_name(c)) { | 10463 | if (c > PEOA_OR_PEOF && is_name(c)) { |
@@ -10582,7 +10527,6 @@ parsesub: { | |||
10582 | * list of commands (passed by reference), and savelen is the number of | 10527 | * list of commands (passed by reference), and savelen is the number of |
10583 | * characters on the top of the stack which must be preserved. | 10528 | * characters on the top of the stack which must be preserved. |
10584 | */ | 10529 | */ |
10585 | |||
10586 | parsebackq: { | 10530 | parsebackq: { |
10587 | struct nodelist **nlpp; | 10531 | struct nodelist **nlpp; |
10588 | int savepbq; | 10532 | int savepbq; |
@@ -10629,12 +10573,14 @@ parsebackq: { | |||
10629 | if (needprompt) { | 10573 | if (needprompt) { |
10630 | setprompt(2); | 10574 | setprompt(2); |
10631 | } | 10575 | } |
10632 | switch (pc = pgetc()) { | 10576 | pc = pgetc(); |
10577 | switch (pc) { | ||
10633 | case '`': | 10578 | case '`': |
10634 | goto done; | 10579 | goto done; |
10635 | 10580 | ||
10636 | case '\\': | 10581 | case '\\': |
10637 | if ((pc = pgetc()) == '\n') { | 10582 | pc = pgetc(); |
10583 | if (pc == '\n') { | ||
10638 | plinno++; | 10584 | plinno++; |
10639 | if (doprompt) | 10585 | if (doprompt) |
10640 | setprompt(2); | 10586 | setprompt(2); |
@@ -10671,7 +10617,7 @@ parsebackq: { | |||
10671 | } | 10617 | } |
10672 | STPUTC(pc, pout); | 10618 | STPUTC(pc, pout); |
10673 | } | 10619 | } |
10674 | done: | 10620 | done: |
10675 | STPUTC('\0', pout); | 10621 | STPUTC('\0', pout); |
10676 | psavelen = pout - (char *)stackblock(); | 10622 | psavelen = pout - (char *)stackblock(); |
10677 | if (psavelen > 0) { | 10623 | if (psavelen > 0) { |
@@ -10763,7 +10709,6 @@ parsearith: { | |||
10763 | * Returns true if the text contains nothing to expand (no dollar signs | 10709 | * Returns true if the text contains nothing to expand (no dollar signs |
10764 | * or backquotes). | 10710 | * or backquotes). |
10765 | */ | 10711 | */ |
10766 | |||
10767 | static int | 10712 | static int |
10768 | noexpand(char *text) | 10713 | noexpand(char *text) |
10769 | { | 10714 | { |
@@ -10787,7 +10732,6 @@ noexpand(char *text) | |||
10787 | * Return of a legal variable name (a letter or underscore followed by zero or | 10732 | * Return of a legal variable name (a letter or underscore followed by zero or |
10788 | * more letters, underscores, and digits). | 10733 | * more letters, underscores, and digits). |
10789 | */ | 10734 | */ |
10790 | |||
10791 | static char * | 10735 | static char * |
10792 | endofname(const char *name) | 10736 | endofname(const char *name) |
10793 | { | 10737 | { |
@@ -10809,7 +10753,6 @@ endofname(const char *name) | |||
10809 | * is the token that is expected, or -1 if more than one type of token can | 10753 | * is the token that is expected, or -1 if more than one type of token can |
10810 | * occur at this point. | 10754 | * occur at this point. |
10811 | */ | 10755 | */ |
10812 | |||
10813 | static void synexpect(int token) | 10756 | static void synexpect(int token) |
10814 | { | 10757 | { |
10815 | char msg[64]; | 10758 | char msg[64]; |
@@ -10834,7 +10777,6 @@ synerror(const char *msg) | |||
10834 | * called by editline -- any expansions to the prompt | 10777 | * called by editline -- any expansions to the prompt |
10835 | * should be added here. | 10778 | * should be added here. |
10836 | */ | 10779 | */ |
10837 | |||
10838 | #if ENABLE_ASH_EXPAND_PRMT | 10780 | #if ENABLE_ASH_EXPAND_PRMT |
10839 | static const char * | 10781 | static const char * |
10840 | expandstr(const char *ps) | 10782 | expandstr(const char *ps) |
@@ -10963,12 +10905,12 @@ static int noclobberopen(const char *fname) | |||
10963 | return -1; | 10905 | return -1; |
10964 | } | 10906 | } |
10965 | 10907 | ||
10908 | |||
10966 | /* | 10909 | /* |
10967 | * Handle here documents. Normally we fork off a process to write the | 10910 | * Handle here documents. Normally we fork off a process to write the |
10968 | * data to a pipe. If the document is short, we can stuff the data in | 10911 | * data to a pipe. If the document is short, we can stuff the data in |
10969 | * the pipe without forking. | 10912 | * the pipe without forking. |
10970 | */ | 10913 | */ |
10971 | |||
10972 | static int openhere(union node *redir) | 10914 | static int openhere(union node *redir) |
10973 | { | 10915 | { |
10974 | int pip[2]; | 10916 | int pip[2]; |
@@ -10998,7 +10940,7 @@ static int openhere(union node *redir) | |||
10998 | expandhere(redir->nhere.doc, pip[1]); | 10940 | expandhere(redir->nhere.doc, pip[1]); |
10999 | _exit(0); | 10941 | _exit(0); |
11000 | } | 10942 | } |
11001 | out: | 10943 | out: |
11002 | close(pip[1]); | 10944 | close(pip[1]); |
11003 | return pip[0]; | 10945 | return pip[0]; |
11004 | } | 10946 | } |
@@ -11012,31 +10954,36 @@ openredirect(union node *redir) | |||
11012 | switch (redir->nfile.type) { | 10954 | switch (redir->nfile.type) { |
11013 | case NFROM: | 10955 | case NFROM: |
11014 | fname = redir->nfile.expfname; | 10956 | fname = redir->nfile.expfname; |
11015 | if ((f = open(fname, O_RDONLY)) < 0) | 10957 | f = open(fname, O_RDONLY); |
10958 | if (f < 0) | ||
11016 | goto eopen; | 10959 | goto eopen; |
11017 | break; | 10960 | break; |
11018 | case NFROMTO: | 10961 | case NFROMTO: |
11019 | fname = redir->nfile.expfname; | 10962 | fname = redir->nfile.expfname; |
11020 | if ((f = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0) | 10963 | f = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0666); |
10964 | if (f < 0) | ||
11021 | goto ecreate; | 10965 | goto ecreate; |
11022 | break; | 10966 | break; |
11023 | case NTO: | 10967 | case NTO: |
11024 | /* Take care of noclobber mode. */ | 10968 | /* Take care of noclobber mode. */ |
11025 | if (Cflag) { | 10969 | if (Cflag) { |
11026 | fname = redir->nfile.expfname; | 10970 | fname = redir->nfile.expfname; |
11027 | if ((f = noclobberopen(fname)) < 0) | 10971 | f = noclobberopen(fname); |
10972 | if (f < 0) | ||
11028 | goto ecreate; | 10973 | goto ecreate; |
11029 | break; | 10974 | break; |
11030 | } | 10975 | } |
11031 | /* FALLTHROUGH */ | 10976 | /* FALLTHROUGH */ |
11032 | case NCLOBBER: | 10977 | case NCLOBBER: |
11033 | fname = redir->nfile.expfname; | 10978 | fname = redir->nfile.expfname; |
11034 | if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) | 10979 | f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666); |
10980 | if (f < 0) | ||
11035 | goto ecreate; | 10981 | goto ecreate; |
11036 | break; | 10982 | break; |
11037 | case NAPPEND: | 10983 | case NAPPEND: |
11038 | fname = redir->nfile.expfname; | 10984 | fname = redir->nfile.expfname; |
11039 | if ((f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0) | 10985 | f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666); |
10986 | if (f < 0) | ||
11040 | goto ecreate; | 10987 | goto ecreate; |
11041 | break; | 10988 | break; |
11042 | default: | 10989 | default: |
@@ -11055,9 +11002,9 @@ openredirect(union node *redir) | |||
11055 | } | 11002 | } |
11056 | 11003 | ||
11057 | return f; | 11004 | return f; |
11058 | ecreate: | 11005 | ecreate: |
11059 | sh_error("cannot create %s: %s", fname, errmsg(errno, E_CREAT)); | 11006 | sh_error("cannot create %s: %s", fname, errmsg(errno, E_CREAT)); |
11060 | eopen: | 11007 | eopen: |
11061 | sh_error("cannot open %s: %s", fname, errmsg(errno, E_OPEN)); | 11008 | sh_error("cannot open %s: %s", fname, errmsg(errno, E_OPEN)); |
11062 | } | 11009 | } |
11063 | 11010 | ||
@@ -11078,6 +11025,7 @@ static void dupredirect(union node *redir, int f) | |||
11078 | } | 11025 | } |
11079 | } | 11026 | } |
11080 | 11027 | ||
11028 | |||
11081 | /* | 11029 | /* |
11082 | * Process a list of redirection commands. If the REDIR_PUSH flag is set, | 11030 | * Process a list of redirection commands. If the REDIR_PUSH flag is set, |
11083 | * old file descriptors are stashed away so that the redirection can be | 11031 | * old file descriptors are stashed away so that the redirection can be |
@@ -11085,7 +11033,6 @@ static void dupredirect(union node *redir, int f) | |||
11085 | * standard output, and the standard error if it becomes a duplicate of | 11033 | * standard output, and the standard error if it becomes a duplicate of |
11086 | * stdout, is saved in memory. | 11034 | * stdout, is saved in memory. |
11087 | */ | 11035 | */ |
11088 | |||
11089 | static void | 11036 | static void |
11090 | redirect(union node *redir, int flags) | 11037 | redirect(union node *redir, int flags) |
11091 | { | 11038 | { |
@@ -11151,8 +11098,7 @@ redirect(union node *redir, int flags) | |||
11151 | /* | 11098 | /* |
11152 | * Undo the effects of the last redirection. | 11099 | * Undo the effects of the last redirection. |
11153 | */ | 11100 | */ |
11154 | 11101 | static void | |
11155 | void | ||
11156 | popredir(int drop) | 11102 | popredir(int drop) |
11157 | { | 11103 | { |
11158 | struct redirtab *rp; | 11104 | struct redirtab *rp; |
@@ -11184,8 +11130,7 @@ popredir(int drop) | |||
11184 | /* | 11130 | /* |
11185 | * Discard all saved file descriptors. | 11131 | * Discard all saved file descriptors. |
11186 | */ | 11132 | */ |
11187 | 11133 | static void | |
11188 | void | ||
11189 | clearredir(int drop) | 11134 | clearredir(int drop) |
11190 | { | 11135 | { |
11191 | for (;;) { | 11136 | for (;;) { |
@@ -11202,8 +11147,7 @@ clearredir(int drop) | |||
11202 | * if the source file descriptor is closed, EMPTY if there are no unused | 11147 | * if the source file descriptor is closed, EMPTY if there are no unused |
11203 | * file descriptors left. | 11148 | * file descriptors left. |
11204 | */ | 11149 | */ |
11205 | 11150 | static int | |
11206 | int | ||
11207 | copyfd(int from, int to) | 11151 | copyfd(int from, int to) |
11208 | { | 11152 | { |
11209 | int newfd; | 11153 | int newfd; |
@@ -11219,7 +11163,7 @@ copyfd(int from, int to) | |||
11219 | } | 11163 | } |
11220 | 11164 | ||
11221 | 11165 | ||
11222 | int | 11166 | static int |
11223 | redirectsafe(union node *redir, int flags) | 11167 | redirectsafe(union node *redir, int flags) |
11224 | { | 11168 | { |
11225 | int err; | 11169 | int err; |
@@ -11228,7 +11172,8 @@ redirectsafe(union node *redir, int flags) | |||
11228 | struct jmploc jmploc; | 11172 | struct jmploc jmploc; |
11229 | 11173 | ||
11230 | SAVEINT(saveint); | 11174 | SAVEINT(saveint); |
11231 | if (!(err = setjmp(jmploc.loc) * 2)) { | 11175 | err = setjmp(jmploc.loc) * 2; |
11176 | if (!err) { | ||
11232 | handler = &jmploc; | 11177 | handler = &jmploc; |
11233 | redirect(redir, flags); | 11178 | redirect(redir, flags); |
11234 | } | 11179 | } |
@@ -11249,7 +11194,7 @@ static void indent(int, char *, FILE *); | |||
11249 | static void trstring(char *); | 11194 | static void trstring(char *); |
11250 | 11195 | ||
11251 | 11196 | ||
11252 | void | 11197 | static void |
11253 | showtree(union node *n) | 11198 | showtree(union node *n) |
11254 | { | 11199 | { |
11255 | trputs("showtree called\n"); | 11200 | trputs("showtree called\n"); |
@@ -11276,7 +11221,7 @@ shtree(union node *n, int ind, char *pfx, FILE *fp) | |||
11276 | goto binop; | 11221 | goto binop; |
11277 | case NOR: | 11222 | case NOR: |
11278 | s = " || "; | 11223 | s = " || "; |
11279 | binop: | 11224 | binop: |
11280 | shtree(n->nbinary.ch1, ind, NULL, fp); | 11225 | shtree(n->nbinary.ch1, ind, NULL, fp); |
11281 | /* if (ind < 0) */ | 11226 | /* if (ind < 0) */ |
11282 | fputs(s, fp); | 11227 | fputs(s, fp); |
@@ -11450,10 +11395,10 @@ indent(int amount, char *pfx, FILE *fp) | |||
11450 | */ | 11395 | */ |
11451 | 11396 | ||
11452 | 11397 | ||
11453 | FILE *tracefile; | 11398 | static FILE *tracefile; |
11454 | 11399 | ||
11455 | 11400 | ||
11456 | void | 11401 | static void |
11457 | trputc(int c) | 11402 | trputc(int c) |
11458 | { | 11403 | { |
11459 | if (debug != 1) | 11404 | if (debug != 1) |
@@ -11461,7 +11406,7 @@ trputc(int c) | |||
11461 | putc(c, tracefile); | 11406 | putc(c, tracefile); |
11462 | } | 11407 | } |
11463 | 11408 | ||
11464 | void | 11409 | static void |
11465 | trace(const char *fmt, ...) | 11410 | trace(const char *fmt, ...) |
11466 | { | 11411 | { |
11467 | va_list va; | 11412 | va_list va; |
@@ -11473,7 +11418,7 @@ trace(const char *fmt, ...) | |||
11473 | va_end(va); | 11418 | va_end(va); |
11474 | } | 11419 | } |
11475 | 11420 | ||
11476 | void | 11421 | static void |
11477 | tracev(const char *fmt, va_list va) | 11422 | tracev(const char *fmt, va_list va) |
11478 | { | 11423 | { |
11479 | if (debug != 1) | 11424 | if (debug != 1) |
@@ -11482,7 +11427,7 @@ tracev(const char *fmt, va_list va) | |||
11482 | } | 11427 | } |
11483 | 11428 | ||
11484 | 11429 | ||
11485 | void | 11430 | static void |
11486 | trputs(const char *s) | 11431 | trputs(const char *s) |
11487 | { | 11432 | { |
11488 | if (debug != 1) | 11433 | if (debug != 1) |
@@ -11512,7 +11457,7 @@ trstring(char *s) | |||
11512 | case CTLVAR+CTLQUOTE: c = 'V'; goto backslash; | 11457 | case CTLVAR+CTLQUOTE: c = 'V'; goto backslash; |
11513 | case CTLBACKQ: c = 'q'; goto backslash; | 11458 | case CTLBACKQ: c = 'q'; goto backslash; |
11514 | case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash; | 11459 | case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash; |
11515 | backslash: putc('\\', tracefile); | 11460 | backslash: putc('\\', tracefile); |
11516 | putc(c, tracefile); | 11461 | putc(c, tracefile); |
11517 | break; | 11462 | break; |
11518 | default: | 11463 | default: |
@@ -11531,7 +11476,7 @@ backslash: putc('\\', tracefile); | |||
11531 | } | 11476 | } |
11532 | 11477 | ||
11533 | 11478 | ||
11534 | void | 11479 | static void |
11535 | trargs(char **ap) | 11480 | trargs(char **ap) |
11536 | { | 11481 | { |
11537 | if (debug != 1) | 11482 | if (debug != 1) |
@@ -11546,7 +11491,7 @@ trargs(char **ap) | |||
11546 | } | 11491 | } |
11547 | 11492 | ||
11548 | 11493 | ||
11549 | void | 11494 | static void |
11550 | opentrace(void) | 11495 | opentrace(void) |
11551 | { | 11496 | { |
11552 | char s[100]; | 11497 | char s[100]; |
@@ -11568,14 +11513,16 @@ opentrace(void) | |||
11568 | return; | 11513 | return; |
11569 | } | 11514 | } |
11570 | } else { | 11515 | } else { |
11571 | if ((tracefile = fopen(s, "a")) == NULL) { | 11516 | tracefile = fopen(s, "a"); |
11517 | if (tracefile == NULL) { | ||
11572 | fprintf(stderr, "Can't open %s\n", s); | 11518 | fprintf(stderr, "Can't open %s\n", s); |
11573 | debug = 0; | 11519 | debug = 0; |
11574 | return; | 11520 | return; |
11575 | } | 11521 | } |
11576 | } | 11522 | } |
11577 | #ifdef O_APPEND | 11523 | #ifdef O_APPEND |
11578 | if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0) | 11524 | flags = fcntl(fileno(tracefile), F_GETFL, 0); |
11525 | if (flags >= 0) | ||
11579 | fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND); | 11526 | fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND); |
11580 | #endif | 11527 | #endif |
11581 | setlinebuf(tracefile); | 11528 | setlinebuf(tracefile); |
@@ -11602,8 +11549,7 @@ opentrace(void) | |||
11602 | /* | 11549 | /* |
11603 | * The trap builtin. | 11550 | * The trap builtin. |
11604 | */ | 11551 | */ |
11605 | 11552 | static int | |
11606 | int | ||
11607 | trapcmd(int argc, char **argv) | 11553 | trapcmd(int argc, char **argv) |
11608 | { | 11554 | { |
11609 | char *action; | 11555 | char *action; |
@@ -11629,7 +11575,8 @@ trapcmd(int argc, char **argv) | |||
11629 | else | 11575 | else |
11630 | action = *ap++; | 11576 | action = *ap++; |
11631 | while (*ap) { | 11577 | while (*ap) { |
11632 | if ((signo = get_signum(*ap)) < 0) | 11578 | signo = get_signum(*ap); |
11579 | if (signo < 0) | ||
11633 | sh_error("%s: bad trap", *ap); | 11580 | sh_error("%s: bad trap", *ap); |
11634 | INTOFF; | 11581 | INTOFF; |
11635 | if (action) { | 11582 | if (action) { |
@@ -11653,8 +11600,7 @@ trapcmd(int argc, char **argv) | |||
11653 | /* | 11600 | /* |
11654 | * Clear traps on a fork. | 11601 | * Clear traps on a fork. |
11655 | */ | 11602 | */ |
11656 | 11603 | static void | |
11657 | void | ||
11658 | clear_traps(void) | 11604 | clear_traps(void) |
11659 | { | 11605 | { |
11660 | char **tp; | 11606 | char **tp; |
@@ -11676,15 +11622,15 @@ clear_traps(void) | |||
11676 | * Set the signal handler for the specified signal. The routine figures | 11622 | * Set the signal handler for the specified signal. The routine figures |
11677 | * out what it should be set to. | 11623 | * out what it should be set to. |
11678 | */ | 11624 | */ |
11679 | 11625 | static void | |
11680 | void | ||
11681 | setsignal(int signo) | 11626 | setsignal(int signo) |
11682 | { | 11627 | { |
11683 | int action; | 11628 | int action; |
11684 | char *t, tsig; | 11629 | char *t, tsig; |
11685 | struct sigaction act; | 11630 | struct sigaction act; |
11686 | 11631 | ||
11687 | if ((t = trap[signo]) == NULL) | 11632 | t = trap[signo]; |
11633 | if (t == NULL) | ||
11688 | action = S_DFL; | 11634 | action = S_DFL; |
11689 | else if (*t != '\0') | 11635 | else if (*t != '\0') |
11690 | action = S_CATCH; | 11636 | action = S_CATCH; |
@@ -11759,11 +11705,11 @@ setsignal(int signo) | |||
11759 | sigaction(signo, &act, 0); | 11705 | sigaction(signo, &act, 0); |
11760 | } | 11706 | } |
11761 | 11707 | ||
11708 | |||
11762 | /* | 11709 | /* |
11763 | * Ignore a signal. | 11710 | * Ignore a signal. |
11764 | */ | 11711 | */ |
11765 | 11712 | static void | |
11766 | void | ||
11767 | ignoresig(int signo) | 11713 | ignoresig(int signo) |
11768 | { | 11714 | { |
11769 | if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) { | 11715 | if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) { |
@@ -11776,8 +11722,7 @@ ignoresig(int signo) | |||
11776 | /* | 11722 | /* |
11777 | * Signal handler. | 11723 | * Signal handler. |
11778 | */ | 11724 | */ |
11779 | 11725 | static void | |
11780 | void | ||
11781 | onsig(int signo) | 11726 | onsig(int signo) |
11782 | { | 11727 | { |
11783 | gotsig[signo - 1] = 1; | 11728 | gotsig[signo - 1] = 1; |
@@ -11795,8 +11740,7 @@ onsig(int signo) | |||
11795 | * Called to execute a trap. Perhaps we should avoid entering new trap | 11740 | * Called to execute a trap. Perhaps we should avoid entering new trap |
11796 | * handlers while we are executing a trap handler. | 11741 | * handlers while we are executing a trap handler. |
11797 | */ | 11742 | */ |
11798 | 11743 | static int | |
11799 | int | ||
11800 | dotrap(void) | 11744 | dotrap(void) |
11801 | { | 11745 | { |
11802 | char *p; | 11746 | char *p; |
@@ -11830,8 +11774,7 @@ dotrap(void) | |||
11830 | /* | 11774 | /* |
11831 | * Controls whether the shell is interactive or not. | 11775 | * Controls whether the shell is interactive or not. |
11832 | */ | 11776 | */ |
11833 | 11777 | static void | |
11834 | void | ||
11835 | setinteractive(int on) | 11778 | setinteractive(int on) |
11836 | { | 11779 | { |
11837 | static int is_interactive; | 11780 | static int is_interactive; |
@@ -11889,11 +11832,11 @@ static int helpcmd(int argc, char **argv) | |||
11889 | } | 11832 | } |
11890 | #endif /* FEATURE_SH_EXTRA_QUIET */ | 11833 | #endif /* FEATURE_SH_EXTRA_QUIET */ |
11891 | 11834 | ||
11835 | |||
11892 | /* | 11836 | /* |
11893 | * Called to exit the shell. | 11837 | * Called to exit the shell. |
11894 | */ | 11838 | */ |
11895 | 11839 | static void | |
11896 | void | ||
11897 | exitshell(void) | 11840 | exitshell(void) |
11898 | { | 11841 | { |
11899 | struct jmploc loc; | 11842 | struct jmploc loc; |
@@ -11912,12 +11855,13 @@ exitshell(void) | |||
11912 | goto out; | 11855 | goto out; |
11913 | } | 11856 | } |
11914 | handler = &loc; | 11857 | handler = &loc; |
11915 | if ((p = trap[0])) { | 11858 | p = trap[0]; |
11859 | if (p) { | ||
11916 | trap[0] = NULL; | 11860 | trap[0] = NULL; |
11917 | evalstring(p, 0); | 11861 | evalstring(p, 0); |
11918 | } | 11862 | } |
11919 | flushall(); | 11863 | flushall(); |
11920 | out: | 11864 | out: |
11921 | setjobctl(0); | 11865 | setjobctl(0); |
11922 | _exit(status); | 11866 | _exit(status); |
11923 | /* NOTREACHED */ | 11867 | /* NOTREACHED */ |
@@ -11939,8 +11883,7 @@ static struct var **findvar(struct var **, const char *); | |||
11939 | /* | 11883 | /* |
11940 | * Safe version of setvar, returns 1 on success 0 on failure. | 11884 | * Safe version of setvar, returns 1 on success 0 on failure. |
11941 | */ | 11885 | */ |
11942 | 11886 | static int | |
11943 | int | ||
11944 | setvarsafe(const char *name, const char *val, int flags) | 11887 | setvarsafe(const char *name, const char *val, int flags) |
11945 | { | 11888 | { |
11946 | int err; | 11889 | int err; |
@@ -11962,11 +11905,11 @@ setvarsafe(const char *name, const char *val, int flags) | |||
11962 | } | 11905 | } |
11963 | #endif | 11906 | #endif |
11964 | 11907 | ||
11908 | |||
11965 | /* | 11909 | /* |
11966 | * Set the value of a variable. The flags argument is ored with the | 11910 | * Set the value of a variable. The flags argument is ored with the |
11967 | * flags of the variable. If val is NULL, the variable is unset. | 11911 | * flags of the variable. If val is NULL, the variable is unset. |
11968 | */ | 11912 | */ |
11969 | |||
11970 | static void | 11913 | static void |
11971 | setvar(const char *name, const char *val, int flags) | 11914 | setvar(const char *name, const char *val, int flags) |
11972 | { | 11915 | { |
@@ -12006,8 +11949,7 @@ setvar(const char *name, const char *val, int flags) | |||
12006 | * will go away. | 11949 | * will go away. |
12007 | * Called with interrupts off. | 11950 | * Called with interrupts off. |
12008 | */ | 11951 | */ |
12009 | 11952 | static void | |
12010 | void | ||
12011 | setvareq(char *s, int flags) | 11953 | setvareq(char *s, int flags) |
12012 | { | 11954 | { |
12013 | struct var *vp, **vpp; | 11955 | struct var *vp, **vpp; |
@@ -12054,7 +11996,6 @@ setvareq(char *s, int flags) | |||
12054 | /* | 11996 | /* |
12055 | * Process a linked list of variable assignments. | 11997 | * Process a linked list of variable assignments. |
12056 | */ | 11998 | */ |
12057 | |||
12058 | static void | 11999 | static void |
12059 | listsetvar(struct strlist *list_set_var, int flags) | 12000 | listsetvar(struct strlist *list_set_var, int flags) |
12060 | { | 12001 | { |
@@ -12073,13 +12014,13 @@ listsetvar(struct strlist *list_set_var, int flags) | |||
12073 | /* | 12014 | /* |
12074 | * Find the value of a variable. Returns NULL if not set. | 12015 | * Find the value of a variable. Returns NULL if not set. |
12075 | */ | 12016 | */ |
12076 | |||
12077 | static char * | 12017 | static char * |
12078 | lookupvar(const char *name) | 12018 | lookupvar(const char *name) |
12079 | { | 12019 | { |
12080 | struct var *v; | 12020 | struct var *v; |
12081 | 12021 | ||
12082 | if ((v = *findvar(hashvar(name), name))) { | 12022 | v = *findvar(hashvar(name), name); |
12023 | if (v) { | ||
12083 | #ifdef DYNAMIC_VAR | 12024 | #ifdef DYNAMIC_VAR |
12084 | /* | 12025 | /* |
12085 | * Dynamic variables are implemented roughly the same way they are | 12026 | * Dynamic variables are implemented roughly the same way they are |
@@ -12101,7 +12042,6 @@ lookupvar(const char *name) | |||
12101 | /* | 12042 | /* |
12102 | * Search the environment of a builtin command. | 12043 | * Search the environment of a builtin command. |
12103 | */ | 12044 | */ |
12104 | |||
12105 | static char * | 12045 | static char * |
12106 | bltinlookup(const char *name) | 12046 | bltinlookup(const char *name) |
12107 | { | 12047 | { |
@@ -12118,7 +12058,6 @@ bltinlookup(const char *name) | |||
12118 | /* | 12058 | /* |
12119 | * Generate a list of variables satisfying the given conditions. | 12059 | * Generate a list of variables satisfying the given conditions. |
12120 | */ | 12060 | */ |
12121 | |||
12122 | static char ** | 12061 | static char ** |
12123 | listvars(int on, int off, char ***end) | 12062 | listvars(int on, int off, char ***end) |
12124 | { | 12063 | { |
@@ -12154,7 +12093,6 @@ listvars(int on, int off, char ***end) | |||
12154 | * instead of hashed lists. | 12093 | * instead of hashed lists. |
12155 | * For now just roll 'em through qsort for printing... | 12094 | * For now just roll 'em through qsort for printing... |
12156 | */ | 12095 | */ |
12157 | |||
12158 | static int | 12096 | static int |
12159 | showvars(const char *sep_prefix, int on, int off) | 12097 | showvars(const char *sep_prefix, int on, int off) |
12160 | { | 12098 | { |
@@ -12185,7 +12123,6 @@ showvars(const char *sep_prefix, int on, int off) | |||
12185 | /* | 12123 | /* |
12186 | * The export and readonly commands. | 12124 | * The export and readonly commands. |
12187 | */ | 12125 | */ |
12188 | |||
12189 | static int | 12126 | static int |
12190 | exportcmd(int argc, char **argv) | 12127 | exportcmd(int argc, char **argv) |
12191 | { | 12128 | { |
@@ -12199,10 +12136,12 @@ exportcmd(int argc, char **argv) | |||
12199 | notp = nextopt("p") - 'p'; | 12136 | notp = nextopt("p") - 'p'; |
12200 | if (notp && ((name = *(aptr = argptr)))) { | 12137 | if (notp && ((name = *(aptr = argptr)))) { |
12201 | do { | 12138 | do { |
12202 | if ((p = strchr(name, '=')) != NULL) { | 12139 | p = strchr(name, '='); |
12140 | if (p != NULL) { | ||
12203 | p++; | 12141 | p++; |
12204 | } else { | 12142 | } else { |
12205 | if ((vp = *findvar(hashvar(name), name))) { | 12143 | vp = *findvar(hashvar(name), name); |
12144 | if (vp) { | ||
12206 | vp->flags |= flag; | 12145 | vp->flags |= flag; |
12207 | continue; | 12146 | continue; |
12208 | } | 12147 | } |
@@ -12222,7 +12161,6 @@ exportcmd(int argc, char **argv) | |||
12222 | * will be restored when the shell function returns. We handle the name | 12161 | * will be restored when the shell function returns. We handle the name |
12223 | * "-" as a special case. | 12162 | * "-" as a special case. |
12224 | */ | 12163 | */ |
12225 | |||
12226 | static void mklocal(char *name) | 12164 | static void mklocal(char *name) |
12227 | { | 12165 | { |
12228 | struct localvar *lvp; | 12166 | struct localvar *lvp; |
@@ -12263,10 +12201,10 @@ static void mklocal(char *name) | |||
12263 | INTON; | 12201 | INTON; |
12264 | } | 12202 | } |
12265 | 12203 | ||
12204 | |||
12266 | /* | 12205 | /* |
12267 | * The "local" command. | 12206 | * The "local" command. |
12268 | */ | 12207 | */ |
12269 | |||
12270 | static int | 12208 | static int |
12271 | localcmd(int argc, char **argv) | 12209 | localcmd(int argc, char **argv) |
12272 | { | 12210 | { |
@@ -12284,7 +12222,6 @@ localcmd(int argc, char **argv) | |||
12284 | * Called after a function returns. | 12222 | * Called after a function returns. |
12285 | * Interrupts must be off. | 12223 | * Interrupts must be off. |
12286 | */ | 12224 | */ |
12287 | |||
12288 | static void | 12225 | static void |
12289 | poplocalvars(void) | 12226 | poplocalvars(void) |
12290 | { | 12227 | { |
@@ -12319,8 +12256,7 @@ poplocalvars(void) | |||
12319 | * variable to allow a function to be unset when there is a readonly variable | 12256 | * variable to allow a function to be unset when there is a readonly variable |
12320 | * with the same name. | 12257 | * with the same name. |
12321 | */ | 12258 | */ |
12322 | 12259 | static int | |
12323 | int | ||
12324 | unsetcmd(int argc, char **argv) | 12260 | unsetcmd(int argc, char **argv) |
12325 | { | 12261 | { |
12326 | char **ap; | 12262 | char **ap; |
@@ -12349,8 +12285,7 @@ unsetcmd(int argc, char **argv) | |||
12349 | /* | 12285 | /* |
12350 | * Unset the specified variable. | 12286 | * Unset the specified variable. |
12351 | */ | 12287 | */ |
12352 | 12288 | static int | |
12353 | int | ||
12354 | unsetvar(const char *s) | 12289 | unsetvar(const char *s) |
12355 | { | 12290 | { |
12356 | struct var **vpp; | 12291 | struct var **vpp; |
@@ -12385,8 +12320,7 @@ unsetvar(const char *s) | |||
12385 | ok: | 12320 | ok: |
12386 | retval = 0; | 12321 | retval = 0; |
12387 | } | 12322 | } |
12388 | 12323 | out: | |
12389 | out: | ||
12390 | return retval; | 12324 | return retval; |
12391 | } | 12325 | } |
12392 | 12326 | ||
@@ -12394,7 +12328,6 @@ out: | |||
12394 | /* | 12328 | /* |
12395 | * Find the appropriate entry in the hash table from the name. | 12329 | * Find the appropriate entry in the hash table from the name. |
12396 | */ | 12330 | */ |
12397 | |||
12398 | static struct var ** | 12331 | static struct var ** |
12399 | hashvar(const char *p) | 12332 | hashvar(const char *p) |
12400 | { | 12333 | { |
@@ -12412,8 +12345,7 @@ hashvar(const char *p) | |||
12412 | * string must be terminated by '='; the second may be terminated by | 12345 | * string must be terminated by '='; the second may be terminated by |
12413 | * either '=' or '\0'. | 12346 | * either '=' or '\0'. |
12414 | */ | 12347 | */ |
12415 | 12348 | static int | |
12416 | int | ||
12417 | varcmp(const char *p, const char *q) | 12349 | varcmp(const char *p, const char *q) |
12418 | { | 12350 | { |
12419 | int c, d; | 12351 | int c, d; |
@@ -12428,7 +12360,7 @@ varcmp(const char *p, const char *q) | |||
12428 | c = 0; | 12360 | c = 0; |
12429 | if (d == '=') | 12361 | if (d == '=') |
12430 | d = 0; | 12362 | d = 0; |
12431 | out: | 12363 | out: |
12432 | return c - d; | 12364 | return c - d; |
12433 | } | 12365 | } |
12434 | 12366 | ||
@@ -12513,7 +12445,6 @@ dash_arith(const char *s) | |||
12513 | * | 12445 | * |
12514 | * Copyright (C) 2003 Vladimir Oleynik <dzo@simtreas.ru> | 12446 | * Copyright (C) 2003 Vladimir Oleynik <dzo@simtreas.ru> |
12515 | */ | 12447 | */ |
12516 | |||
12517 | static int | 12448 | static int |
12518 | letcmd(int argc, char **argv) | 12449 | letcmd(int argc, char **argv) |
12519 | { | 12450 | { |
@@ -12550,7 +12481,6 @@ typedef enum __rlimit_resource rlim_t; | |||
12550 | * | 12481 | * |
12551 | * This uses unbuffered input, which may be avoidable in some cases. | 12482 | * This uses unbuffered input, which may be avoidable in some cases. |
12552 | */ | 12483 | */ |
12553 | |||
12554 | static int | 12484 | static int |
12555 | readcmd(int argc, char **argv) | 12485 | readcmd(int argc, char **argv) |
12556 | { | 12486 | { |
@@ -12639,9 +12569,11 @@ readcmd(int argc, char **argv) | |||
12639 | if (prompt && isatty(0)) { | 12569 | if (prompt && isatty(0)) { |
12640 | out2str(prompt); | 12570 | out2str(prompt); |
12641 | } | 12571 | } |
12642 | if (*(ap = argptr) == NULL) | 12572 | ap = argptr; |
12573 | if (*ap == NULL) | ||
12643 | sh_error("arg count"); | 12574 | sh_error("arg count"); |
12644 | if ((ifs = bltinlookup("IFS")) == NULL) | 12575 | ifs = bltinlookup("IFS"); |
12576 | if (ifs == NULL) | ||
12645 | ifs = defifs; | 12577 | ifs = defifs; |
12646 | #if ENABLE_ASH_READ_NCHARS | 12578 | #if ENABLE_ASH_READ_NCHARS |
12647 | if (nch_flag || silent) { | 12579 | if (nch_flag || silent) { |
@@ -12712,7 +12644,7 @@ readcmd(int argc, char **argv) | |||
12712 | startword = 1; | 12644 | startword = 1; |
12713 | STARTSTACKSTR(p); | 12645 | STARTSTACKSTR(p); |
12714 | } else { | 12646 | } else { |
12715 | put: | 12647 | put: |
12716 | STPUTC(c, p); | 12648 | STPUTC(c, p); |
12717 | } | 12649 | } |
12718 | } | 12650 | } |
@@ -12756,7 +12688,8 @@ static int umaskcmd(int argc, char **argv) | |||
12756 | umask(mask); | 12688 | umask(mask); |
12757 | INTON; | 12689 | INTON; |
12758 | 12690 | ||
12759 | if ((ap = *argptr) == NULL) { | 12691 | ap = *argptr; |
12692 | if (ap == NULL) { | ||
12760 | if (symbolic_mode) { | 12693 | if (symbolic_mode) { |
12761 | char buf[18]; | 12694 | char buf[18]; |
12762 | char *p = buf; | 12695 | char *p = buf; |
@@ -13465,7 +13398,8 @@ static arith_t arith(const char *expr, int *perrcode) | |||
13465 | *perrcode = errcode = 0; | 13398 | *perrcode = errcode = 0; |
13466 | 13399 | ||
13467 | while (1) { | 13400 | while (1) { |
13468 | if ((arithval = *expr) == 0) { | 13401 | arithval = *expr; |
13402 | if (arithval == 0) { | ||
13469 | if (p == endexpression) { | 13403 | if (p == endexpression) { |
13470 | /* Null expression. */ | 13404 | /* Null expression. */ |
13471 | return 0; | 13405 | return 0; |
@@ -13503,7 +13437,8 @@ static arith_t arith(const char *expr, int *perrcode) | |||
13503 | /* Skip whitespace */ | 13437 | /* Skip whitespace */ |
13504 | goto prologue; | 13438 | goto prologue; |
13505 | } | 13439 | } |
13506 | if ((p = endofname(expr)) != expr) { | 13440 | p = endofname(expr); |
13441 | if (p != expr) { | ||
13507 | size_t var_name_size = (p-expr) + 1; /* trailing zero */ | 13442 | size_t var_name_size = (p-expr) + 1; /* trailing zero */ |
13508 | 13443 | ||
13509 | numstackptr->var = alloca(var_name_size); | 13444 | numstackptr->var = alloca(var_name_size); |