diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-02-23 21:10:35 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-02-23 21:10:35 +0000 |
commit | cc5715184bf91fa5a6bb7d4423e6c7aed71a98ef (patch) | |
tree | 1873fdfbae8cfe040073b4277782adfc5ab17b86 | |
parent | 2de3d9fbeef02d19305a4a18c758a4e5f65260d4 (diff) | |
download | busybox-w32-cc5715184bf91fa5a6bb7d4423e6c7aed71a98ef.tar.gz busybox-w32-cc5715184bf91fa5a6bb7d4423e6c7aed71a98ef.tar.bz2 busybox-w32-cc5715184bf91fa5a6bb7d4423e6c7aed71a98ef.zip |
ash: cleanup part 2.6
-rw-r--r-- | shell/ash.c | 402 |
1 files changed, 195 insertions, 207 deletions
diff --git a/shell/ash.c b/shell/ash.c index c96517c3a..5c9060cad 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -74,7 +74,6 @@ | |||
74 | #define signed_char2int(sc) ((int)((signed char)sc)) | 74 | #define signed_char2int(sc) ((int)((signed char)sc)) |
75 | 75 | ||
76 | 76 | ||
77 | |||
78 | /* ============ Shell options */ | 77 | /* ============ Shell options */ |
79 | 78 | ||
80 | static const char *const optletters_optnames[] = { | 79 | static const char *const optletters_optnames[] = { |
@@ -139,6 +138,8 @@ static const char homestr[] = "HOME"; | |||
139 | static const char snlfmt[] = "%s\n"; | 138 | static const char snlfmt[] = "%s\n"; |
140 | static const char illnum[] = "Illegal number: %s"; | 139 | static const char illnum[] = "Illegal number: %s"; |
141 | 140 | ||
141 | static char *minusc; /* argument to -c option */ | ||
142 | |||
142 | static int isloginsh; | 143 | static int isloginsh; |
143 | /* pid of main shell */ | 144 | /* pid of main shell */ |
144 | static int rootpid; | 145 | static int rootpid; |
@@ -2464,14 +2465,6 @@ pwdcmd(int argc, char **argv) | |||
2464 | #define PEOA_OR_PEOF PEOF | 2465 | #define PEOA_OR_PEOF PEOF |
2465 | #endif | 2466 | #endif |
2466 | 2467 | ||
2467 | /* | ||
2468 | * is_special(c) evaluates to 1 for c in "!#$*-0123456789?@"; 0 otherwise | ||
2469 | * (assuming ascii char codes, as the original implementation did) | ||
2470 | */ | ||
2471 | #define is_special(c) \ | ||
2472 | ((((unsigned int)c) - 33 < 32) \ | ||
2473 | && ((0xc1ff920dUL >> (((unsigned int)c) - 33)) & 1)) | ||
2474 | |||
2475 | /* number syntax index */ | 2468 | /* number syntax index */ |
2476 | #define BASESYNTAX 0 /* not in quotes */ | 2469 | #define BASESYNTAX 0 /* not in quotes */ |
2477 | #define DQSYNTAX 1 /* in double quotes */ | 2470 | #define DQSYNTAX 1 /* in double quotes */ |
@@ -2878,15 +2871,8 @@ static const char syntax_index_table[258] = { | |||
2878 | #endif /* USE_SIT_FUNCTION */ | 2871 | #endif /* USE_SIT_FUNCTION */ |
2879 | 2872 | ||
2880 | 2873 | ||
2881 | /* main.h */ | ||
2882 | |||
2883 | static void readcmdfile(char *); | ||
2884 | |||
2885 | |||
2886 | /* options.h */ | 2874 | /* options.h */ |
2887 | 2875 | ||
2888 | static char *minusc; /* argument to -c option */ | ||
2889 | |||
2890 | static void optschanged(void); | 2876 | static void optschanged(void); |
2891 | static void setparam(char **); | 2877 | static void setparam(char **); |
2892 | static void freeparam(volatile struct shparam *); | 2878 | static void freeparam(volatile struct shparam *); |
@@ -3120,7 +3106,6 @@ unaliascmd(int argc, char **argv) | |||
3120 | #define SHOW_PID 0x04 /* include process pid */ | 3106 | #define SHOW_PID 0x04 /* include process pid */ |
3121 | #define SHOW_CHANGED 0x08 /* only jobs whose state has changed */ | 3107 | #define SHOW_CHANGED 0x08 /* only jobs whose state has changed */ |
3122 | 3108 | ||
3123 | |||
3124 | /* | 3109 | /* |
3125 | * A job structure contains information about a job. A job is either a | 3110 | * A job structure contains information about a job. A job is either a |
3126 | * single process or a set of processes contained in a pipeline. In the | 3111 | * single process or a set of processes contained in a pipeline. In the |
@@ -7823,190 +7808,6 @@ find_builtin(const char *name) | |||
7823 | } | 7808 | } |
7824 | 7809 | ||
7825 | /* | 7810 | /* |
7826 | * Resolve a command name. If you change this routine, you may have to | ||
7827 | * change the shellexec routine as well. | ||
7828 | */ | ||
7829 | static void | ||
7830 | find_command(char *name, struct cmdentry *entry, int act, const char *path) | ||
7831 | { | ||
7832 | struct tblentry *cmdp; | ||
7833 | int idx; | ||
7834 | int prev; | ||
7835 | char *fullname; | ||
7836 | struct stat statb; | ||
7837 | int e; | ||
7838 | int updatetbl; | ||
7839 | struct builtincmd *bcmd; | ||
7840 | |||
7841 | /* If name contains a slash, don't use PATH or hash table */ | ||
7842 | if (strchr(name, '/') != NULL) { | ||
7843 | entry->u.index = -1; | ||
7844 | if (act & DO_ABS) { | ||
7845 | while (stat(name, &statb) < 0) { | ||
7846 | #ifdef SYSV | ||
7847 | if (errno == EINTR) | ||
7848 | continue; | ||
7849 | #endif | ||
7850 | entry->cmdtype = CMDUNKNOWN; | ||
7851 | return; | ||
7852 | } | ||
7853 | } | ||
7854 | entry->cmdtype = CMDNORMAL; | ||
7855 | return; | ||
7856 | } | ||
7857 | |||
7858 | #if ENABLE_FEATURE_SH_STANDALONE_SHELL | ||
7859 | if (find_applet_by_name(name)) { | ||
7860 | entry->cmdtype = CMDNORMAL; | ||
7861 | entry->u.index = -1; | ||
7862 | return; | ||
7863 | } | ||
7864 | #endif | ||
7865 | |||
7866 | if (is_safe_applet(name)) { | ||
7867 | entry->cmdtype = CMDNORMAL; | ||
7868 | entry->u.index = -1; | ||
7869 | return; | ||
7870 | } | ||
7871 | |||
7872 | updatetbl = (path == pathval()); | ||
7873 | if (!updatetbl) { | ||
7874 | act |= DO_ALTPATH; | ||
7875 | if (strstr(path, "%builtin") != NULL) | ||
7876 | act |= DO_ALTBLTIN; | ||
7877 | } | ||
7878 | |||
7879 | /* If name is in the table, check answer will be ok */ | ||
7880 | cmdp = cmdlookup(name, 0); | ||
7881 | if (cmdp != NULL) { | ||
7882 | int bit; | ||
7883 | |||
7884 | switch (cmdp->cmdtype) { | ||
7885 | default: | ||
7886 | #if DEBUG | ||
7887 | abort(); | ||
7888 | #endif | ||
7889 | case CMDNORMAL: | ||
7890 | bit = DO_ALTPATH; | ||
7891 | break; | ||
7892 | case CMDFUNCTION: | ||
7893 | bit = DO_NOFUNC; | ||
7894 | break; | ||
7895 | case CMDBUILTIN: | ||
7896 | bit = DO_ALTBLTIN; | ||
7897 | break; | ||
7898 | } | ||
7899 | if (act & bit) { | ||
7900 | updatetbl = 0; | ||
7901 | cmdp = NULL; | ||
7902 | } else if (cmdp->rehash == 0) | ||
7903 | /* if not invalidated by cd, we're done */ | ||
7904 | goto success; | ||
7905 | } | ||
7906 | |||
7907 | /* If %builtin not in path, check for builtin next */ | ||
7908 | bcmd = find_builtin(name); | ||
7909 | if (bcmd && (IS_BUILTIN_REGULAR(bcmd) || ( | ||
7910 | act & DO_ALTPATH ? !(act & DO_ALTBLTIN) : builtinloc <= 0 | ||
7911 | ))) | ||
7912 | goto builtin_success; | ||
7913 | |||
7914 | /* We have to search path. */ | ||
7915 | prev = -1; /* where to start */ | ||
7916 | if (cmdp && cmdp->rehash) { /* doing a rehash */ | ||
7917 | if (cmdp->cmdtype == CMDBUILTIN) | ||
7918 | prev = builtinloc; | ||
7919 | else | ||
7920 | prev = cmdp->param.index; | ||
7921 | } | ||
7922 | |||
7923 | e = ENOENT; | ||
7924 | idx = -1; | ||
7925 | loop: | ||
7926 | while ((fullname = padvance(&path, name)) != NULL) { | ||
7927 | stunalloc(fullname); | ||
7928 | idx++; | ||
7929 | if (pathopt) { | ||
7930 | if (prefix(pathopt, "builtin")) { | ||
7931 | if (bcmd) | ||
7932 | goto builtin_success; | ||
7933 | continue; | ||
7934 | } else if (!(act & DO_NOFUNC) && | ||
7935 | prefix(pathopt, "func")) { | ||
7936 | /* handled below */ | ||
7937 | } else { | ||
7938 | /* ignore unimplemented options */ | ||
7939 | continue; | ||
7940 | } | ||
7941 | } | ||
7942 | /* if rehash, don't redo absolute path names */ | ||
7943 | if (fullname[0] == '/' && idx <= prev) { | ||
7944 | if (idx < prev) | ||
7945 | continue; | ||
7946 | TRACE(("searchexec \"%s\": no change\n", name)); | ||
7947 | goto success; | ||
7948 | } | ||
7949 | while (stat(fullname, &statb) < 0) { | ||
7950 | #ifdef SYSV | ||
7951 | if (errno == EINTR) | ||
7952 | continue; | ||
7953 | #endif | ||
7954 | if (errno != ENOENT && errno != ENOTDIR) | ||
7955 | e = errno; | ||
7956 | goto loop; | ||
7957 | } | ||
7958 | e = EACCES; /* if we fail, this will be the error */ | ||
7959 | if (!S_ISREG(statb.st_mode)) | ||
7960 | continue; | ||
7961 | if (pathopt) { /* this is a %func directory */ | ||
7962 | stalloc(strlen(fullname) + 1); | ||
7963 | readcmdfile(fullname); | ||
7964 | cmdp = cmdlookup(name, 0); | ||
7965 | if (cmdp == NULL || cmdp->cmdtype != CMDFUNCTION) | ||
7966 | ash_msg_and_raise_error("%s not defined in %s", name, fullname); | ||
7967 | stunalloc(fullname); | ||
7968 | goto success; | ||
7969 | } | ||
7970 | TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname)); | ||
7971 | if (!updatetbl) { | ||
7972 | entry->cmdtype = CMDNORMAL; | ||
7973 | entry->u.index = idx; | ||
7974 | return; | ||
7975 | } | ||
7976 | INT_OFF; | ||
7977 | cmdp = cmdlookup(name, 1); | ||
7978 | cmdp->cmdtype = CMDNORMAL; | ||
7979 | cmdp->param.index = idx; | ||
7980 | INT_ON; | ||
7981 | goto success; | ||
7982 | } | ||
7983 | |||
7984 | /* We failed. If there was an entry for this command, delete it */ | ||
7985 | if (cmdp && updatetbl) | ||
7986 | delete_cmd_entry(); | ||
7987 | if (act & DO_ERR) | ||
7988 | ash_msg("%s: %s", name, errmsg(e, "not found")); | ||
7989 | entry->cmdtype = CMDUNKNOWN; | ||
7990 | return; | ||
7991 | |||
7992 | builtin_success: | ||
7993 | if (!updatetbl) { | ||
7994 | entry->cmdtype = CMDBUILTIN; | ||
7995 | entry->u.cmd = bcmd; | ||
7996 | return; | ||
7997 | } | ||
7998 | INT_OFF; | ||
7999 | cmdp = cmdlookup(name, 1); | ||
8000 | cmdp->cmdtype = CMDBUILTIN; | ||
8001 | cmdp->param.cmd = bcmd; | ||
8002 | INT_ON; | ||
8003 | success: | ||
8004 | cmdp->rehash = 0; | ||
8005 | entry->cmdtype = cmdp->cmdtype; | ||
8006 | entry->u = cmdp->param; | ||
8007 | } | ||
8008 | |||
8009 | /* | ||
8010 | * Execute a simple command. | 7811 | * Execute a simple command. |
8011 | */ | 7812 | */ |
8012 | static int back_exitstatus; /* exit status of backquoted command */ | 7813 | static int back_exitstatus; /* exit status of backquoted command */ |
@@ -8410,7 +8211,6 @@ static int checkkwd; | |||
8410 | #define CHKKWD 0x2 | 8211 | #define CHKKWD 0x2 |
8411 | #define CHKNL 0x4 | 8212 | #define CHKNL 0x4 |
8412 | 8213 | ||
8413 | |||
8414 | static void | 8214 | static void |
8415 | popstring(void) | 8215 | popstring(void) |
8416 | { | 8216 | { |
@@ -10096,7 +9896,6 @@ readtoken1(int firstc, int syntax, char *eofmark, int striptabs) | |||
10096 | return lasttoken; | 9896 | return lasttoken; |
10097 | /* end of readtoken routine */ | 9897 | /* end of readtoken routine */ |
10098 | 9898 | ||
10099 | |||
10100 | /* | 9899 | /* |
10101 | * Check to see whether we are at the end of the here document. When this | 9900 | * Check to see whether we are at the end of the here document. When this |
10102 | * is called, c is set to the first character of the next input line. If | 9901 | * is called, c is set to the first character of the next input line. If |
@@ -10133,7 +9932,6 @@ checkend: { | |||
10133 | goto checkend_return; | 9932 | goto checkend_return; |
10134 | } | 9933 | } |
10135 | 9934 | ||
10136 | |||
10137 | /* | 9935 | /* |
10138 | * Parse a redirection operator. The variable "out" points to a string | 9936 | * Parse a redirection operator. The variable "out" points to a string |
10139 | * specifying the fd to be redirected. The variable "c" contains the | 9937 | * specifying the fd to be redirected. The variable "c" contains the |
@@ -10198,11 +9996,16 @@ parseredir: { | |||
10198 | goto parseredir_return; | 9996 | goto parseredir_return; |
10199 | } | 9997 | } |
10200 | 9998 | ||
10201 | |||
10202 | /* | 9999 | /* |
10203 | * Parse a substitution. At this point, we have read the dollar sign | 10000 | * Parse a substitution. At this point, we have read the dollar sign |
10204 | * and nothing else. | 10001 | * and nothing else. |
10205 | */ | 10002 | */ |
10003 | |||
10004 | /* is_special(c) evaluates to 1 for c in "!#$*-0123456789?@"; 0 otherwise | ||
10005 | * (assuming ascii char codes, as the original implementation did) */ | ||
10006 | #define is_special(c) \ | ||
10007 | ((((unsigned int)c) - 33 < 32) \ | ||
10008 | && ((0xc1ff920dUL >> (((unsigned int)c) - 33)) & 1)) | ||
10206 | parsesub: { | 10009 | parsesub: { |
10207 | int subtype; | 10010 | int subtype; |
10208 | int typeloc; | 10011 | int typeloc; |
@@ -10304,7 +10107,6 @@ parsesub: { | |||
10304 | goto parsesub_return; | 10107 | goto parsesub_return; |
10305 | } | 10108 | } |
10306 | 10109 | ||
10307 | |||
10308 | /* | 10110 | /* |
10309 | * Called to parse command substitutions. Newstyle is set if the command | 10111 | * Called to parse command substitutions. Newstyle is set if the command |
10310 | * is enclosed inside $(...); nlpp is a pointer to the head of the linked | 10112 | * is enclosed inside $(...); nlpp is a pointer to the head of the linked |
@@ -10993,6 +10795,193 @@ readcmdfile(char *name) | |||
10993 | } | 10795 | } |
10994 | 10796 | ||
10995 | 10797 | ||
10798 | /* ============ find_command inplementation */ | ||
10799 | |||
10800 | /* | ||
10801 | * Resolve a command name. If you change this routine, you may have to | ||
10802 | * change the shellexec routine as well. | ||
10803 | */ | ||
10804 | static void | ||
10805 | find_command(char *name, struct cmdentry *entry, int act, const char *path) | ||
10806 | { | ||
10807 | struct tblentry *cmdp; | ||
10808 | int idx; | ||
10809 | int prev; | ||
10810 | char *fullname; | ||
10811 | struct stat statb; | ||
10812 | int e; | ||
10813 | int updatetbl; | ||
10814 | struct builtincmd *bcmd; | ||
10815 | |||
10816 | /* If name contains a slash, don't use PATH or hash table */ | ||
10817 | if (strchr(name, '/') != NULL) { | ||
10818 | entry->u.index = -1; | ||
10819 | if (act & DO_ABS) { | ||
10820 | while (stat(name, &statb) < 0) { | ||
10821 | #ifdef SYSV | ||
10822 | if (errno == EINTR) | ||
10823 | continue; | ||
10824 | #endif | ||
10825 | entry->cmdtype = CMDUNKNOWN; | ||
10826 | return; | ||
10827 | } | ||
10828 | } | ||
10829 | entry->cmdtype = CMDNORMAL; | ||
10830 | return; | ||
10831 | } | ||
10832 | |||
10833 | #if ENABLE_FEATURE_SH_STANDALONE_SHELL | ||
10834 | if (find_applet_by_name(name)) { | ||
10835 | entry->cmdtype = CMDNORMAL; | ||
10836 | entry->u.index = -1; | ||
10837 | return; | ||
10838 | } | ||
10839 | #endif | ||
10840 | |||
10841 | if (is_safe_applet(name)) { | ||
10842 | entry->cmdtype = CMDNORMAL; | ||
10843 | entry->u.index = -1; | ||
10844 | return; | ||
10845 | } | ||
10846 | |||
10847 | updatetbl = (path == pathval()); | ||
10848 | if (!updatetbl) { | ||
10849 | act |= DO_ALTPATH; | ||
10850 | if (strstr(path, "%builtin") != NULL) | ||
10851 | act |= DO_ALTBLTIN; | ||
10852 | } | ||
10853 | |||
10854 | /* If name is in the table, check answer will be ok */ | ||
10855 | cmdp = cmdlookup(name, 0); | ||
10856 | if (cmdp != NULL) { | ||
10857 | int bit; | ||
10858 | |||
10859 | switch (cmdp->cmdtype) { | ||
10860 | default: | ||
10861 | #if DEBUG | ||
10862 | abort(); | ||
10863 | #endif | ||
10864 | case CMDNORMAL: | ||
10865 | bit = DO_ALTPATH; | ||
10866 | break; | ||
10867 | case CMDFUNCTION: | ||
10868 | bit = DO_NOFUNC; | ||
10869 | break; | ||
10870 | case CMDBUILTIN: | ||
10871 | bit = DO_ALTBLTIN; | ||
10872 | break; | ||
10873 | } | ||
10874 | if (act & bit) { | ||
10875 | updatetbl = 0; | ||
10876 | cmdp = NULL; | ||
10877 | } else if (cmdp->rehash == 0) | ||
10878 | /* if not invalidated by cd, we're done */ | ||
10879 | goto success; | ||
10880 | } | ||
10881 | |||
10882 | /* If %builtin not in path, check for builtin next */ | ||
10883 | bcmd = find_builtin(name); | ||
10884 | if (bcmd && (IS_BUILTIN_REGULAR(bcmd) || ( | ||
10885 | act & DO_ALTPATH ? !(act & DO_ALTBLTIN) : builtinloc <= 0 | ||
10886 | ))) | ||
10887 | goto builtin_success; | ||
10888 | |||
10889 | /* We have to search path. */ | ||
10890 | prev = -1; /* where to start */ | ||
10891 | if (cmdp && cmdp->rehash) { /* doing a rehash */ | ||
10892 | if (cmdp->cmdtype == CMDBUILTIN) | ||
10893 | prev = builtinloc; | ||
10894 | else | ||
10895 | prev = cmdp->param.index; | ||
10896 | } | ||
10897 | |||
10898 | e = ENOENT; | ||
10899 | idx = -1; | ||
10900 | loop: | ||
10901 | while ((fullname = padvance(&path, name)) != NULL) { | ||
10902 | stunalloc(fullname); | ||
10903 | idx++; | ||
10904 | if (pathopt) { | ||
10905 | if (prefix(pathopt, "builtin")) { | ||
10906 | if (bcmd) | ||
10907 | goto builtin_success; | ||
10908 | continue; | ||
10909 | } else if (!(act & DO_NOFUNC) && | ||
10910 | prefix(pathopt, "func")) { | ||
10911 | /* handled below */ | ||
10912 | } else { | ||
10913 | /* ignore unimplemented options */ | ||
10914 | continue; | ||
10915 | } | ||
10916 | } | ||
10917 | /* if rehash, don't redo absolute path names */ | ||
10918 | if (fullname[0] == '/' && idx <= prev) { | ||
10919 | if (idx < prev) | ||
10920 | continue; | ||
10921 | TRACE(("searchexec \"%s\": no change\n", name)); | ||
10922 | goto success; | ||
10923 | } | ||
10924 | while (stat(fullname, &statb) < 0) { | ||
10925 | #ifdef SYSV | ||
10926 | if (errno == EINTR) | ||
10927 | continue; | ||
10928 | #endif | ||
10929 | if (errno != ENOENT && errno != ENOTDIR) | ||
10930 | e = errno; | ||
10931 | goto loop; | ||
10932 | } | ||
10933 | e = EACCES; /* if we fail, this will be the error */ | ||
10934 | if (!S_ISREG(statb.st_mode)) | ||
10935 | continue; | ||
10936 | if (pathopt) { /* this is a %func directory */ | ||
10937 | stalloc(strlen(fullname) + 1); | ||
10938 | readcmdfile(fullname); | ||
10939 | cmdp = cmdlookup(name, 0); | ||
10940 | if (cmdp == NULL || cmdp->cmdtype != CMDFUNCTION) | ||
10941 | ash_msg_and_raise_error("%s not defined in %s", name, fullname); | ||
10942 | stunalloc(fullname); | ||
10943 | goto success; | ||
10944 | } | ||
10945 | TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname)); | ||
10946 | if (!updatetbl) { | ||
10947 | entry->cmdtype = CMDNORMAL; | ||
10948 | entry->u.index = idx; | ||
10949 | return; | ||
10950 | } | ||
10951 | INT_OFF; | ||
10952 | cmdp = cmdlookup(name, 1); | ||
10953 | cmdp->cmdtype = CMDNORMAL; | ||
10954 | cmdp->param.index = idx; | ||
10955 | INT_ON; | ||
10956 | goto success; | ||
10957 | } | ||
10958 | |||
10959 | /* We failed. If there was an entry for this command, delete it */ | ||
10960 | if (cmdp && updatetbl) | ||
10961 | delete_cmd_entry(); | ||
10962 | if (act & DO_ERR) | ||
10963 | ash_msg("%s: %s", name, errmsg(e, "not found")); | ||
10964 | entry->cmdtype = CMDUNKNOWN; | ||
10965 | return; | ||
10966 | |||
10967 | builtin_success: | ||
10968 | if (!updatetbl) { | ||
10969 | entry->cmdtype = CMDBUILTIN; | ||
10970 | entry->u.cmd = bcmd; | ||
10971 | return; | ||
10972 | } | ||
10973 | INT_OFF; | ||
10974 | cmdp = cmdlookup(name, 1); | ||
10975 | cmdp->cmdtype = CMDBUILTIN; | ||
10976 | cmdp->param.cmd = bcmd; | ||
10977 | INT_ON; | ||
10978 | success: | ||
10979 | cmdp->rehash = 0; | ||
10980 | entry->cmdtype = cmdp->cmdtype; | ||
10981 | entry->u = cmdp->param; | ||
10982 | } | ||
10983 | |||
10984 | |||
10996 | /* ============ redir.c | 10985 | /* ============ redir.c |
10997 | * | 10986 | * |
10998 | * Code for dealing with input/output redirection. | 10987 | * Code for dealing with input/output redirection. |
@@ -11184,7 +11173,6 @@ dupredirect(union node *redir, int f) | |||
11184 | } | 11173 | } |
11185 | } | 11174 | } |
11186 | 11175 | ||
11187 | |||
11188 | /* | 11176 | /* |
11189 | * Process a list of redirection commands. If the REDIR_PUSH flag is set, | 11177 | * Process a list of redirection commands. If the REDIR_PUSH flag is set, |
11190 | * old file descriptors are stashed away so that the redirection can be | 11178 | * old file descriptors are stashed away so that the redirection can be |