aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-02-23 21:10:35 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-02-23 21:10:35 +0000
commitcc5715184bf91fa5a6bb7d4423e6c7aed71a98ef (patch)
tree1873fdfbae8cfe040073b4277782adfc5ab17b86
parent2de3d9fbeef02d19305a4a18c758a4e5f65260d4 (diff)
downloadbusybox-w32-cc5715184bf91fa5a6bb7d4423e6c7aed71a98ef.tar.gz
busybox-w32-cc5715184bf91fa5a6bb7d4423e6c7aed71a98ef.tar.bz2
busybox-w32-cc5715184bf91fa5a6bb7d4423e6c7aed71a98ef.zip
ash: cleanup part 2.6
-rw-r--r--shell/ash.c402
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
80static const char *const optletters_optnames[] = { 79static const char *const optletters_optnames[] = {
@@ -139,6 +138,8 @@ static const char homestr[] = "HOME";
139static const char snlfmt[] = "%s\n"; 138static const char snlfmt[] = "%s\n";
140static const char illnum[] = "Illegal number: %s"; 139static const char illnum[] = "Illegal number: %s";
141 140
141static char *minusc; /* argument to -c option */
142
142static int isloginsh; 143static int isloginsh;
143/* pid of main shell */ 144/* pid of main shell */
144static int rootpid; 145static 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
2883static void readcmdfile(char *);
2884
2885
2886/* options.h */ 2874/* options.h */
2887 2875
2888static char *minusc; /* argument to -c option */
2889
2890static void optschanged(void); 2876static void optschanged(void);
2891static void setparam(char **); 2877static void setparam(char **);
2892static void freeparam(volatile struct shparam *); 2878static 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 */
7829static void
7830find_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 */
8012static int back_exitstatus; /* exit status of backquoted command */ 7813static 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
8414static void 8214static void
8415popstring(void) 8215popstring(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))
10206parsesub: { 10009parsesub: {
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 */
10804static void
10805find_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