diff options
author | Eric Andersen <andersen@codepoet.org> | 2001-05-21 16:18:22 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2001-05-21 16:18:22 +0000 |
commit | ada18ff0f53f1b61073a843959e97c0f4206576e (patch) | |
tree | d7b851cf4f91bd6b510ee83d0f8fe18efd79c906 | |
parent | 8ae319a32228dff15f4b9696deb5883fb242f024 (diff) | |
download | busybox-w32-ada18ff0f53f1b61073a843959e97c0f4206576e.tar.gz busybox-w32-ada18ff0f53f1b61073a843959e97c0f4206576e.tar.bz2 busybox-w32-ada18ff0f53f1b61073a843959e97c0f4206576e.zip |
The latest patch from Larry
-rw-r--r-- | hush.c | 92 | ||||
-rw-r--r-- | shell/hush.c | 92 |
2 files changed, 122 insertions, 62 deletions
@@ -365,6 +365,7 @@ static int setup_redirects(struct child_prog *prog, int squirrel[]); | |||
365 | static int pipe_wait(struct pipe *pi); | 365 | static int pipe_wait(struct pipe *pi); |
366 | static int run_list_real(struct pipe *pi); | 366 | static int run_list_real(struct pipe *pi); |
367 | static void pseudo_exec(struct child_prog *child) __attribute__ ((noreturn)); | 367 | static void pseudo_exec(struct child_prog *child) __attribute__ ((noreturn)); |
368 | int controlling_tty(int check_pgrp); | ||
368 | static int run_pipe_real(struct pipe *pi); | 369 | static int run_pipe_real(struct pipe *pi); |
369 | /* extended glob support: */ | 370 | /* extended glob support: */ |
370 | static int globhack(const char *src, int flags, glob_t *pglob); | 371 | static int globhack(const char *src, int flags, glob_t *pglob); |
@@ -576,7 +577,7 @@ static int builtin_fg_bg(struct child_prog *child) | |||
576 | signal(SIGTTOU, SIG_IGN); | 577 | signal(SIGTTOU, SIG_IGN); |
577 | /* suppress messages when run from /linuxrc mag@sysgo.de */ | 578 | /* suppress messages when run from /linuxrc mag@sysgo.de */ |
578 | if (tcsetpgrp(0, pi->pgrp) && errno != ENOTTY) | 579 | if (tcsetpgrp(0, pi->pgrp) && errno != ENOTTY) |
579 | perror_msg("tcsetpgrp"); | 580 | perror_msg("tcsetpgrp-1"); |
580 | signal(SIGTTOU, SIG_DFL); | 581 | signal(SIGTTOU, SIG_DFL); |
581 | job_list->fg = pi; | 582 | job_list->fg = pi; |
582 | } | 583 | } |
@@ -1059,13 +1060,14 @@ static int pipe_wait(struct pipe *pi) | |||
1059 | return rcode; | 1060 | return rcode; |
1060 | } | 1061 | } |
1061 | 1062 | ||
1062 | /* very simple version for testing */ | 1063 | /* never returns */ |
1063 | static void pseudo_exec(struct child_prog *child) | 1064 | static void pseudo_exec(struct child_prog *child) |
1064 | { | 1065 | { |
1065 | int i, rcode; | 1066 | int i, rcode; |
1066 | struct built_in_command *x; | 1067 | struct built_in_command *x; |
1067 | if (child->argv) { | 1068 | if (child->argv) { |
1068 | for (i=0; is_assignment(child->argv[i]); i++) { | 1069 | for (i=0; is_assignment(child->argv[i]); i++) { |
1070 | debug_printf("pid %d environment modification: %s\n",getpid(),child->argv[i]); | ||
1069 | putenv(strdup(child->argv[i])); | 1071 | putenv(strdup(child->argv[i])); |
1070 | } | 1072 | } |
1071 | child->argv+=i; /* XXX this hack isn't so horrible, since we are about | 1073 | child->argv+=i; /* XXX this hack isn't so horrible, since we are about |
@@ -1125,7 +1127,7 @@ static void pseudo_exec(struct child_prog *child) | |||
1125 | #endif | 1127 | #endif |
1126 | debug_printf("exec of %s\n",child->argv[0]); | 1128 | debug_printf("exec of %s\n",child->argv[0]); |
1127 | execvp(child->argv[0],child->argv); | 1129 | execvp(child->argv[0],child->argv); |
1128 | perror("execvp"); | 1130 | perror_msg("couldn't exec: %s",child->argv[0]); |
1129 | exit(1); | 1131 | exit(1); |
1130 | } else if (child->group) { | 1132 | } else if (child->group) { |
1131 | debug_printf("runtime nesting to group\n"); | 1133 | debug_printf("runtime nesting to group\n"); |
@@ -1224,7 +1226,7 @@ static void free_pipe(struct pipe *pi) | |||
1224 | have, figure out why and see if a job has completed */ | 1226 | have, figure out why and see if a job has completed */ |
1225 | static void checkjobs() | 1227 | static void checkjobs() |
1226 | { | 1228 | { |
1227 | int status; | 1229 | int status, ctty; |
1228 | int prognum = 0; | 1230 | int prognum = 0; |
1229 | struct pipe *pi; | 1231 | struct pipe *pi; |
1230 | pid_t childpid; | 1232 | pid_t childpid; |
@@ -1264,8 +1266,31 @@ static void checkjobs() | |||
1264 | perror_msg("waitpid"); | 1266 | perror_msg("waitpid"); |
1265 | 1267 | ||
1266 | /* move the shell to the foreground */ | 1268 | /* move the shell to the foreground */ |
1267 | if (tcsetpgrp(0, getpgrp()) && errno != ENOTTY) | 1269 | if (interactive && (ctty=controlling_tty(0))!=-1) { |
1268 | perror_msg("tcsetpgrp"); | 1270 | if (tcsetpgrp(ctty, getpgrp())) |
1271 | perror_msg("tcsetpgrp-2"); | ||
1272 | } | ||
1273 | } | ||
1274 | |||
1275 | /* Figure out our controlling tty, checking in order stderr, | ||
1276 | * stdin, and stdout. If check_pgrp is set, also check that | ||
1277 | * we belong to the foreground process group associated with | ||
1278 | * that tty. The value of ctty is needed in order to call | ||
1279 | * tcsetpgrp(ctty, ...); */ | ||
1280 | int controlling_tty(int check_pgrp) | ||
1281 | { | ||
1282 | pid_t curpgrp; | ||
1283 | int ctty; | ||
1284 | |||
1285 | if ((curpgrp = tcgetpgrp(ctty = 2)) < 0 | ||
1286 | && (curpgrp = tcgetpgrp(ctty = 0)) < 0 | ||
1287 | && (curpgrp = tcgetpgrp(ctty = 1)) < 0) | ||
1288 | return errno = ENOTTY, -1; | ||
1289 | |||
1290 | if (check_pgrp && curpgrp != getpgrp()) | ||
1291 | return errno = EPERM, -1; | ||
1292 | |||
1293 | return ctty; | ||
1269 | } | 1294 | } |
1270 | 1295 | ||
1271 | /* run_pipe_real() starts all the jobs, but doesn't wait for anything | 1296 | /* run_pipe_real() starts all the jobs, but doesn't wait for anything |
@@ -1295,17 +1320,11 @@ static int run_pipe_real(struct pipe *pi) | |||
1295 | 1320 | ||
1296 | ctty = -1; | 1321 | ctty = -1; |
1297 | nextin = 0; | 1322 | nextin = 0; |
1298 | pi->pgrp = 0; | 1323 | pi->pgrp = -1; |
1299 | 1324 | ||
1300 | /* Check if we are supposed to run in the foreground */ | 1325 | /* Check if we are supposed to run in the foreground */ |
1301 | if (interactive && pi->followup!=PIPE_BG) { | 1326 | if (interactive && pi->followup!=PIPE_BG) { |
1302 | if ((pi->pgrp = tcgetpgrp(ctty = 2)) < 0 | 1327 | if ((ctty = controlling_tty(pi->pgrp<0)) < 0) return -1; |
1303 | && (pi->pgrp = tcgetpgrp(ctty = 0)) < 0 | ||
1304 | && (pi->pgrp = tcgetpgrp(ctty = 1)) < 0) | ||
1305 | return errno = ENOTTY, -1; | ||
1306 | |||
1307 | if (pi->pgrp < 0 && pi->pgrp != getpgrp()) | ||
1308 | return errno = EPERM, -1; | ||
1309 | } | 1328 | } |
1310 | 1329 | ||
1311 | /* Check if this is a simple builtin (not part of a pipe). | 1330 | /* Check if this is a simple builtin (not part of a pipe). |
@@ -1395,11 +1414,11 @@ static int run_pipe_real(struct pipe *pi) | |||
1395 | * and the pipe fd is available for dup'ing. */ | 1414 | * and the pipe fd is available for dup'ing. */ |
1396 | setup_redirects(child,NULL); | 1415 | setup_redirects(child,NULL); |
1397 | 1416 | ||
1398 | if (pi->followup!=PIPE_BG) { | 1417 | if (interactive && pi->followup!=PIPE_BG) { |
1399 | /* If we (the child) win the race, put ourselves in the process | 1418 | /* If we (the child) win the race, put ourselves in the process |
1400 | * group whose leader is the first process in this pipe. */ | 1419 | * group whose leader is the first process in this pipe. */ |
1401 | if (pi->pgrp < 0) { | 1420 | if (pi->pgrp < 0) { |
1402 | pi->pgrp = child->pid; | 1421 | pi->pgrp = getpid(); |
1403 | } | 1422 | } |
1404 | if (setpgid(0, pi->pgrp) == 0) { | 1423 | if (setpgid(0, pi->pgrp) == 0) { |
1405 | signal(SIGTTOU, SIG_IGN); | 1424 | signal(SIGTTOU, SIG_IGN); |
@@ -1461,13 +1480,15 @@ static int run_list_real(struct pipe *pi) | |||
1461 | if (interactive) { | 1480 | if (interactive) { |
1462 | /* move the new process group into the foreground */ | 1481 | /* move the new process group into the foreground */ |
1463 | /* suppress messages when run from /linuxrc mag@sysgo.de */ | 1482 | /* suppress messages when run from /linuxrc mag@sysgo.de */ |
1483 | /* XXX probably this "0" should come from controlling_tty() */ | ||
1464 | if (tcsetpgrp(0, pi->pgrp) && errno != ENOTTY) | 1484 | if (tcsetpgrp(0, pi->pgrp) && errno != ENOTTY) |
1465 | perror_msg("tcsetpgrp"); | 1485 | perror_msg("tcsetpgrp-3"); |
1466 | rcode = pipe_wait(pi); | 1486 | rcode = pipe_wait(pi); |
1467 | if (tcsetpgrp(0, getpgrp()) && errno != ENOTTY) | 1487 | if (tcsetpgrp(0, getpgrp()) && errno != ENOTTY) |
1468 | perror_msg("tcsetpgrp"); | 1488 | perror_msg("tcsetpgrp-4"); |
1469 | } else { | 1489 | } else { |
1470 | rcode = pipe_wait(pi); | 1490 | rcode = pipe_wait(pi); |
1491 | debug_printf("pipe_wait returned %d\n",rcode); | ||
1471 | } | 1492 | } |
1472 | } | 1493 | } |
1473 | last_return_code=rcode; | 1494 | last_return_code=rcode; |
@@ -2484,6 +2505,25 @@ static int parse_file_outer(FILE *f) | |||
2484 | return rcode; | 2505 | return rcode; |
2485 | } | 2506 | } |
2486 | 2507 | ||
2508 | |||
2509 | /* I think Erik wrote this. It looks imperfect at best */ | ||
2510 | void grab_tty_control(void) | ||
2511 | { | ||
2512 | pid_t initialpgrp; | ||
2513 | do { | ||
2514 | initialpgrp = tcgetpgrp(fileno(stderr)); | ||
2515 | if (initialpgrp < 0) { | ||
2516 | error_msg("sh: can't access tty; job control disabled\n"); | ||
2517 | } | ||
2518 | if (initialpgrp == -1) | ||
2519 | initialpgrp = getpgrp(); | ||
2520 | else if (initialpgrp != getpgrp()) { | ||
2521 | killpg(initialpgrp, SIGTTIN); | ||
2522 | continue; | ||
2523 | } | ||
2524 | } while (0); | ||
2525 | } | ||
2526 | |||
2487 | int shell_main(int argc, char **argv) | 2527 | int shell_main(int argc, char **argv) |
2488 | { | 2528 | { |
2489 | int opt; | 2529 | int opt; |
@@ -2507,19 +2547,6 @@ int shell_main(int argc, char **argv) | |||
2507 | /* If we get started under a job aware app (like bash | 2547 | /* If we get started under a job aware app (like bash |
2508 | * for example), make sure we are now in charge so we | 2548 | * for example), make sure we are now in charge so we |
2509 | * don't fight over who gets the foreground */ | 2549 | * don't fight over who gets the foreground */ |
2510 | do { | ||
2511 | pid_t initialpgrp; | ||
2512 | initialpgrp = tcgetpgrp(fileno(stderr)); | ||
2513 | if (initialpgrp < 0) { | ||
2514 | error_msg_and_die("sh: can't access tty; job control disabled\n"); | ||
2515 | } | ||
2516 | if (initialpgrp == -1) | ||
2517 | initialpgrp = getpgrp(); | ||
2518 | else if (initialpgrp != getpgrp()) { | ||
2519 | killpg(initialpgrp, SIGTTIN); | ||
2520 | continue; | ||
2521 | } | ||
2522 | } while (0); | ||
2523 | /* don't pay any attention to this signal; it just confuses | 2550 | /* don't pay any attention to this signal; it just confuses |
2524 | things and isn't really meant for shells anyway */ | 2551 | things and isn't really meant for shells anyway */ |
2525 | signal(SIGTTOU, SIG_IGN); | 2552 | signal(SIGTTOU, SIG_IGN); |
@@ -2588,6 +2615,9 @@ int shell_main(int argc, char **argv) | |||
2588 | if (interactive) { | 2615 | if (interactive) { |
2589 | /* Looks like they want an interactive shell */ | 2616 | /* Looks like they want an interactive shell */ |
2590 | fprintf(stdout, "\nhush -- the humble shell v0.01 (testing)\n\n"); | 2617 | fprintf(stdout, "\nhush -- the humble shell v0.01 (testing)\n\n"); |
2618 | grab_tty_control(); | ||
2619 | } | ||
2620 | if (argv[optind]==NULL) { | ||
2591 | opt=parse_file_outer(stdin); | 2621 | opt=parse_file_outer(stdin); |
2592 | goto final_return; | 2622 | goto final_return; |
2593 | } | 2623 | } |
diff --git a/shell/hush.c b/shell/hush.c index a1e65b24e..fc45bb270 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -365,6 +365,7 @@ static int setup_redirects(struct child_prog *prog, int squirrel[]); | |||
365 | static int pipe_wait(struct pipe *pi); | 365 | static int pipe_wait(struct pipe *pi); |
366 | static int run_list_real(struct pipe *pi); | 366 | static int run_list_real(struct pipe *pi); |
367 | static void pseudo_exec(struct child_prog *child) __attribute__ ((noreturn)); | 367 | static void pseudo_exec(struct child_prog *child) __attribute__ ((noreturn)); |
368 | int controlling_tty(int check_pgrp); | ||
368 | static int run_pipe_real(struct pipe *pi); | 369 | static int run_pipe_real(struct pipe *pi); |
369 | /* extended glob support: */ | 370 | /* extended glob support: */ |
370 | static int globhack(const char *src, int flags, glob_t *pglob); | 371 | static int globhack(const char *src, int flags, glob_t *pglob); |
@@ -576,7 +577,7 @@ static int builtin_fg_bg(struct child_prog *child) | |||
576 | signal(SIGTTOU, SIG_IGN); | 577 | signal(SIGTTOU, SIG_IGN); |
577 | /* suppress messages when run from /linuxrc mag@sysgo.de */ | 578 | /* suppress messages when run from /linuxrc mag@sysgo.de */ |
578 | if (tcsetpgrp(0, pi->pgrp) && errno != ENOTTY) | 579 | if (tcsetpgrp(0, pi->pgrp) && errno != ENOTTY) |
579 | perror_msg("tcsetpgrp"); | 580 | perror_msg("tcsetpgrp-1"); |
580 | signal(SIGTTOU, SIG_DFL); | 581 | signal(SIGTTOU, SIG_DFL); |
581 | job_list->fg = pi; | 582 | job_list->fg = pi; |
582 | } | 583 | } |
@@ -1059,13 +1060,14 @@ static int pipe_wait(struct pipe *pi) | |||
1059 | return rcode; | 1060 | return rcode; |
1060 | } | 1061 | } |
1061 | 1062 | ||
1062 | /* very simple version for testing */ | 1063 | /* never returns */ |
1063 | static void pseudo_exec(struct child_prog *child) | 1064 | static void pseudo_exec(struct child_prog *child) |
1064 | { | 1065 | { |
1065 | int i, rcode; | 1066 | int i, rcode; |
1066 | struct built_in_command *x; | 1067 | struct built_in_command *x; |
1067 | if (child->argv) { | 1068 | if (child->argv) { |
1068 | for (i=0; is_assignment(child->argv[i]); i++) { | 1069 | for (i=0; is_assignment(child->argv[i]); i++) { |
1070 | debug_printf("pid %d environment modification: %s\n",getpid(),child->argv[i]); | ||
1069 | putenv(strdup(child->argv[i])); | 1071 | putenv(strdup(child->argv[i])); |
1070 | } | 1072 | } |
1071 | child->argv+=i; /* XXX this hack isn't so horrible, since we are about | 1073 | child->argv+=i; /* XXX this hack isn't so horrible, since we are about |
@@ -1125,7 +1127,7 @@ static void pseudo_exec(struct child_prog *child) | |||
1125 | #endif | 1127 | #endif |
1126 | debug_printf("exec of %s\n",child->argv[0]); | 1128 | debug_printf("exec of %s\n",child->argv[0]); |
1127 | execvp(child->argv[0],child->argv); | 1129 | execvp(child->argv[0],child->argv); |
1128 | perror("execvp"); | 1130 | perror_msg("couldn't exec: %s",child->argv[0]); |
1129 | exit(1); | 1131 | exit(1); |
1130 | } else if (child->group) { | 1132 | } else if (child->group) { |
1131 | debug_printf("runtime nesting to group\n"); | 1133 | debug_printf("runtime nesting to group\n"); |
@@ -1224,7 +1226,7 @@ static void free_pipe(struct pipe *pi) | |||
1224 | have, figure out why and see if a job has completed */ | 1226 | have, figure out why and see if a job has completed */ |
1225 | static void checkjobs() | 1227 | static void checkjobs() |
1226 | { | 1228 | { |
1227 | int status; | 1229 | int status, ctty; |
1228 | int prognum = 0; | 1230 | int prognum = 0; |
1229 | struct pipe *pi; | 1231 | struct pipe *pi; |
1230 | pid_t childpid; | 1232 | pid_t childpid; |
@@ -1264,8 +1266,31 @@ static void checkjobs() | |||
1264 | perror_msg("waitpid"); | 1266 | perror_msg("waitpid"); |
1265 | 1267 | ||
1266 | /* move the shell to the foreground */ | 1268 | /* move the shell to the foreground */ |
1267 | if (tcsetpgrp(0, getpgrp()) && errno != ENOTTY) | 1269 | if (interactive && (ctty=controlling_tty(0))!=-1) { |
1268 | perror_msg("tcsetpgrp"); | 1270 | if (tcsetpgrp(ctty, getpgrp())) |
1271 | perror_msg("tcsetpgrp-2"); | ||
1272 | } | ||
1273 | } | ||
1274 | |||
1275 | /* Figure out our controlling tty, checking in order stderr, | ||
1276 | * stdin, and stdout. If check_pgrp is set, also check that | ||
1277 | * we belong to the foreground process group associated with | ||
1278 | * that tty. The value of ctty is needed in order to call | ||
1279 | * tcsetpgrp(ctty, ...); */ | ||
1280 | int controlling_tty(int check_pgrp) | ||
1281 | { | ||
1282 | pid_t curpgrp; | ||
1283 | int ctty; | ||
1284 | |||
1285 | if ((curpgrp = tcgetpgrp(ctty = 2)) < 0 | ||
1286 | && (curpgrp = tcgetpgrp(ctty = 0)) < 0 | ||
1287 | && (curpgrp = tcgetpgrp(ctty = 1)) < 0) | ||
1288 | return errno = ENOTTY, -1; | ||
1289 | |||
1290 | if (check_pgrp && curpgrp != getpgrp()) | ||
1291 | return errno = EPERM, -1; | ||
1292 | |||
1293 | return ctty; | ||
1269 | } | 1294 | } |
1270 | 1295 | ||
1271 | /* run_pipe_real() starts all the jobs, but doesn't wait for anything | 1296 | /* run_pipe_real() starts all the jobs, but doesn't wait for anything |
@@ -1295,17 +1320,11 @@ static int run_pipe_real(struct pipe *pi) | |||
1295 | 1320 | ||
1296 | ctty = -1; | 1321 | ctty = -1; |
1297 | nextin = 0; | 1322 | nextin = 0; |
1298 | pi->pgrp = 0; | 1323 | pi->pgrp = -1; |
1299 | 1324 | ||
1300 | /* Check if we are supposed to run in the foreground */ | 1325 | /* Check if we are supposed to run in the foreground */ |
1301 | if (interactive && pi->followup!=PIPE_BG) { | 1326 | if (interactive && pi->followup!=PIPE_BG) { |
1302 | if ((pi->pgrp = tcgetpgrp(ctty = 2)) < 0 | 1327 | if ((ctty = controlling_tty(pi->pgrp<0)) < 0) return -1; |
1303 | && (pi->pgrp = tcgetpgrp(ctty = 0)) < 0 | ||
1304 | && (pi->pgrp = tcgetpgrp(ctty = 1)) < 0) | ||
1305 | return errno = ENOTTY, -1; | ||
1306 | |||
1307 | if (pi->pgrp < 0 && pi->pgrp != getpgrp()) | ||
1308 | return errno = EPERM, -1; | ||
1309 | } | 1328 | } |
1310 | 1329 | ||
1311 | /* Check if this is a simple builtin (not part of a pipe). | 1330 | /* Check if this is a simple builtin (not part of a pipe). |
@@ -1395,11 +1414,11 @@ static int run_pipe_real(struct pipe *pi) | |||
1395 | * and the pipe fd is available for dup'ing. */ | 1414 | * and the pipe fd is available for dup'ing. */ |
1396 | setup_redirects(child,NULL); | 1415 | setup_redirects(child,NULL); |
1397 | 1416 | ||
1398 | if (pi->followup!=PIPE_BG) { | 1417 | if (interactive && pi->followup!=PIPE_BG) { |
1399 | /* If we (the child) win the race, put ourselves in the process | 1418 | /* If we (the child) win the race, put ourselves in the process |
1400 | * group whose leader is the first process in this pipe. */ | 1419 | * group whose leader is the first process in this pipe. */ |
1401 | if (pi->pgrp < 0) { | 1420 | if (pi->pgrp < 0) { |
1402 | pi->pgrp = child->pid; | 1421 | pi->pgrp = getpid(); |
1403 | } | 1422 | } |
1404 | if (setpgid(0, pi->pgrp) == 0) { | 1423 | if (setpgid(0, pi->pgrp) == 0) { |
1405 | signal(SIGTTOU, SIG_IGN); | 1424 | signal(SIGTTOU, SIG_IGN); |
@@ -1461,13 +1480,15 @@ static int run_list_real(struct pipe *pi) | |||
1461 | if (interactive) { | 1480 | if (interactive) { |
1462 | /* move the new process group into the foreground */ | 1481 | /* move the new process group into the foreground */ |
1463 | /* suppress messages when run from /linuxrc mag@sysgo.de */ | 1482 | /* suppress messages when run from /linuxrc mag@sysgo.de */ |
1483 | /* XXX probably this "0" should come from controlling_tty() */ | ||
1464 | if (tcsetpgrp(0, pi->pgrp) && errno != ENOTTY) | 1484 | if (tcsetpgrp(0, pi->pgrp) && errno != ENOTTY) |
1465 | perror_msg("tcsetpgrp"); | 1485 | perror_msg("tcsetpgrp-3"); |
1466 | rcode = pipe_wait(pi); | 1486 | rcode = pipe_wait(pi); |
1467 | if (tcsetpgrp(0, getpgrp()) && errno != ENOTTY) | 1487 | if (tcsetpgrp(0, getpgrp()) && errno != ENOTTY) |
1468 | perror_msg("tcsetpgrp"); | 1488 | perror_msg("tcsetpgrp-4"); |
1469 | } else { | 1489 | } else { |
1470 | rcode = pipe_wait(pi); | 1490 | rcode = pipe_wait(pi); |
1491 | debug_printf("pipe_wait returned %d\n",rcode); | ||
1471 | } | 1492 | } |
1472 | } | 1493 | } |
1473 | last_return_code=rcode; | 1494 | last_return_code=rcode; |
@@ -2484,6 +2505,25 @@ static int parse_file_outer(FILE *f) | |||
2484 | return rcode; | 2505 | return rcode; |
2485 | } | 2506 | } |
2486 | 2507 | ||
2508 | |||
2509 | /* I think Erik wrote this. It looks imperfect at best */ | ||
2510 | void grab_tty_control(void) | ||
2511 | { | ||
2512 | pid_t initialpgrp; | ||
2513 | do { | ||
2514 | initialpgrp = tcgetpgrp(fileno(stderr)); | ||
2515 | if (initialpgrp < 0) { | ||
2516 | error_msg("sh: can't access tty; job control disabled\n"); | ||
2517 | } | ||
2518 | if (initialpgrp == -1) | ||
2519 | initialpgrp = getpgrp(); | ||
2520 | else if (initialpgrp != getpgrp()) { | ||
2521 | killpg(initialpgrp, SIGTTIN); | ||
2522 | continue; | ||
2523 | } | ||
2524 | } while (0); | ||
2525 | } | ||
2526 | |||
2487 | int shell_main(int argc, char **argv) | 2527 | int shell_main(int argc, char **argv) |
2488 | { | 2528 | { |
2489 | int opt; | 2529 | int opt; |
@@ -2507,19 +2547,6 @@ int shell_main(int argc, char **argv) | |||
2507 | /* If we get started under a job aware app (like bash | 2547 | /* If we get started under a job aware app (like bash |
2508 | * for example), make sure we are now in charge so we | 2548 | * for example), make sure we are now in charge so we |
2509 | * don't fight over who gets the foreground */ | 2549 | * don't fight over who gets the foreground */ |
2510 | do { | ||
2511 | pid_t initialpgrp; | ||
2512 | initialpgrp = tcgetpgrp(fileno(stderr)); | ||
2513 | if (initialpgrp < 0) { | ||
2514 | error_msg_and_die("sh: can't access tty; job control disabled\n"); | ||
2515 | } | ||
2516 | if (initialpgrp == -1) | ||
2517 | initialpgrp = getpgrp(); | ||
2518 | else if (initialpgrp != getpgrp()) { | ||
2519 | killpg(initialpgrp, SIGTTIN); | ||
2520 | continue; | ||
2521 | } | ||
2522 | } while (0); | ||
2523 | /* don't pay any attention to this signal; it just confuses | 2550 | /* don't pay any attention to this signal; it just confuses |
2524 | things and isn't really meant for shells anyway */ | 2551 | things and isn't really meant for shells anyway */ |
2525 | signal(SIGTTOU, SIG_IGN); | 2552 | signal(SIGTTOU, SIG_IGN); |
@@ -2588,6 +2615,9 @@ int shell_main(int argc, char **argv) | |||
2588 | if (interactive) { | 2615 | if (interactive) { |
2589 | /* Looks like they want an interactive shell */ | 2616 | /* Looks like they want an interactive shell */ |
2590 | fprintf(stdout, "\nhush -- the humble shell v0.01 (testing)\n\n"); | 2617 | fprintf(stdout, "\nhush -- the humble shell v0.01 (testing)\n\n"); |
2618 | grab_tty_control(); | ||
2619 | } | ||
2620 | if (argv[optind]==NULL) { | ||
2591 | opt=parse_file_outer(stdin); | 2621 | opt=parse_file_outer(stdin); |
2592 | goto final_return; | 2622 | goto final_return; |
2593 | } | 2623 | } |