diff options
-rw-r--r-- | shell/lash.c | 69 |
1 files changed, 27 insertions, 42 deletions
diff --git a/shell/lash.c b/shell/lash.c index 729d102c6..c74684bf7 100644 --- a/shell/lash.c +++ b/shell/lash.c | |||
@@ -126,27 +126,27 @@ static int busy_loop(FILE * input); | |||
126 | * can change global variables in the parent shell process but they will not | 126 | * can change global variables in the parent shell process but they will not |
127 | * work with pipes and redirects; 'unset foo | whatever' will not work) */ | 127 | * work with pipes and redirects; 'unset foo | whatever' will not work) */ |
128 | static const struct built_in_command bltins[] = { | 128 | static const struct built_in_command bltins[] = { |
129 | {"bg", "Resume a job in the background", builtin_fg_bg}, | 129 | {"bg" , "Resume a job in the background", builtin_fg_bg}, |
130 | {"cd", "Change working directory", builtin_cd}, | 130 | {"cd" , "Change working directory", builtin_cd}, |
131 | {"exec", "Exec command, replacing this shell with the exec'd process", builtin_exec}, | 131 | {"exec" , "Exec command, replacing this shell with the exec'd process", builtin_exec}, |
132 | {"exit", "Exit from shell()", builtin_exit}, | 132 | {"exit" , "Exit from shell()", builtin_exit}, |
133 | {"fg", "Bring job into the foreground", builtin_fg_bg}, | 133 | {"fg" , "Bring job into the foreground", builtin_fg_bg}, |
134 | {"jobs", "Lists the active jobs", builtin_jobs}, | 134 | {"jobs" , "Lists the active jobs", builtin_jobs}, |
135 | {"export", "Set environment variable", builtin_export}, | 135 | {"export", "Set environment variable", builtin_export}, |
136 | {"unset", "Unset environment variable", builtin_unset}, | 136 | {"unset" , "Unset environment variable", builtin_unset}, |
137 | {"read", "Input environment variable", builtin_read}, | 137 | {"read" , "Input environment variable", builtin_read}, |
138 | {".", "Source-in and run commands in a file", builtin_source}, | 138 | {"." , "Source-in and run commands in a file", builtin_source}, |
139 | /* These were "forked applets", but distinction was nuked */ | ||
140 | /* Original comment retained: */ | ||
141 | /* Table of forking built-in functions (things that fork cannot change global | ||
142 | * variables in the parent process, such as the current working directory) */ | ||
143 | {"pwd" , "Print current directory", builtin_pwd}, | ||
144 | {"help" , "List shell built-in commands", builtin_help}, | ||
139 | /* to do: add ulimit */ | 145 | /* to do: add ulimit */ |
140 | {NULL, NULL, NULL} | ||
141 | }; | 146 | }; |
142 | 147 | ||
143 | /* Table of forking built-in functions (things that fork cannot change global | 148 | #define VEC_SIZE(v) (sizeof(v)/sizeof(v[0])) |
144 | * variables in the parent process, such as the current working directory) */ | 149 | #define VEC_LAST(v) v[VEC_SIZE(v)-1] |
145 | static struct built_in_command bltins_forking[] = { | ||
146 | {"pwd", "Print current directory", builtin_pwd}, | ||
147 | {"help", "List shell built-in commands", builtin_help}, | ||
148 | {NULL, NULL, NULL} | ||
149 | }; | ||
150 | 150 | ||
151 | 151 | ||
152 | static int shell_context; /* Type prompt trigger (PS1 or PS2) */ | 152 | static int shell_context; /* Type prompt trigger (PS1 or PS2) */ |
@@ -318,12 +318,7 @@ static int builtin_help(struct child_prog ATTRIBUTE_UNUSED *dummy) | |||
318 | 318 | ||
319 | printf("\nBuilt-in commands:\n" | 319 | printf("\nBuilt-in commands:\n" |
320 | "-------------------\n"); | 320 | "-------------------\n"); |
321 | for (x = bltins; x->cmd; x++) { | 321 | for (x = bltins; x <= &VEC_LAST(bltins); x++) { |
322 | if (x->descr == NULL) | ||
323 | continue; | ||
324 | printf("%s\t%s\n", x->cmd, x->descr); | ||
325 | } | ||
326 | for (x = bltins_forking; x->cmd; x++) { | ||
327 | if (x->descr == NULL) | 322 | if (x->descr == NULL) |
328 | continue; | 323 | continue; |
329 | printf("%s\t%s\n", x->cmd, x->descr); | 324 | printf("%s\t%s\n", x->cmd, x->descr); |
@@ -963,7 +958,7 @@ static int parse_command(char **command_ptr, struct job *job, int *inbg) | |||
963 | *src == ']') *buf++ = '\\'; | 958 | *src == ']') *buf++ = '\\'; |
964 | *buf++ = *src; | 959 | *buf++ = *src; |
965 | } else if (isspace(*src)) { | 960 | } else if (isspace(*src)) { |
966 | if (*prog->argv[argc_l] || flag & LASH_OPT_SAW_QUOTE) { | 961 | if (*prog->argv[argc_l] || (flag & LASH_OPT_SAW_QUOTE)) { |
967 | buf++, argc_l++; | 962 | buf++, argc_l++; |
968 | /* +1 here leaves room for the NULL which ends argv */ | 963 | /* +1 here leaves room for the NULL which ends argv */ |
969 | if ((argc_l + 1) == argv_alloced) { | 964 | if ((argc_l + 1) == argv_alloced) { |
@@ -1143,20 +1138,14 @@ static int pseudo_exec(struct child_prog *child) | |||
1143 | * easier to waste a few CPU cycles than it is to figure out | 1138 | * easier to waste a few CPU cycles than it is to figure out |
1144 | * if this is one of those cases. | 1139 | * if this is one of those cases. |
1145 | */ | 1140 | */ |
1146 | for (x = bltins; x->cmd; x++) { | ||
1147 | if (strcmp(child->argv[0], x->cmd) == 0) { | ||
1148 | _exit(x->function(child)); | ||
1149 | } | ||
1150 | } | ||
1151 | |||
1152 | /* Check if the command matches any of the forking builtins. */ | 1141 | /* Check if the command matches any of the forking builtins. */ |
1153 | for (x = bltins_forking; x->cmd; x++) { | 1142 | for (x = bltins; x <= &VEC_LAST(bltins); x++) { |
1154 | if (strcmp(child->argv[0], x->cmd) == 0) { | 1143 | if (strcmp(child->argv[0], x->cmd) == 0) { |
1155 | applet_name = x->cmd; | ||
1156 | _exit(x->function(child)); | 1144 | _exit(x->function(child)); |
1157 | } | 1145 | } |
1158 | } | 1146 | } |
1159 | 1147 | ||
1148 | |||
1160 | /* Check if the command matches any busybox internal | 1149 | /* Check if the command matches any busybox internal |
1161 | * commands ("applets") here. Following discussions from | 1150 | * commands ("applets") here. Following discussions from |
1162 | * November 2000 on busybox@busybox.net, don't use | 1151 | * November 2000 on busybox@busybox.net, don't use |
@@ -1237,23 +1226,19 @@ static int run_command(struct job *newjob, int inbg, int outpipe[2]) | |||
1237 | const struct built_in_command *x; | 1226 | const struct built_in_command *x; |
1238 | struct child_prog *child; | 1227 | struct child_prog *child; |
1239 | 1228 | ||
1240 | nextin = 0, nextout = 1; | 1229 | nextin = 0; |
1241 | for (i = 0; i < newjob->num_progs; i++) { | 1230 | for (i = 0; i < newjob->num_progs; i++) { |
1242 | child = &(newjob->progs[i]); | 1231 | child = &(newjob->progs[i]); |
1243 | 1232 | ||
1233 | nextout = 1; | ||
1244 | if ((i + 1) < newjob->num_progs) { | 1234 | if ((i + 1) < newjob->num_progs) { |
1245 | if (pipe(pipefds) < 0) | 1235 | if (pipe(pipefds) < 0) |
1246 | bb_perror_msg_and_die("pipe"); | 1236 | bb_perror_msg_and_die("pipe"); |
1247 | nextout = pipefds[1]; | 1237 | nextout = pipefds[1]; |
1248 | } else { | 1238 | } else if (outpipe[1] != -1) { |
1249 | if (outpipe[1] != -1) { | 1239 | nextout = outpipe[1]; |
1250 | nextout = outpipe[1]; | ||
1251 | } else { | ||
1252 | nextout = 1; | ||
1253 | } | ||
1254 | } | 1240 | } |
1255 | 1241 | ||
1256 | |||
1257 | /* Check if the command matches any non-forking builtins, | 1242 | /* Check if the command matches any non-forking builtins, |
1258 | * but only if this is a simple command. | 1243 | * but only if this is a simple command. |
1259 | * Non-forking builtins within pipes have to fork anyway, | 1244 | * Non-forking builtins within pipes have to fork anyway, |
@@ -1267,7 +1252,7 @@ static int run_command(struct job *newjob, int inbg, int outpipe[2]) | |||
1267 | return builtin_export(child); | 1252 | return builtin_export(child); |
1268 | } | 1253 | } |
1269 | 1254 | ||
1270 | for (x = bltins; x->cmd; x++) { | 1255 | for (x = bltins; x <= &VEC_LAST(bltins); x++) { |
1271 | if (strcmp(child->argv[0], x->cmd) == 0) { | 1256 | if (strcmp(child->argv[0], x->cmd) == 0) { |
1272 | int rcode; | 1257 | int rcode; |
1273 | int squirrel[] = {-1, -1, -1}; | 1258 | int squirrel[] = {-1, -1, -1}; |
@@ -1279,7 +1264,7 @@ static int run_command(struct job *newjob, int inbg, int outpipe[2]) | |||
1279 | } | 1264 | } |
1280 | } | 1265 | } |
1281 | 1266 | ||
1282 | #if !defined(__UCLIBC__) || defined(__ARCH_HAS_MMU__) | 1267 | #if BB_MMU |
1283 | child->pid = fork(); | 1268 | child->pid = fork(); |
1284 | #else | 1269 | #else |
1285 | child->pid = vfork(); | 1270 | child->pid = vfork(); |