diff options
| author | Eric Andersen <andersen@codepoet.org> | 2001-06-22 06:23:03 +0000 |
|---|---|---|
| committer | Eric Andersen <andersen@codepoet.org> | 2001-06-22 06:23:03 +0000 |
| commit | c798b0776264950350b53a0aa58101bb1dfcf6dc (patch) | |
| tree | 81f8a3a9c7dc197f2d62e28f51df86a9d2ae2058 /shell | |
| parent | a0105713e82d108e36f01375de606b69d7aac5d0 (diff) | |
| download | busybox-w32-c798b0776264950350b53a0aa58101bb1dfcf6dc.tar.gz busybox-w32-c798b0776264950350b53a0aa58101bb1dfcf6dc.tar.bz2 busybox-w32-c798b0776264950350b53a0aa58101bb1dfcf6dc.zip | |
Some cleanups for hush. Saves about 350bytes.
-Erik
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/hush.c | 165 |
1 files changed, 67 insertions, 98 deletions
diff --git a/shell/hush.c b/shell/hush.c index 3b1e53c82..a9d3a16ac 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
| @@ -217,11 +217,6 @@ struct pipe { | |||
| 217 | reserved_style r_mode; /* supports if, for, while, until */ | 217 | reserved_style r_mode; /* supports if, for, while, until */ |
| 218 | }; | 218 | }; |
| 219 | 219 | ||
| 220 | struct jobset { | ||
| 221 | struct pipe *head; /* head of list of running jobs */ | ||
| 222 | struct pipe *fg; /* current foreground job */ | ||
| 223 | }; | ||
| 224 | |||
| 225 | struct close_me { | 220 | struct close_me { |
| 226 | int fd; | 221 | int fd; |
| 227 | struct close_me *next; | 222 | struct close_me *next; |
| @@ -253,8 +248,10 @@ static int fake_mode; | |||
| 253 | static int interactive; | 248 | static int interactive; |
| 254 | static struct close_me *close_me_head; | 249 | static struct close_me *close_me_head; |
| 255 | static const char *cwd; | 250 | static const char *cwd; |
| 256 | static struct jobset *job_list; | 251 | static struct pipe *job_list; |
| 257 | static unsigned int last_bg_pid; | 252 | static unsigned int last_bg_pid; |
| 253 | static unsigned int last_jobid; | ||
| 254 | static unsigned int ctty; | ||
| 258 | static char *PS1; | 255 | static char *PS1; |
| 259 | static char *PS2; | 256 | static char *PS2; |
| 260 | struct variables shell_ver = { "HUSH_VERSION", "0.01", 1, 1, 0 }; | 257 | struct variables shell_ver = { "HUSH_VERSION", "0.01", 1, 1, 0 }; |
| @@ -361,10 +358,8 @@ static int free_pipe_list(struct pipe *head, int indent); | |||
| 361 | static int free_pipe(struct pipe *pi, int indent); | 358 | static int free_pipe(struct pipe *pi, int indent); |
| 362 | /* really run the final data structures: */ | 359 | /* really run the final data structures: */ |
| 363 | static int setup_redirects(struct child_prog *prog, int squirrel[]); | 360 | static int setup_redirects(struct child_prog *prog, int squirrel[]); |
| 364 | static int pipe_wait(struct pipe *pi); | ||
| 365 | static int run_list_real(struct pipe *pi); | 361 | static int run_list_real(struct pipe *pi); |
| 366 | static void pseudo_exec(struct child_prog *child) __attribute__ ((noreturn)); | 362 | static void pseudo_exec(struct child_prog *child) __attribute__ ((noreturn)); |
| 367 | int controlling_tty(int check_pgrp); | ||
| 368 | static int run_pipe_real(struct pipe *pi); | 363 | static int run_pipe_real(struct pipe *pi); |
| 369 | /* extended glob support: */ | 364 | /* extended glob support: */ |
| 370 | static int globhack(const char *src, int flags, glob_t *pglob); | 365 | static int globhack(const char *src, int flags, glob_t *pglob); |
| @@ -392,7 +387,7 @@ static int parse_stream_outer(struct in_str *inp); | |||
| 392 | static int parse_string_outer(const char *s); | 387 | static int parse_string_outer(const char *s); |
| 393 | static int parse_file_outer(FILE *f); | 388 | static int parse_file_outer(FILE *f); |
| 394 | /* job management: */ | 389 | /* job management: */ |
| 395 | static void checkjobs(); | 390 | static int checkjobs(struct pipe* fg_pipe); |
| 396 | static void insert_bg_job(struct pipe *pi); | 391 | static void insert_bg_job(struct pipe *pi); |
| 397 | static void remove_bg_job(struct pipe *pi); | 392 | static void remove_bg_job(struct pipe *pi); |
| 398 | /* local variable support */ | 393 | /* local variable support */ |
| @@ -543,10 +538,12 @@ static int builtin_fg_bg(struct child_prog *child) | |||
| 543 | int i, jobnum; | 538 | int i, jobnum; |
| 544 | struct pipe *pi=NULL; | 539 | struct pipe *pi=NULL; |
| 545 | 540 | ||
| 541 | if (!interactive) | ||
| 542 | return EXIT_FAILURE; | ||
| 546 | /* If they gave us no args, assume they want the last backgrounded task */ | 543 | /* If they gave us no args, assume they want the last backgrounded task */ |
| 547 | if (!child->argv[1]) { | 544 | if (!child->argv[1]) { |
| 548 | for (pi = job_list->head; pi; pi = pi->next) { | 545 | for (pi = job_list; pi; pi = pi->next) { |
| 549 | if (pi->progs && pi->progs->pid == last_bg_pid) { | 546 | if (pi->jobid == last_jobid) { |
| 550 | break; | 547 | break; |
| 551 | } | 548 | } |
| 552 | } | 549 | } |
| @@ -560,7 +557,7 @@ static int builtin_fg_bg(struct child_prog *child) | |||
| 560 | return EXIT_FAILURE; | 557 | return EXIT_FAILURE; |
| 561 | } | 558 | } |
| 562 | 559 | ||
| 563 | for (pi = job_list->head; pi; pi = pi->next) { | 560 | for (pi = job_list; pi; pi = pi->next) { |
| 564 | if (pi->jobid == jobnum) { | 561 | if (pi->jobid == jobnum) { |
| 565 | break; | 562 | break; |
| 566 | } | 563 | } |
| @@ -574,10 +571,9 @@ static int builtin_fg_bg(struct child_prog *child) | |||
| 574 | /* Make this job the foreground job */ | 571 | /* Make this job the foreground job */ |
| 575 | signal(SIGTTOU, SIG_IGN); | 572 | signal(SIGTTOU, SIG_IGN); |
| 576 | /* suppress messages when run from /linuxrc mag@sysgo.de */ | 573 | /* suppress messages when run from /linuxrc mag@sysgo.de */ |
| 577 | if (tcsetpgrp(0, pi->pgrp) && errno != ENOTTY) | 574 | if (tcsetpgrp(ctty, pi->pgrp) && errno != ENOTTY) |
| 578 | perror_msg("tcsetpgrp-1"); | 575 | perror_msg("tcsetpgrp-1"); |
| 579 | signal(SIGTTOU, SIG_DFL); | 576 | signal(SIGTTOU, SIG_DFL); |
| 580 | job_list->fg = pi; | ||
| 581 | } | 577 | } |
| 582 | 578 | ||
| 583 | /* Restart the processes in the job */ | 579 | /* Restart the processes in the job */ |
| @@ -612,7 +608,7 @@ static int builtin_jobs(struct child_prog *child) | |||
| 612 | struct pipe *job; | 608 | struct pipe *job; |
| 613 | char *status_string; | 609 | char *status_string; |
| 614 | 610 | ||
| 615 | for (job = job_list->head; job; job = job->next) { | 611 | for (job = job_list; job; job = job->next) { |
| 616 | if (job->running_progs == job->stopped_progs) | 612 | if (job->running_progs == job->stopped_progs) |
| 617 | status_string = "Stopped"; | 613 | status_string = "Stopped"; |
| 618 | else | 614 | else |
| @@ -1044,27 +1040,6 @@ static void restore_redirects(int squirrel[]) | |||
| 1044 | } | 1040 | } |
| 1045 | } | 1041 | } |
| 1046 | 1042 | ||
| 1047 | /* XXX this definitely needs some more thought, work, and | ||
| 1048 | * cribbing from other shells */ | ||
| 1049 | static int pipe_wait(struct pipe *pi) | ||
| 1050 | { | ||
| 1051 | int rcode=0, i, pid, running, status; | ||
| 1052 | running = pi->num_progs; | ||
| 1053 | while (running) { | ||
| 1054 | pid=waitpid(-1, &status, 0); | ||
| 1055 | if (pid < 0) perror_msg_and_die("waitpid"); | ||
| 1056 | for (i=0; i < pi->num_progs; i++) { | ||
| 1057 | if (pi->progs[i].pid == pid) { | ||
| 1058 | if (i==pi->num_progs-1) rcode=WEXITSTATUS(status); | ||
| 1059 | pi->progs[i].pid = 0; | ||
| 1060 | running--; | ||
| 1061 | break; | ||
| 1062 | } | ||
| 1063 | } | ||
| 1064 | } | ||
| 1065 | return rcode; | ||
| 1066 | } | ||
| 1067 | |||
| 1068 | /* never returns */ | 1043 | /* never returns */ |
| 1069 | /* XXX no exit() here. If you don't exec, use _exit instead. | 1044 | /* XXX no exit() here. If you don't exec, use _exit instead. |
| 1070 | * The at_exit handlers apparently confuse the calling process, | 1045 | * The at_exit handlers apparently confuse the calling process, |
| @@ -1161,15 +1136,15 @@ static void insert_bg_job(struct pipe *pi) | |||
| 1161 | 1136 | ||
| 1162 | /* Linear search for the ID of the job to use */ | 1137 | /* Linear search for the ID of the job to use */ |
| 1163 | pi->jobid = 1; | 1138 | pi->jobid = 1; |
| 1164 | for (thejob = job_list->head; thejob; thejob = thejob->next) | 1139 | for (thejob = job_list; thejob; thejob = thejob->next) |
| 1165 | if (thejob->jobid >= pi->jobid) | 1140 | if (thejob->jobid >= pi->jobid) |
| 1166 | pi->jobid = thejob->jobid + 1; | 1141 | pi->jobid = thejob->jobid + 1; |
| 1167 | 1142 | ||
| 1168 | /* add thejob to the list of running jobs */ | 1143 | /* add thejob to the list of running jobs */ |
| 1169 | if (!job_list->head) { | 1144 | if (!job_list) { |
| 1170 | thejob = job_list->head = xmalloc(sizeof(*thejob)); | 1145 | thejob = job_list= xmalloc(sizeof(*thejob)); |
| 1171 | } else { | 1146 | } else { |
| 1172 | for (thejob = job_list->head; thejob->next; thejob = thejob->next) /* nothing */; | 1147 | for (thejob = job_list; thejob->next; thejob = thejob->next) /* nothing */; |
| 1173 | thejob->next = xmalloc(sizeof(*thejob)); | 1148 | thejob->next = xmalloc(sizeof(*thejob)); |
| 1174 | thejob = thejob->next; | 1149 | thejob = thejob->next; |
| 1175 | } | 1150 | } |
| @@ -1194,17 +1169,18 @@ static void insert_bg_job(struct pipe *pi) | |||
| 1194 | to the list of backgrounded thejobs and leave it alone */ | 1169 | to the list of backgrounded thejobs and leave it alone */ |
| 1195 | printf("[%d] %d\n", thejob->jobid, thejob->progs[0].pid); | 1170 | printf("[%d] %d\n", thejob->jobid, thejob->progs[0].pid); |
| 1196 | last_bg_pid = thejob->progs[0].pid; | 1171 | last_bg_pid = thejob->progs[0].pid; |
| 1172 | last_jobid = thejob->jobid; | ||
| 1197 | } | 1173 | } |
| 1198 | 1174 | ||
| 1199 | /* remove a backgrounded job from a jobset */ | 1175 | /* remove a backgrounded job */ |
| 1200 | static void remove_bg_job(struct pipe *pi) | 1176 | static void remove_bg_job(struct pipe *pi) |
| 1201 | { | 1177 | { |
| 1202 | struct pipe *prev_pipe; | 1178 | struct pipe *prev_pipe; |
| 1203 | 1179 | ||
| 1204 | if (pi == job_list->head) { | 1180 | if (pi == job_list) { |
| 1205 | job_list->head = pi->next; | 1181 | job_list= pi->next; |
| 1206 | } else { | 1182 | } else { |
| 1207 | prev_pipe = job_list->head; | 1183 | prev_pipe = job_list; |
| 1208 | while (prev_pipe->next != pi) | 1184 | while (prev_pipe->next != pi) |
| 1209 | prev_pipe = prev_pipe->next; | 1185 | prev_pipe = prev_pipe->next; |
| 1210 | prev_pipe->next = pi->next; | 1186 | prev_pipe->next = pi->next; |
| @@ -1214,17 +1190,35 @@ static void remove_bg_job(struct pipe *pi) | |||
| 1214 | free(pi); | 1190 | free(pi); |
| 1215 | } | 1191 | } |
| 1216 | 1192 | ||
| 1217 | /* Checks to see if any background processes have exited -- if they | 1193 | /* Checks to see if any processes have exited -- if they |
| 1218 | have, figure out why and see if a job has completed */ | 1194 | have, figure out why and see if a job has completed */ |
| 1219 | static void checkjobs() | 1195 | static int checkjobs(struct pipe* fg_pipe) |
| 1220 | { | 1196 | { |
| 1221 | int status, ctty; | 1197 | int attributes; |
| 1198 | int status; | ||
| 1222 | int prognum = 0; | 1199 | int prognum = 0; |
| 1223 | struct pipe *pi; | 1200 | struct pipe *pi; |
| 1224 | pid_t childpid; | 1201 | pid_t childpid; |
| 1225 | 1202 | ||
| 1226 | while ((childpid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) { | 1203 | attributes = WUNTRACED; |
| 1227 | for (pi = job_list->head; pi; pi = pi->next) { | 1204 | if (fg_pipe==NULL) { |
| 1205 | attributes |= WNOHANG; | ||
| 1206 | } | ||
| 1207 | |||
| 1208 | while ((childpid = waitpid(-1, &status, attributes)) > 0) { | ||
| 1209 | if (fg_pipe) { | ||
| 1210 | int i, rcode = 0; | ||
| 1211 | for (i=0; i < fg_pipe->num_progs; i++) { | ||
| 1212 | if (fg_pipe->progs[i].pid == childpid) { | ||
| 1213 | if (i==fg_pipe->num_progs-1) | ||
| 1214 | rcode=WEXITSTATUS(status); | ||
| 1215 | (fg_pipe->num_progs)--; | ||
| 1216 | return(rcode); | ||
| 1217 | } | ||
| 1218 | } | ||
| 1219 | } | ||
| 1220 | |||
| 1221 | for (pi = job_list; pi; pi = pi->next) { | ||
| 1228 | prognum = 0; | 1222 | prognum = 0; |
| 1229 | while (prognum < pi->num_progs && | 1223 | while (prognum < pi->num_progs && |
| 1230 | pi->progs[prognum].pid != childpid) prognum++; | 1224 | pi->progs[prognum].pid != childpid) prognum++; |
| @@ -1261,10 +1255,9 @@ static void checkjobs() | |||
| 1261 | perror_msg("waitpid"); | 1255 | perror_msg("waitpid"); |
| 1262 | 1256 | ||
| 1263 | /* move the shell to the foreground */ | 1257 | /* move the shell to the foreground */ |
| 1264 | if (interactive && (ctty=controlling_tty(0))!=-1) { | 1258 | if (interactive && tcsetpgrp(ctty, getpgid(0))) |
| 1265 | if (tcsetpgrp(ctty, getpgrp())) | 1259 | perror_msg("tcsetpgrp-2"); |
| 1266 | perror_msg("tcsetpgrp-2"); | 1260 | return -1; |
| 1267 | } | ||
| 1268 | } | 1261 | } |
| 1269 | 1262 | ||
| 1270 | /* Figure out our controlling tty, checking in order stderr, | 1263 | /* Figure out our controlling tty, checking in order stderr, |
| @@ -1272,24 +1265,27 @@ static void checkjobs() | |||
| 1272 | * we belong to the foreground process group associated with | 1265 | * we belong to the foreground process group associated with |
| 1273 | * that tty. The value of ctty is needed in order to call | 1266 | * that tty. The value of ctty is needed in order to call |
| 1274 | * tcsetpgrp(ctty, ...); */ | 1267 | * tcsetpgrp(ctty, ...); */ |
| 1275 | int controlling_tty(int check_pgrp) | 1268 | void controlling_tty(int check_pgrp) |
| 1276 | { | 1269 | { |
| 1277 | pid_t curpgrp; | 1270 | pid_t curpgrp; |
| 1278 | int ctty; | ||
| 1279 | 1271 | ||
| 1280 | if ((curpgrp = tcgetpgrp(ctty = 2)) < 0 | 1272 | if ((curpgrp = tcgetpgrp(ctty = 2)) < 0 |
| 1281 | && (curpgrp = tcgetpgrp(ctty = 0)) < 0 | 1273 | && (curpgrp = tcgetpgrp(ctty = 0)) < 0 |
| 1282 | && (curpgrp = tcgetpgrp(ctty = 1)) < 0) | 1274 | && (curpgrp = tcgetpgrp(ctty = 1)) < 0) |
| 1283 | return errno = ENOTTY, -1; | 1275 | goto ctty_error; |
| 1276 | |||
| 1277 | if (check_pgrp && curpgrp != getpgid(0)) | ||
| 1278 | goto ctty_error; | ||
| 1284 | 1279 | ||
| 1285 | if (check_pgrp && curpgrp != getpgrp()) | 1280 | return; |
| 1286 | return errno = EPERM, -1; | ||
| 1287 | 1281 | ||
| 1288 | return ctty; | 1282 | ctty_error: |
| 1283 | ctty = -1; | ||
| 1284 | return; | ||
| 1289 | } | 1285 | } |
| 1290 | 1286 | ||
| 1291 | /* run_pipe_real() starts all the jobs, but doesn't wait for anything | 1287 | /* run_pipe_real() starts all the jobs, but doesn't wait for anything |
| 1292 | * to finish. See pipe_wait(). | 1288 | * to finish. See checkjobs(). |
| 1293 | * | 1289 | * |
| 1294 | * return code is normally -1, when the caller has to wait for children | 1290 | * return code is normally -1, when the caller has to wait for children |
| 1295 | * to finish to determine the exit status of the pipe. If the pipe | 1291 | * to finish to determine the exit status of the pipe. If the pipe |
| @@ -1307,21 +1303,14 @@ int controlling_tty(int check_pgrp) | |||
| 1307 | static int run_pipe_real(struct pipe *pi) | 1303 | static int run_pipe_real(struct pipe *pi) |
| 1308 | { | 1304 | { |
| 1309 | int i; | 1305 | int i; |
| 1310 | int ctty; | ||
| 1311 | int nextin, nextout; | 1306 | int nextin, nextout; |
| 1312 | int pipefds[2]; /* pipefds[0] is for reading */ | 1307 | int pipefds[2]; /* pipefds[0] is for reading */ |
| 1313 | struct child_prog *child; | 1308 | struct child_prog *child; |
| 1314 | struct built_in_command *x; | 1309 | struct built_in_command *x; |
| 1315 | 1310 | ||
| 1316 | ctty = -1; | ||
| 1317 | nextin = 0; | 1311 | nextin = 0; |
| 1318 | pi->pgrp = -1; | 1312 | pi->pgrp = -1; |
| 1319 | 1313 | ||
| 1320 | /* Check if we are supposed to run in the foreground */ | ||
| 1321 | if (interactive && pi->followup!=PIPE_BG) { | ||
| 1322 | if ((ctty = controlling_tty(pi->pgrp<0)) < 0) return -1; | ||
| 1323 | } | ||
| 1324 | |||
| 1325 | /* Check if this is a simple builtin (not part of a pipe). | 1314 | /* Check if this is a simple builtin (not part of a pipe). |
| 1326 | * Builtins within pipes have to fork anyway, and are handled in | 1315 | * Builtins within pipes have to fork anyway, and are handled in |
| 1327 | * pseudo_exec. "echo foo | read bar" doesn't work on bash, either. | 1316 | * pseudo_exec. "echo foo | read bar" doesn't work on bash, either. |
| @@ -1492,15 +1481,13 @@ static int run_list_real(struct pipe *pi) | |||
| 1492 | 1481 | ||
| 1493 | if (interactive) { | 1482 | if (interactive) { |
| 1494 | /* move the new process group into the foreground */ | 1483 | /* move the new process group into the foreground */ |
| 1495 | /* suppress messages when run from /linuxrc mag@sysgo.de */ | 1484 | if (tcsetpgrp(ctty, pi->pgrp) && errno != ENOTTY) |
| 1496 | /* XXX probably this "0" should come from controlling_tty() */ | ||
| 1497 | if (tcsetpgrp(0, pi->pgrp) && errno != ENOTTY) | ||
| 1498 | perror_msg("tcsetpgrp-3"); | 1485 | perror_msg("tcsetpgrp-3"); |
| 1499 | rcode = pipe_wait(pi); | 1486 | rcode = checkjobs(pi); |
| 1500 | if (tcsetpgrp(0, getpgrp()) && errno != ENOTTY) | 1487 | if (tcsetpgrp(ctty, getpgid(0)) && errno != ENOTTY) |
| 1501 | perror_msg("tcsetpgrp-4"); | 1488 | perror_msg("tcsetpgrp-4"); |
| 1502 | } else { | 1489 | } else { |
| 1503 | rcode = pipe_wait(pi); | 1490 | rcode = checkjobs(pi); |
| 1504 | } | 1491 | } |
| 1505 | debug_printf("pipe_wait returned %d\n",rcode); | 1492 | debug_printf("pipe_wait returned %d\n",rcode); |
| 1506 | } | 1493 | } |
| @@ -1511,7 +1498,7 @@ static int run_list_real(struct pipe *pi) | |||
| 1511 | (rcode!=EXIT_SUCCESS && pi->followup==PIPE_AND) ) | 1498 | (rcode!=EXIT_SUCCESS && pi->followup==PIPE_AND) ) |
| 1512 | skip_more_in_this_rmode=rmode; | 1499 | skip_more_in_this_rmode=rmode; |
| 1513 | } | 1500 | } |
| 1514 | checkjobs(); | 1501 | checkjobs(NULL); |
| 1515 | return rcode; | 1502 | return rcode; |
| 1516 | } | 1503 | } |
| 1517 | 1504 | ||
| @@ -2530,29 +2517,10 @@ static int parse_file_outer(FILE *f) | |||
| 2530 | } | 2517 | } |
| 2531 | 2518 | ||
| 2532 | 2519 | ||
| 2533 | /* I think Erik wrote this. It looks imperfect at best */ | ||
| 2534 | void grab_tty_control(void) | ||
| 2535 | { | ||
| 2536 | pid_t initialpgrp; | ||
| 2537 | do { | ||
| 2538 | initialpgrp = tcgetpgrp(fileno(stderr)); | ||
| 2539 | if (initialpgrp < 0) { | ||
| 2540 | error_msg("sh: can't access tty; job control disabled\n"); | ||
| 2541 | } | ||
| 2542 | if (initialpgrp == -1) | ||
| 2543 | initialpgrp = getpgrp(); | ||
| 2544 | else if (initialpgrp != getpgrp()) { | ||
| 2545 | killpg(initialpgrp, SIGTTIN); | ||
| 2546 | continue; | ||
| 2547 | } | ||
| 2548 | } while (0); | ||
| 2549 | } | ||
| 2550 | |||
| 2551 | int shell_main(int argc, char **argv) | 2520 | int shell_main(int argc, char **argv) |
| 2552 | { | 2521 | { |
| 2553 | int opt; | 2522 | int opt; |
| 2554 | FILE *input; | 2523 | FILE *input; |
| 2555 | struct jobset joblist_end = { NULL, NULL }; | ||
| 2556 | char **e = environ; | 2524 | char **e = environ; |
| 2557 | 2525 | ||
| 2558 | /* XXX what should these be while sourcing /etc/profile? */ | 2526 | /* XXX what should these be while sourcing /etc/profile? */ |
| @@ -2568,10 +2536,11 @@ int shell_main(int argc, char **argv) | |||
| 2568 | interactive = 0; | 2536 | interactive = 0; |
| 2569 | close_me_head = NULL; | 2537 | close_me_head = NULL; |
| 2570 | last_bg_pid = 0; | 2538 | last_bg_pid = 0; |
| 2539 | last_jobid = 0; | ||
| 2571 | 2540 | ||
| 2572 | /* Initialize some more globals to non-zero values */ | 2541 | /* Initialize some more globals to non-zero values */ |
| 2573 | set_cwd(); | 2542 | set_cwd(); |
| 2574 | job_list = &joblist_end; | 2543 | job_list = NULL; |
| 2575 | #ifdef BB_FEATURE_COMMAND_EDITING | 2544 | #ifdef BB_FEATURE_COMMAND_EDITING |
| 2576 | cmdedit_set_initial_prompt(); | 2545 | cmdedit_set_initial_prompt(); |
| 2577 | #else | 2546 | #else |
| @@ -2594,9 +2563,10 @@ int shell_main(int argc, char **argv) | |||
| 2594 | * don't fight over who gets the foreground */ | 2563 | * don't fight over who gets the foreground */ |
| 2595 | /* don't pay any attention to this signal; it just confuses | 2564 | /* don't pay any attention to this signal; it just confuses |
| 2596 | things and isn't really meant for shells anyway */ | 2565 | things and isn't really meant for shells anyway */ |
| 2566 | controlling_tty(0); | ||
| 2597 | signal(SIGTTOU, SIG_IGN); | 2567 | signal(SIGTTOU, SIG_IGN); |
| 2598 | setpgid(0, getpid()); | 2568 | setpgid(0, getpid()); |
| 2599 | tcsetpgrp(fileno(stderr), getpid()); | 2569 | tcsetpgrp(ctty, getpid()); |
| 2600 | 2570 | ||
| 2601 | if (argv[0] && argv[0][0] == '-') { | 2571 | if (argv[0] && argv[0][0] == '-') { |
| 2602 | debug_printf("\nsourcing /etc/profile\n"); | 2572 | debug_printf("\nsourcing /etc/profile\n"); |
| @@ -2650,7 +2620,6 @@ int shell_main(int argc, char **argv) | |||
| 2650 | if (interactive) { | 2620 | if (interactive) { |
| 2651 | /* Looks like they want an interactive shell */ | 2621 | /* Looks like they want an interactive shell */ |
| 2652 | fprintf(stdout, "\nhush -- the humble shell v0.01 (testing)\n\n"); | 2622 | fprintf(stdout, "\nhush -- the humble shell v0.01 (testing)\n\n"); |
| 2653 | grab_tty_control(); | ||
| 2654 | } | 2623 | } |
| 2655 | if (argv[optind]==NULL) { | 2624 | if (argv[optind]==NULL) { |
| 2656 | opt=parse_file_outer(stdin); | 2625 | opt=parse_file_outer(stdin); |
