diff options
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/lash.c | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/shell/lash.c b/shell/lash.c index 3675d21df..a98aebdf5 100644 --- a/shell/lash.c +++ b/shell/lash.c | |||
| @@ -57,7 +57,8 @@ | |||
| 57 | #define expand_t glob_t | 57 | #define expand_t glob_t |
| 58 | 58 | ||
| 59 | /* Always enable for the moment... */ | 59 | /* Always enable for the moment... */ |
| 60 | #define CONFIG_LASH_PIPE_N_REDIRECTS | 60 | //#define CONFIG_LASH_PIPE_N_REDIRECTS |
| 61 | //#define CONFIG_LASH_JOB_CONTROL | ||
| 61 | 62 | ||
| 62 | static const int MAX_READ = 128; /* size of input buffer for `read' builtin */ | 63 | static const int MAX_READ = 128; /* size of input buffer for `read' builtin */ |
| 63 | #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n" | 64 | #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n" |
| @@ -192,7 +193,6 @@ static int last_return_code; | |||
| 192 | static int last_bg_pid; | 193 | static int last_bg_pid; |
| 193 | static unsigned int last_jobid; | 194 | static unsigned int last_jobid; |
| 194 | static int shell_terminal; | 195 | static int shell_terminal; |
| 195 | static pid_t shell_pgrp; | ||
| 196 | static char *PS1; | 196 | static char *PS1; |
| 197 | static char *PS2 = "> "; | 197 | static char *PS2 = "> "; |
| 198 | 198 | ||
| @@ -513,6 +513,7 @@ static void close_all() | |||
| 513 | } | 513 | } |
| 514 | 514 | ||
| 515 | 515 | ||
| 516 | #ifdef CONFIG_LASH_JOB_CONTROL | ||
| 516 | /* free up all memory from a job */ | 517 | /* free up all memory from a job */ |
| 517 | static void free_job(struct job *cmd) | 518 | static void free_job(struct job *cmd) |
| 518 | { | 519 | { |
| @@ -609,6 +610,17 @@ static void checkjobs(struct jobset *j_list) | |||
| 609 | if (childpid == -1 && errno != ECHILD) | 610 | if (childpid == -1 && errno != ECHILD) |
| 610 | bb_perror_msg("waitpid"); | 611 | bb_perror_msg("waitpid"); |
| 611 | } | 612 | } |
| 613 | #else | ||
| 614 | static void checkjobs(struct jobset *j_list) | ||
| 615 | { | ||
| 616 | } | ||
| 617 | static void free_job(struct job *cmd) | ||
| 618 | { | ||
| 619 | } | ||
| 620 | static void remove_job(struct jobset *j_list, struct job *job) | ||
| 621 | { | ||
| 622 | } | ||
| 623 | #endif | ||
| 612 | 624 | ||
| 613 | #ifdef CONFIG_LASH_PIPE_N_REDIRECTS | 625 | #ifdef CONFIG_LASH_PIPE_N_REDIRECTS |
| 614 | /* squirrel != NULL means we squirrel away copies of stdin, stdout, | 626 | /* squirrel != NULL means we squirrel away copies of stdin, stdout, |
| @@ -1171,8 +1183,10 @@ static int parse_command(char **command_ptr, struct job *job, int *inbg) | |||
| 1171 | break; | 1183 | break; |
| 1172 | #endif | 1184 | #endif |
| 1173 | 1185 | ||
| 1186 | #ifdef CONFIG_LASH_JOB_CONTROL | ||
| 1174 | case '&': /* background */ | 1187 | case '&': /* background */ |
| 1175 | *inbg = 1; | 1188 | *inbg = 1; |
| 1189 | #endif | ||
| 1176 | case ';': /* multiple commands */ | 1190 | case ';': /* multiple commands */ |
| 1177 | done = 1; | 1191 | done = 1; |
| 1178 | return_command = *command_ptr + (src - *command_ptr) + 1; | 1192 | return_command = *command_ptr + (src - *command_ptr) + 1; |
| @@ -1312,6 +1326,7 @@ static void insert_job(struct job *newjob, int inbg) | |||
| 1312 | thejob->running_progs = thejob->num_progs; | 1326 | thejob->running_progs = thejob->num_progs; |
| 1313 | thejob->stopped_progs = 0; | 1327 | thejob->stopped_progs = 0; |
| 1314 | 1328 | ||
| 1329 | #ifdef CONFIG_LASH_JOB_CONTROL | ||
| 1315 | if (inbg) { | 1330 | if (inbg) { |
| 1316 | /* we don't wait for background thejobs to return -- append it | 1331 | /* we don't wait for background thejobs to return -- append it |
| 1317 | to the list of backgrounded thejobs and leave it alone */ | 1332 | to the list of backgrounded thejobs and leave it alone */ |
| @@ -1327,6 +1342,7 @@ static void insert_job(struct job *newjob, int inbg) | |||
| 1327 | if (tcsetpgrp(shell_terminal, newjob->pgrp) && errno != ENOTTY) | 1342 | if (tcsetpgrp(shell_terminal, newjob->pgrp) && errno != ENOTTY) |
| 1328 | bb_perror_msg("tcsetpgrp"); | 1343 | bb_perror_msg("tcsetpgrp"); |
| 1329 | } | 1344 | } |
| 1345 | #endif | ||
| 1330 | } | 1346 | } |
| 1331 | 1347 | ||
| 1332 | static int run_command(struct job *newjob, int inbg, int outpipe[2]) | 1348 | static int run_command(struct job *newjob, int inbg, int outpipe[2]) |
| @@ -1438,15 +1454,17 @@ static int busy_loop(FILE * input) | |||
| 1438 | char *command; | 1454 | char *command; |
| 1439 | char *next_command = NULL; | 1455 | char *next_command = NULL; |
| 1440 | struct job newjob; | 1456 | struct job newjob; |
| 1441 | pid_t parent_pgrp; | ||
| 1442 | int i; | 1457 | int i; |
| 1443 | int inbg; | 1458 | int inbg; |
| 1444 | int status; | 1459 | int status; |
| 1445 | newjob.job_list = &job_list; | 1460 | newjob.job_list = &job_list; |
| 1446 | newjob.job_context = DEFAULT_CONTEXT; | 1461 | newjob.job_context = DEFAULT_CONTEXT; |
| 1462 | #ifdef CONFIG_LASH_JOB_CONTROL | ||
| 1463 | pid_t parent_pgrp; | ||
| 1447 | 1464 | ||
| 1448 | /* save current owner of TTY so we can restore it on exit */ | 1465 | /* save current owner of TTY so we can restore it on exit */ |
| 1449 | parent_pgrp = tcgetpgrp(shell_terminal); | 1466 | parent_pgrp = tcgetpgrp(shell_terminal); |
| 1467 | #endif | ||
| 1450 | 1468 | ||
| 1451 | command = (char *) xcalloc(BUFSIZ, sizeof(char)); | 1469 | command = (char *) xcalloc(BUFSIZ, sizeof(char)); |
| 1452 | 1470 | ||
| @@ -1506,7 +1524,9 @@ static int busy_loop(FILE * input) | |||
| 1506 | remove_job(&job_list, job_list.fg); | 1524 | remove_job(&job_list, job_list.fg); |
| 1507 | job_list.fg = NULL; | 1525 | job_list.fg = NULL; |
| 1508 | } | 1526 | } |
| 1509 | } else { | 1527 | } |
| 1528 | #ifdef CONFIG_LASH_JOB_CONTROL | ||
| 1529 | else { | ||
| 1510 | /* the child was stopped */ | 1530 | /* the child was stopped */ |
| 1511 | job_list.fg->stopped_progs++; | 1531 | job_list.fg->stopped_progs++; |
| 1512 | job_list.fg->progs[i].is_stopped = 1; | 1532 | job_list.fg->progs[i].is_stopped = 1; |
| @@ -1524,13 +1544,16 @@ static int busy_loop(FILE * input) | |||
| 1524 | if (tcsetpgrp(shell_terminal, getpgrp()) && errno != ENOTTY) | 1544 | if (tcsetpgrp(shell_terminal, getpgrp()) && errno != ENOTTY) |
| 1525 | bb_perror_msg("tcsetpgrp"); | 1545 | bb_perror_msg("tcsetpgrp"); |
| 1526 | } | 1546 | } |
| 1547 | #endif | ||
| 1527 | } | 1548 | } |
| 1528 | } | 1549 | } |
| 1529 | free(command); | 1550 | free(command); |
| 1530 | 1551 | ||
| 1552 | #ifdef CONFIG_LASH_JOB_CONTROL | ||
| 1531 | /* return controlling TTY back to parent process group before exiting */ | 1553 | /* return controlling TTY back to parent process group before exiting */ |
| 1532 | if (tcsetpgrp(shell_terminal, parent_pgrp) && errno != ENOTTY) | 1554 | if (tcsetpgrp(shell_terminal, parent_pgrp) && errno != ENOTTY) |
| 1533 | bb_perror_msg("tcsetpgrp"); | 1555 | bb_perror_msg("tcsetpgrp"); |
| 1556 | #endif | ||
| 1534 | 1557 | ||
| 1535 | /* return exit status if called with "-c" */ | 1558 | /* return exit status if called with "-c" */ |
| 1536 | if (input == NULL && WIFEXITED(status)) | 1559 | if (input == NULL && WIFEXITED(status)) |
| @@ -1539,7 +1562,6 @@ static int busy_loop(FILE * input) | |||
| 1539 | return 0; | 1562 | return 0; |
| 1540 | } | 1563 | } |
| 1541 | 1564 | ||
| 1542 | |||
| 1543 | #ifdef CONFIG_FEATURE_CLEAN_UP | 1565 | #ifdef CONFIG_FEATURE_CLEAN_UP |
| 1544 | void free_memory(void) | 1566 | void free_memory(void) |
| 1545 | { | 1567 | { |
| @@ -1555,12 +1577,14 @@ void free_memory(void) | |||
| 1555 | } | 1577 | } |
| 1556 | #endif | 1578 | #endif |
| 1557 | 1579 | ||
| 1580 | #ifdef CONFIG_LASH_JOB_CONTROL | ||
| 1558 | /* Make sure we have a controlling tty. If we get started under a job | 1581 | /* Make sure we have a controlling tty. If we get started under a job |
| 1559 | * aware app (like bash for example), make sure we are now in charge so | 1582 | * aware app (like bash for example), make sure we are now in charge so |
| 1560 | * we don't fight over who gets the foreground */ | 1583 | * we don't fight over who gets the foreground */ |
| 1561 | static void setup_job_control(void) | 1584 | static void setup_job_control(void) |
| 1562 | { | 1585 | { |
| 1563 | int status; | 1586 | int status; |
| 1587 | pid_t shell_pgrp; | ||
| 1564 | 1588 | ||
| 1565 | /* Loop until we are in the foreground. */ | 1589 | /* Loop until we are in the foreground. */ |
| 1566 | while ((status = tcgetpgrp (shell_terminal)) >= 0) { | 1590 | while ((status = tcgetpgrp (shell_terminal)) >= 0) { |
| @@ -1586,6 +1610,11 @@ static void setup_job_control(void) | |||
| 1586 | /* Grab control of the terminal. */ | 1610 | /* Grab control of the terminal. */ |
| 1587 | tcsetpgrp(shell_terminal, shell_pgrp); | 1611 | tcsetpgrp(shell_terminal, shell_pgrp); |
| 1588 | } | 1612 | } |
| 1613 | #else | ||
| 1614 | static inline void setup_job_control(void) | ||
| 1615 | { | ||
| 1616 | } | ||
| 1617 | #endif | ||
| 1589 | 1618 | ||
| 1590 | int lash_main(int argc_l, char **argv_l) | 1619 | int lash_main(int argc_l, char **argv_l) |
| 1591 | { | 1620 | { |
| @@ -1647,7 +1676,7 @@ int lash_main(int argc_l, char **argv_l) | |||
| 1647 | if (interactive==TRUE) { | 1676 | if (interactive==TRUE) { |
| 1648 | //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]); | 1677 | //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]); |
| 1649 | /* Looks like they want an interactive shell */ | 1678 | /* Looks like they want an interactive shell */ |
| 1650 | #ifndef CONFIG_FEATURE_SH_EXTRA_QUIET | 1679 | #ifndef CONFIG_FEATURE_SH_EXTRA_QUIET |
| 1651 | printf( "\n\n" BB_BANNER " Built-in shell (lash)\n"); | 1680 | printf( "\n\n" BB_BANNER " Built-in shell (lash)\n"); |
| 1652 | printf( "Enter 'help' for a list of built-in commands.\n\n"); | 1681 | printf( "Enter 'help' for a list of built-in commands.\n\n"); |
| 1653 | #endif | 1682 | #endif |
