aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-04-12 17:10:45 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-04-12 17:10:45 +0000
commitb69f35effee244a564a2c2557578812be1e77296 (patch)
treeb53201f8b2b182305c9357041d5aea1856ff2b87
parent7cced6e57404cc1043a1b0dd0491aef2f792497e (diff)
downloadbusybox-w32-b69f35effee244a564a2c2557578812be1e77296.tar.gz
busybox-w32-b69f35effee244a564a2c2557578812be1e77296.tar.bz2
busybox-w32-b69f35effee244a564a2c2557578812be1e77296.zip
lash: "forking" applets are actually can be treated the same way as "non-forked".
Also save a bit of space on trailing NULL array elements.
-rw-r--r--shell/lash.c69
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) */
128static const struct built_in_command bltins[] = { 128static 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]
145static 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
152static int shell_context; /* Type prompt trigger (PS1 or PS2) */ 152static 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();