summaryrefslogtreecommitdiff
path: root/shell/hush.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-04-21 23:27:30 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-04-21 23:27:30 +0000
commit1359da6ac7f7f44f82d224e61cc2c6ecb58baeef (patch)
tree0fce9fa95cef2293e24a5626a88b60c59b11a865 /shell/hush.c
parent762d35c75fe7001847adf85b5cf8279d53f627d7 (diff)
downloadbusybox-w32-1359da6ac7f7f44f82d224e61cc2c6ecb58baeef.tar.gz
busybox-w32-1359da6ac7f7f44f82d224e61cc2c6ecb58baeef.tar.bz2
busybox-w32-1359da6ac7f7f44f82d224e61cc2c6ecb58baeef.zip
hush: make Ctrl-Z work (at least sometimes)
Diffstat (limited to 'shell/hush.c')
-rw-r--r--shell/hush.c400
1 files changed, 224 insertions, 176 deletions
diff --git a/shell/hush.c b/shell/hush.c
index b367a08b2..e2ce3676d 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -82,7 +82,9 @@
82#include <getopt.h> /* should be pretty obvious */ 82#include <getopt.h> /* should be pretty obvious */
83 83
84/* #include <dmalloc.h> */ 84/* #include <dmalloc.h> */
85/* #define DEBUG_SHELL */ 85//#define DEBUG_SHELL
86/* Finer-grained debug switch */
87//#define DEBUG_SHELL_JOBS
86 88
87 89
88#define SPECIAL_VAR_SYMBOL 03 90#define SPECIAL_VAR_SYMBOL 03
@@ -274,9 +276,9 @@ struct in_str {
274#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n" 276#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
275 277
276struct built_in_command { 278struct built_in_command {
277 const char *cmd; /* name */ 279 const char *cmd; /* name */
278 const char *descr; /* description */ 280 const char *descr; /* description */
279 int (*function) (struct child_prog *); /* function ptr */ 281 int (*function) (char **argv); /* function ptr */
280}; 282};
281 283
282/* belongs in busybox.h */ 284/* belongs in busybox.h */
@@ -285,24 +287,24 @@ static int max(int a, int b)
285 return (a > b) ? a : b; 287 return (a > b) ? a : b;
286} 288}
287 289
288/* This should be in utility.c */
289#ifdef DEBUG_SHELL 290#ifdef DEBUG_SHELL
290static void debug_printf(const char *format, ...) 291#define debug_printf(...) fprintf(stderr, __VA_ARGS__)
291{
292 va_list args;
293 va_start(args, format);
294 vfprintf(stderr, format, args);
295 va_end(args);
296}
297/* broken, of course, but OK for testing */ 292/* broken, of course, but OK for testing */
298static char *indenter(int i) 293static char *indenter(int i)
299{ 294{
300 static char blanks[] = " "; 295 static char blanks[] = " ";
301 return &blanks[sizeof(blanks)-i-1]; 296 return &blanks[sizeof(blanks) - i - 1];
302} 297}
303#else 298#else
304#define debug_printf(...) do {} while (0) 299#define debug_printf(...) do {} while (0)
305#endif 300#endif
301
302#ifdef DEBUG_SHELL_JOBS
303#define debug_jobs_printf(...) fprintf(stderr, __VA_ARGS__)
304#else
305#define debug_jobs_printf(...) do {} while (0)
306#endif
307
306#define final_printf debug_printf 308#define final_printf debug_printf
307 309
308static void __syntax(const char *file, int line) 310static void __syntax(const char *file, int line)
@@ -314,23 +316,23 @@ static void __syntax(const char *file, int line)
314 316
315/* Index of subroutines: */ 317/* Index of subroutines: */
316/* function prototypes for builtins */ 318/* function prototypes for builtins */
317static int builtin_cd(struct child_prog *child); 319static int builtin_cd(char **argv);
318static int builtin_env(struct child_prog *child); 320static int builtin_env(char **argv);
319static int builtin_eval(struct child_prog *child); 321static int builtin_eval(char **argv);
320static int builtin_exec(struct child_prog *child); 322static int builtin_exec(char **argv);
321static int builtin_exit(struct child_prog *child); 323static int builtin_exit(char **argv);
322static int builtin_export(struct child_prog *child); 324static int builtin_export(char **argv);
323static int builtin_fg_bg(struct child_prog *child); 325static int builtin_fg_bg(char **argv);
324static int builtin_help(struct child_prog *child); 326static int builtin_help(char **argv);
325static int builtin_jobs(struct child_prog *child); 327static int builtin_jobs(char **argv);
326static int builtin_pwd(struct child_prog *child); 328static int builtin_pwd(char **argv);
327static int builtin_read(struct child_prog *child); 329static int builtin_read(char **argv);
328static int builtin_set(struct child_prog *child); 330static int builtin_set(char **argv);
329static int builtin_shift(struct child_prog *child); 331static int builtin_shift(char **argv);
330static int builtin_source(struct child_prog *child); 332static int builtin_source(char **argv);
331static int builtin_umask(struct child_prog *child); 333static int builtin_umask(char **argv);
332static int builtin_unset(struct child_prog *child); 334static int builtin_unset(char **argv);
333static int builtin_not_written(struct child_prog *child); 335static int builtin_not_written(char **argv);
334/* o_string manipulation: */ 336/* o_string manipulation: */
335static int b_check_space(o_string *o, int len); 337static int b_check_space(o_string *o, int len);
336static int b_addchr(o_string *o, int ch); 338static int b_addchr(o_string *o, int ch);
@@ -354,6 +356,7 @@ static int free_pipe(struct pipe *pi, int indent);
354/* really run the final data structures: */ 356/* really run the final data structures: */
355static int setup_redirects(struct child_prog *prog, int squirrel[]); 357static int setup_redirects(struct child_prog *prog, int squirrel[]);
356static int run_list_real(struct pipe *pi); 358static int run_list_real(struct pipe *pi);
359static void pseudo_exec_argv(char **argv) ATTRIBUTE_NORETURN;
357static void pseudo_exec(struct child_prog *child) ATTRIBUTE_NORETURN; 360static void pseudo_exec(struct child_prog *child) ATTRIBUTE_NORETURN;
358static int run_pipe_real(struct pipe *pi); 361static int run_pipe_real(struct pipe *pi);
359/* extended glob support: */ 362/* extended glob support: */
@@ -387,6 +390,7 @@ static int checkjobs(struct pipe* fg_pipe);
387static int checkjobs_and_fg_shell(struct pipe* fg_pipe); 390static int checkjobs_and_fg_shell(struct pipe* fg_pipe);
388static void insert_bg_job(struct pipe *pi); 391static void insert_bg_job(struct pipe *pi);
389static void remove_bg_job(struct pipe *pi); 392static void remove_bg_job(struct pipe *pi);
393static void delete_finished_bg_job(struct pipe *pi);
390/* local variable support */ 394/* local variable support */
391static char **make_list_in(char **inp, char *name); 395static char **make_list_in(char **inp, char *name);
392static char *insert_var_value(char *inp); 396static char *insert_var_value(char *inp);
@@ -503,18 +507,14 @@ static const char *set_cwd(void)
503 return cwd; 507 return cwd;
504} 508}
505 509
506// It seems ALL built-ins ever use *only* child->argv in child param.
507// Passing argv directly may make 'child->argv += n' modifications
508// unneeded on vfork codepaths.
509
510/* built-in 'eval' handler */ 510/* built-in 'eval' handler */
511static int builtin_eval(struct child_prog *child) 511static int builtin_eval(char **argv)
512{ 512{
513 char *str = NULL; 513 char *str = NULL;
514 int rcode = EXIT_SUCCESS; 514 int rcode = EXIT_SUCCESS;
515 515
516 if (child->argv[1]) { 516 if (argv[1]) {
517 str = make_string(child->argv + 1); 517 str = make_string(argv + 1);
518 parse_string_outer(str, FLAG_EXIT_FROM_LOOP | 518 parse_string_outer(str, FLAG_EXIT_FROM_LOOP |
519 FLAG_PARSE_SEMICOLON); 519 FLAG_PARSE_SEMICOLON);
520 free(str); 520 free(str);
@@ -524,13 +524,13 @@ static int builtin_eval(struct child_prog *child)
524} 524}
525 525
526/* built-in 'cd <path>' handler */ 526/* built-in 'cd <path>' handler */
527static int builtin_cd(struct child_prog *child) 527static int builtin_cd(char **argv)
528{ 528{
529 char *newdir; 529 char *newdir;
530 if (child->argv[1] == NULL) 530 if (argv[1] == NULL)
531 newdir = getenv("HOME"); 531 newdir = getenv("HOME");
532 else 532 else
533 newdir = child->argv[1]; 533 newdir = argv[1];
534 if (chdir(newdir)) { 534 if (chdir(newdir)) {
535 printf("cd: %s: %s\n", newdir, strerror(errno)); 535 printf("cd: %s: %s\n", newdir, strerror(errno));
536 return EXIT_FAILURE; 536 return EXIT_FAILURE;
@@ -540,7 +540,7 @@ static int builtin_cd(struct child_prog *child)
540} 540}
541 541
542/* built-in 'env' handler */ 542/* built-in 'env' handler */
543static int builtin_env(struct child_prog *dummy ATTRIBUTE_UNUSED) 543static int builtin_env(char **argv ATTRIBUTE_UNUSED)
544{ 544{
545/* TODO: call env applet's code instead */ 545/* TODO: call env applet's code instead */
546 char **e = environ; 546 char **e = environ;
@@ -553,37 +553,36 @@ static int builtin_env(struct child_prog *dummy ATTRIBUTE_UNUSED)
553} 553}
554 554
555/* built-in 'exec' handler */ 555/* built-in 'exec' handler */
556static int builtin_exec(struct child_prog *child) 556static int builtin_exec(char **argv)
557{ 557{
558 if (child->argv[1] == NULL) 558 if (argv[1] == NULL)
559 return EXIT_SUCCESS; /* Really? */ 559 return EXIT_SUCCESS; /* Really? */
560 child->argv++; 560 pseudo_exec_argv(argv + 1);
561 pseudo_exec(child);
562 /* never returns */ 561 /* never returns */
563} 562}
564 563
565/* built-in 'exit' handler */ 564/* built-in 'exit' handler */
566static int builtin_exit(struct child_prog *child) 565static int builtin_exit(char **argv)
567{ 566{
568// TODO: bash does it ONLY on top-level sh exit (+interacive only?) 567// TODO: bash does it ONLY on top-level sh exit (+interacive only?)
569 //puts("exit"); /* bash does it */ 568 //puts("exit"); /* bash does it */
570 569
571 if (child->argv[1] == NULL) 570 if (argv[1] == NULL)
572 hush_exit(last_return_code); 571 hush_exit(last_return_code);
573 /* mimic bash: exit 123abc == exit 255 + error msg */ 572 /* mimic bash: exit 123abc == exit 255 + error msg */
574 xfunc_error_retval = 255; 573 xfunc_error_retval = 255;
575 /* bash: exit -2 == exit 254, no error msg */ 574 /* bash: exit -2 == exit 254, no error msg */
576 hush_exit(xatoi(child->argv[1])); 575 hush_exit(xatoi(argv[1]));
577} 576}
578 577
579/* built-in 'export VAR=value' handler */ 578/* built-in 'export VAR=value' handler */
580static int builtin_export(struct child_prog *child) 579static int builtin_export(char **argv)
581{ 580{
582 int res = 0; 581 int res = 0;
583 char *name = child->argv[1]; 582 char *name = argv[1];
584 583
585 if (name == NULL) { 584 if (name == NULL) {
586 return builtin_env(child); 585 return builtin_env(argv);
587 } 586 }
588 587
589 name = strdup(name); 588 name = strdup(name);
@@ -624,7 +623,7 @@ static int builtin_export(struct child_prog *child)
624} 623}
625 624
626/* built-in 'fg' and 'bg' handler */ 625/* built-in 'fg' and 'bg' handler */
627static int builtin_fg_bg(struct child_prog *child) 626static int builtin_fg_bg(char **argv)
628{ 627{
629 int i, jobnum; 628 int i, jobnum;
630 struct pipe *pi; 629 struct pipe *pi;
@@ -632,17 +631,17 @@ static int builtin_fg_bg(struct child_prog *child)
632 if (!interactive_fd) 631 if (!interactive_fd)
633 return EXIT_FAILURE; 632 return EXIT_FAILURE;
634 /* If they gave us no args, assume they want the last backgrounded task */ 633 /* If they gave us no args, assume they want the last backgrounded task */
635 if (!child->argv[1]) { 634 if (!argv[1]) {
636 for (pi = job_list; pi; pi = pi->next) { 635 for (pi = job_list; pi; pi = pi->next) {
637 if (pi->jobid == last_jobid) { 636 if (pi->jobid == last_jobid) {
638 goto found; 637 goto found;
639 } 638 }
640 } 639 }
641 bb_error_msg("%s: no current job", child->argv[0]); 640 bb_error_msg("%s: no current job", argv[0]);
642 return EXIT_FAILURE; 641 return EXIT_FAILURE;
643 } 642 }
644 if (sscanf(child->argv[1], "%%%d", &jobnum) != 1) { 643 if (sscanf(argv[1], "%%%d", &jobnum) != 1) {
645 bb_error_msg("%s: bad argument '%s'", child->argv[0], child->argv[1]); 644 bb_error_msg("%s: bad argument '%s'", argv[0], argv[1]);
646 return EXIT_FAILURE; 645 return EXIT_FAILURE;
647 } 646 }
648 for (pi = job_list; pi; pi = pi->next) { 647 for (pi = job_list; pi; pi = pi->next) {
@@ -650,37 +649,42 @@ static int builtin_fg_bg(struct child_prog *child)
650 goto found; 649 goto found;
651 } 650 }
652 } 651 }
653 bb_error_msg("%s: %d: no such job", child->argv[0], jobnum); 652 bb_error_msg("%s: %d: no such job", argv[0], jobnum);
654 return EXIT_FAILURE; 653 return EXIT_FAILURE;
655 found: 654 found:
656 // TODO: bash prints a string representation 655 // TODO: bash prints a string representation
657 // of job being foregrounded (like "sleep 1 | cat") 656 // of job being foregrounded (like "sleep 1 | cat")
658 if (*child->argv[0] == 'f') { 657 if (*argv[0] == 'f') {
659 /* Put the job into the foreground. */ 658 /* Put the job into the foreground. */
660 tcsetpgrp(interactive_fd, pi->pgrp); 659 tcsetpgrp(interactive_fd, pi->pgrp);
661 } 660 }
662 661
663 /* Restart the processes in the job */ 662 /* Restart the processes in the job */
664 for (i = 0; i < pi->num_progs; i++) 663 debug_jobs_printf("reviving %d procs, pgrp %d\n", pi->num_progs, pi->pgrp);
664 for (i = 0; i < pi->num_progs; i++) {
665 debug_jobs_printf("reviving pid %d\n", pi->progs[i].pid);
665 pi->progs[i].is_stopped = 0; 666 pi->progs[i].is_stopped = 0;
667 }
668 pi->stopped_progs = 0;
666 669
667 i = kill(- pi->pgrp, SIGCONT); 670 i = kill(- pi->pgrp, SIGCONT);
668 pi->stopped_progs = 0;
669 if (i < 0) { 671 if (i < 0) {
670 if (errno == ESRCH) { 672 if (errno == ESRCH) {
671 remove_bg_job(pi); 673 delete_finished_bg_job(pi);
672 } else { 674 } else {
673 bb_perror_msg("kill (SIGCONT)"); 675 bb_perror_msg("kill (SIGCONT)");
674 } 676 }
675 } 677 }
676 678
677 if (*child->argv[0] == 'f') 679 if (*argv[0] == 'f') {
680 remove_bg_job(pi);
678 return checkjobs_and_fg_shell(pi); 681 return checkjobs_and_fg_shell(pi);
682 }
679 return EXIT_SUCCESS; 683 return EXIT_SUCCESS;
680} 684}
681 685
682/* built-in 'help' handler */ 686/* built-in 'help' handler */
683static int builtin_help(struct child_prog *dummy ATTRIBUTE_UNUSED) 687static int builtin_help(char **argv ATTRIBUTE_UNUSED)
684{ 688{
685 const struct built_in_command *x; 689 const struct built_in_command *x;
686 690
@@ -696,7 +700,7 @@ static int builtin_help(struct child_prog *dummy ATTRIBUTE_UNUSED)
696} 700}
697 701
698/* built-in 'jobs' handler */ 702/* built-in 'jobs' handler */
699static int builtin_jobs(struct child_prog *child ATTRIBUTE_UNUSED) 703static int builtin_jobs(char **argv ATTRIBUTE_UNUSED)
700{ 704{
701 struct pipe *job; 705 struct pipe *job;
702 const char *status_string; 706 const char *status_string;
@@ -713,18 +717,18 @@ static int builtin_jobs(struct child_prog *child ATTRIBUTE_UNUSED)
713} 717}
714 718
715/* built-in 'pwd' handler */ 719/* built-in 'pwd' handler */
716static int builtin_pwd(struct child_prog *dummy ATTRIBUTE_UNUSED) 720static int builtin_pwd(char **argv ATTRIBUTE_UNUSED)
717{ 721{
718 puts(set_cwd()); 722 puts(set_cwd());
719 return EXIT_SUCCESS; 723 return EXIT_SUCCESS;
720} 724}
721 725
722/* built-in 'read VAR' handler */ 726/* built-in 'read VAR' handler */
723static int builtin_read(struct child_prog *child) 727static int builtin_read(char **argv)
724{ 728{
725 int res; 729 int res;
726 730
727 if (child->argv[1]) { 731 if (argv[1]) {
728 char string[BUFSIZ]; 732 char string[BUFSIZ];
729 char *var = NULL; 733 char *var = NULL;
730 734
@@ -732,9 +736,9 @@ static int builtin_read(struct child_prog *child)
732 /* read string */ 736 /* read string */
733 fgets(string, sizeof(string), stdin); 737 fgets(string, sizeof(string), stdin);
734 chomp(string); 738 chomp(string);
735 var = malloc(strlen(child->argv[1]) + strlen(string) + 2); 739 var = malloc(strlen(argv[1]) + strlen(string) + 2);
736 if (var) { 740 if (var) {
737 sprintf(var, "%s=%s", child->argv[1], string); 741 sprintf(var, "%s=%s", argv[1], string);
738 res = set_local_var(var, 0); 742 res = set_local_var(var, 0);
739 } else 743 } else
740 res = -1; 744 res = -1;
@@ -748,9 +752,9 @@ static int builtin_read(struct child_prog *child)
748} 752}
749 753
750/* built-in 'set VAR=value' handler */ 754/* built-in 'set VAR=value' handler */
751static int builtin_set(struct child_prog *child) 755static int builtin_set(char **argv)
752{ 756{
753 char *temp = child->argv[1]; 757 char *temp = argv[1];
754 struct variables *e; 758 struct variables *e;
755 759
756 if (temp == NULL) 760 if (temp == NULL)
@@ -764,11 +768,11 @@ static int builtin_set(struct child_prog *child)
764 768
765 769
766/* Built-in 'shift' handler */ 770/* Built-in 'shift' handler */
767static int builtin_shift(struct child_prog *child) 771static int builtin_shift(char **argv)
768{ 772{
769 int n = 1; 773 int n = 1;
770 if (child->argv[1]) { 774 if (argv[1]) {
771 n = atoi(child->argv[1]); 775 n = atoi(argv[1]);
772 } 776 }
773 if (n >= 0 && n < global_argc) { 777 if (n >= 0 && n < global_argc) {
774 /* XXX This probably breaks $0 */ 778 /* XXX This probably breaks $0 */
@@ -780,25 +784,25 @@ static int builtin_shift(struct child_prog *child)
780} 784}
781 785
782/* Built-in '.' handler (read-in and execute commands from file) */ 786/* Built-in '.' handler (read-in and execute commands from file) */
783static int builtin_source(struct child_prog *child) 787static int builtin_source(char **argv)
784{ 788{
785 FILE *input; 789 FILE *input;
786 int status; 790 int status;
787 791
788 if (child->argv[1] == NULL) 792 if (argv[1] == NULL)
789 return EXIT_FAILURE; 793 return EXIT_FAILURE;
790 794
791 /* XXX search through $PATH is missing */ 795 /* XXX search through $PATH is missing */
792 input = fopen(child->argv[1], "r"); 796 input = fopen(argv[1], "r");
793 if (!input) { 797 if (!input) {
794 bb_error_msg("cannot open '%s'", child->argv[1]); 798 bb_error_msg("cannot open '%s'", argv[1]);
795 return EXIT_FAILURE; 799 return EXIT_FAILURE;
796 } 800 }
797 801
798 /* Now run the file */ 802 /* Now run the file */
799 /* XXX argv and argc are broken; need to save old global_argv 803 /* XXX argv and argc are broken; need to save old global_argv
800 * (pointer only is OK!) on this stack frame, 804 * (pointer only is OK!) on this stack frame,
801 * set global_argv=child->argv+1, recurse, and restore. */ 805 * set global_argv=argv+1, recurse, and restore. */
802 mark_open(fileno(input)); 806 mark_open(fileno(input));
803 status = parse_file_outer(input); 807 status = parse_file_outer(input);
804 mark_closed(fileno(input)); 808 mark_closed(fileno(input));
@@ -806,10 +810,10 @@ static int builtin_source(struct child_prog *child)
806 return status; 810 return status;
807} 811}
808 812
809static int builtin_umask(struct child_prog *child) 813static int builtin_umask(char **argv)
810{ 814{
811 mode_t new_umask; 815 mode_t new_umask;
812 const char *arg = child->argv[1]; 816 const char *arg = argv[1];
813 char *end; 817 char *end;
814 if (arg) { 818 if (arg) {
815 new_umask = strtoul(arg, &end, 8); 819 new_umask = strtoul(arg, &end, 8);
@@ -825,16 +829,16 @@ static int builtin_umask(struct child_prog *child)
825} 829}
826 830
827/* built-in 'unset VAR' handler */ 831/* built-in 'unset VAR' handler */
828static int builtin_unset(struct child_prog *child) 832static int builtin_unset(char **argv)
829{ 833{
830 /* bash returned already true */ 834 /* bash returned already true */
831 unset_local_var(child->argv[1]); 835 unset_local_var(argv[1]);
832 return EXIT_SUCCESS; 836 return EXIT_SUCCESS;
833} 837}
834 838
835static int builtin_not_written(struct child_prog *child) 839static int builtin_not_written(char **argv)
836{ 840{
837 printf("builtin_%s not written\n", child->argv[0]); 841 printf("builtin_%s not written\n", argv[0]);
838 return EXIT_FAILURE; 842 return EXIT_FAILURE;
839} 843}
840 844
@@ -1132,68 +1136,71 @@ static void restore_redirects(int squirrel[])
1132/* XXX no exit() here. If you don't exec, use _exit instead. 1136/* XXX no exit() here. If you don't exec, use _exit instead.
1133 * The at_exit handlers apparently confuse the calling process, 1137 * The at_exit handlers apparently confuse the calling process,
1134 * in particular stdin handling. Not sure why? -- because of vfork! (vda) */ 1138 * in particular stdin handling. Not sure why? -- because of vfork! (vda) */
1135static void pseudo_exec(struct child_prog *child) 1139static void pseudo_exec_argv(char **argv)
1136{ 1140{
1137 int i, rcode; 1141 int i, rcode;
1138 char *p; 1142 char *p;
1139 const struct built_in_command *x; 1143 const struct built_in_command *x;
1140 1144
1141 if (child->argv) { 1145 for (i = 0; is_assignment(argv[i]); i++) {
1142 for (i = 0; is_assignment(child->argv[i]); i++) { 1146 debug_printf("pid %d environment modification: %s\n",
1143 debug_printf("pid %d environment modification: %s\n", 1147 getpid(), argv[i]);
1144 getpid(), child->argv[i]); 1148 // FIXME: vfork case??
1145 // FIXME: vfork case?? 1149 p = insert_var_value(argv[i]);
1146 p = insert_var_value(child->argv[i]); 1150 putenv(strdup(p));
1147 putenv(strdup(p)); 1151 if (p != argv[i])
1148 if (p != child->argv[i]) 1152 free(p);
1149 free(p); 1153 }
1150 } 1154 argv += i;
1151 child->argv += i; /* XXX this hack isn't so horrible, since we are about 1155 /* If a variable is assigned in a forest, and nobody listens,
1152 to exit, and therefore don't need to keep data 1156 * was it ever really set?
1153 structures consistent for free() use. */ 1157 */
1154 // FIXME: ...unless we have _vforked_! Think NOMMU! 1158 if (argv[0] == NULL) {
1155 1159 _exit(EXIT_SUCCESS);
1156 /* If a variable is assigned in a forest, and nobody listens, 1160 }
1157 * was it ever really set?
1158 */
1159 if (child->argv[0] == NULL) {
1160 _exit(EXIT_SUCCESS);
1161 }
1162
1163 /*
1164 * Check if the command matches any of the builtins.
1165 * Depending on context, this might be redundant. But it's
1166 * easier to waste a few CPU cycles than it is to figure out
1167 * if this is one of those cases.
1168 */
1169 for (x = bltins; x->cmd; x++) {
1170 if (strcmp(child->argv[0], x->cmd) == 0) {
1171 debug_printf("builtin exec %s\n", child->argv[0]);
1172 rcode = x->function(child);
1173 fflush(stdout);
1174 _exit(rcode);
1175 }
1176 }
1177 1161
1178 /* Check if the command matches any busybox internal commands 1162 /*
1179 * ("applets") here. 1163 * Check if the command matches any of the builtins.
1180 * FIXME: This feature is not 100% safe, since 1164 * Depending on context, this might be redundant. But it's
1181 * BusyBox is not fully reentrant, so we have no guarantee the things 1165 * easier to waste a few CPU cycles than it is to figure out
1182 * from the .bss are still zeroed, or that things from .data are still 1166 * if this is one of those cases.
1183 * at their defaults. We could exec ourself from /proc/self/exe, but I 1167 */
1184 * really dislike relying on /proc for things. We could exec ourself 1168 for (x = bltins; x->cmd; x++) {
1185 * from global_argv[0], but if we are in a chroot, we may not be able 1169 if (strcmp(argv[0], x->cmd) == 0) {
1186 * to find ourself... */ 1170 debug_printf("builtin exec %s\n", argv[0]);
1171 rcode = x->function(argv);
1172 fflush(stdout);
1173 _exit(rcode);
1174 }
1175 }
1176
1177 /* Check if the command matches any busybox internal commands
1178 * ("applets") here.
1179 * FIXME: This feature is not 100% safe, since
1180 * BusyBox is not fully reentrant, so we have no guarantee the things
1181 * from the .bss are still zeroed, or that things from .data are still
1182 * at their defaults. We could exec ourself from /proc/self/exe, but I
1183 * really dislike relying on /proc for things. We could exec ourself
1184 * from global_argv[0], but if we are in a chroot, we may not be able
1185 * to find ourself... */
1187#if ENABLE_FEATURE_SH_STANDALONE 1186#if ENABLE_FEATURE_SH_STANDALONE
1188 debug_printf("running applet %s\n", child->argv[0]); 1187 debug_printf("running applet %s\n", argv[0]);
1189 run_applet_and_exit(child->argv[0], child->argv); 1188 run_applet_and_exit(argv[0], argv);
1190// is it ok that run_applet_and_exit() does exit(), not _exit()? 1189// is it ok that run_applet_and_exit() does exit(), not _exit()?
1191// NB: IIRC on NOMMU we are after _vfork_, not fork! 1190// NB: IIRC on NOMMU we are after _vfork_, not fork!
1192#endif 1191#endif
1193 debug_printf("exec of %s\n", child->argv[0]); 1192 debug_printf("exec of %s\n", argv[0]);
1194 execvp(child->argv[0], child->argv); 1193 execvp(argv[0], argv);
1195 bb_perror_msg("cannot exec '%s'", child->argv[0]); 1194 bb_perror_msg("cannot exec '%s'", argv[0]);
1196 _exit(1); 1195 _exit(1);
1196}
1197
1198static void pseudo_exec(struct child_prog *child)
1199{
1200 int rcode;
1201
1202 if (child->argv) {
1203 pseudo_exec_argv(child->argv);
1197 } 1204 }
1198 1205
1199 if (child->group) { 1206 if (child->group) {
@@ -1233,13 +1240,17 @@ static void insert_bg_job(struct pipe *pi)
1233 1240
1234 /* physically copy the struct job */ 1241 /* physically copy the struct job */
1235 memcpy(thejob, pi, sizeof(struct pipe)); 1242 memcpy(thejob, pi, sizeof(struct pipe));
1243// (pi->num_progs+1) is one-too-many I think?
1244 thejob->progs = xmalloc(sizeof(pi->progs[0]) * (pi->num_progs+1));
1245 memcpy(thejob->progs, pi->progs, sizeof(pi->progs[0]) * (pi->num_progs+1));
1236 thejob->next = NULL; 1246 thejob->next = NULL;
1237 thejob->running_progs = thejob->num_progs; 1247 /*seems to be wrong:*/
1238 thejob->stopped_progs = 0; 1248 /*thejob->running_progs = thejob->num_progs;*/
1249 /*thejob->stopped_progs = 0;*/
1239 thejob->text = xmalloc(BUFSIZ); /* cmdedit buffer size */ 1250 thejob->text = xmalloc(BUFSIZ); /* cmdedit buffer size */
1240
1241 //if (pi->progs[0] && pi->progs[0].argv && pi->progs[0].argv[0]) 1251 //if (pi->progs[0] && pi->progs[0].argv && pi->progs[0].argv[0])
1242 { 1252 {
1253 // FIXME: overflow check? and also trim the size, BUFSIZ can be 4K!
1243 char *bar = thejob->text; 1254 char *bar = thejob->text;
1244 char **foo = pi->progs[0].argv; 1255 char **foo = pi->progs[0].argv;
1245 if (foo) 1256 if (foo)
@@ -1254,7 +1265,6 @@ static void insert_bg_job(struct pipe *pi)
1254 last_jobid = thejob->jobid; 1265 last_jobid = thejob->jobid;
1255} 1266}
1256 1267
1257/* remove a backgrounded job */
1258static void remove_bg_job(struct pipe *pi) 1268static void remove_bg_job(struct pipe *pi)
1259{ 1269{
1260 struct pipe *prev_pipe; 1270 struct pipe *prev_pipe;
@@ -1271,7 +1281,12 @@ static void remove_bg_job(struct pipe *pi)
1271 last_jobid = job_list->jobid; 1281 last_jobid = job_list->jobid;
1272 else 1282 else
1273 last_jobid = 0; 1283 last_jobid = 0;
1284}
1274 1285
1286/* remove a backgrounded job */
1287static void delete_finished_bg_job(struct pipe *pi)
1288{
1289 remove_bg_job(pi);
1275 pi->stopped_progs = 0; 1290 pi->stopped_progs = 0;
1276 free_pipe(pi, 0); 1291 free_pipe(pi, 0);
1277 free(pi); 1292 free(pi);
@@ -1289,36 +1304,67 @@ static int checkjobs(struct pipe* fg_pipe)
1289 int rcode = 0; 1304 int rcode = 0;
1290 1305
1291 attributes = WUNTRACED; 1306 attributes = WUNTRACED;
1292//WUNTRACED?? huh, what will happed on Ctrl-Z? fg waiting code
1293//doesn't seem to be ready for stopped children! (only exiting ones)...
1294 if (fg_pipe == NULL) { 1307 if (fg_pipe == NULL) {
1295 attributes |= WNOHANG; 1308 attributes |= WNOHANG;
1296 } 1309 }
1297 1310
1311/* Do we do this right?
1312 * bash-3.00# sleep 20 | false
1313 * <Ctrl-Z pressed>
1314 * [3]+ Stopped sleep 20 | false
1315 * bash-3.00# echo $?
1316 * 1 <========== bg pipe is not fully done, but exitcode is already known!
1317 */
1318
1298 wait_more: 1319 wait_more:
1299 while ((childpid = waitpid(-1, &status, attributes)) > 0) { 1320 while ((childpid = waitpid(-1, &status, attributes)) > 0) {
1321 const int dead = WIFEXITED(status) || WIFSIGNALED(status);
1322
1323#ifdef DEBUG_SHELL_JOBS
1324 if (WIFSTOPPED(status))
1325 debug_jobs_printf("pid %d stopped by sig %d (exitcode %d)\n",
1326 childpid, WSTOPSIG(status), WEXITSTATUS(status));
1327 if (WIFSIGNALED(status))
1328 debug_jobs_printf("pid %d killed by sig %d (exitcode %d)\n",
1329 childpid, WTERMSIG(status), WEXITSTATUS(status));
1330 if (WIFEXITED(status))
1331 debug_jobs_printf("pid %d exited, exitcode %d\n",
1332 childpid, WEXITSTATUS(status));
1333#endif
1300 /* Were we asked to wait for fg pipe? */ 1334 /* Were we asked to wait for fg pipe? */
1301 if (fg_pipe) { 1335 if (fg_pipe) {
1302 int i; 1336 int i;
1303 for (i = 0; i < fg_pipe->num_progs; i++) { 1337 for (i = 0; i < fg_pipe->num_progs; i++) {
1338 debug_jobs_printf("check pid %d\n", fg_pipe->progs[i].pid);
1304 if (fg_pipe->progs[i].pid == childpid) { 1339 if (fg_pipe->progs[i].pid == childpid) {
1305 /* printf("process %d exit %d\n", i, WEXITSTATUS(status)); */ 1340 /* printf("process %d exit %d\n", i, WEXITSTATUS(status)); */
1306 fg_pipe->progs[i].pid = 0; 1341 if (dead) {
1307 if (i == fg_pipe->num_progs-1) 1342 fg_pipe->progs[i].pid = 0;
1308 /* last process gives overall exitstatus */ 1343 fg_pipe->running_progs--;
1309 rcode = WEXITSTATUS(status); 1344 if (i == fg_pipe->num_progs-1)
1310 if (--fg_pipe->running_progs <= 0) 1345 /* last process gives overall exitstatus */
1311 /* All processes in fg pipe have exited */ 1346 rcode = WEXITSTATUS(status);
1347 } else {
1348 fg_pipe->progs[i].is_stopped = 1;
1349 fg_pipe->stopped_progs++;
1350 }
1351 debug_jobs_printf("fg_pipe: running_progs %d stopped_progs %d\n",
1352 fg_pipe->running_progs, fg_pipe->stopped_progs);
1353 if (fg_pipe->running_progs - fg_pipe->stopped_progs <= 0) {
1354 /* All processes in fg pipe have exited/stopped */
1355 if (fg_pipe->running_progs)
1356 insert_bg_job(fg_pipe);
1312 return rcode; 1357 return rcode;
1358 }
1313 /* There are still running processes in the fg pipe */ 1359 /* There are still running processes in the fg pipe */
1314 goto wait_more; 1360 goto wait_more;
1315 } 1361 }
1316 } 1362 }
1363 /* fall through to searching process in bg pipes */
1317 } 1364 }
1318 1365
1319 /* We asked to wait for bg or orphaned children */ 1366 /* We asked to wait for bg or orphaned children */
1320 /* No need to remember exitcode in this case */ 1367 /* No need to remember exitcode in this case */
1321
1322 for (pi = job_list; pi; pi = pi->next) { 1368 for (pi = job_list; pi; pi = pi->next) {
1323 prognum = 0; 1369 prognum = 0;
1324 while (prognum < pi->num_progs) { 1370 while (prognum < pi->num_progs) {
@@ -1330,18 +1376,17 @@ static int checkjobs(struct pipe* fg_pipe)
1330 1376
1331 /* Happens when shell is used as init process (init=/bin/sh) */ 1377 /* Happens when shell is used as init process (init=/bin/sh) */
1332 debug_printf("checkjobs: pid %d was not in our list!\n", childpid); 1378 debug_printf("checkjobs: pid %d was not in our list!\n", childpid);
1333 continue; 1379 goto wait_more;
1334 1380
1335 found_pi_and_prognum: 1381 found_pi_and_prognum:
1336 if (WIFEXITED(status) || WIFSIGNALED(status)) { 1382 if (dead) {
1337 /* child exited */ 1383 /* child exited */
1338 pi->running_progs--;
1339 pi->progs[prognum].pid = 0; 1384 pi->progs[prognum].pid = 0;
1340 1385 pi->running_progs--;
1341 if (!pi->running_progs) { 1386 if (!pi->running_progs) {
1342 printf(JOB_STATUS_FORMAT, pi->jobid, 1387 printf(JOB_STATUS_FORMAT, pi->jobid,
1343 "Done", pi->text); 1388 "Done", pi->text);
1344 remove_bg_job(pi); 1389 delete_finished_bg_job(pi);
1345 } 1390 }
1346 } else { 1391 } else {
1347 /* child stopped */ 1392 /* child stopped */
@@ -1350,7 +1395,9 @@ static int checkjobs(struct pipe* fg_pipe)
1350 } 1395 }
1351 } 1396 }
1352 1397
1353 if (childpid == -1 && errno != ECHILD) 1398 /* wait found no children or failed */
1399
1400 if (childpid && errno != ECHILD)
1354 bb_perror_msg("waitpid"); 1401 bb_perror_msg("waitpid");
1355 1402
1356 /* move the shell to the foreground */ 1403 /* move the shell to the foreground */
@@ -1402,6 +1449,8 @@ static int run_pipe_real(struct pipe *pi)
1402 1449
1403 nextin = 0; 1450 nextin = 0;
1404 pi->pgrp = -1; 1451 pi->pgrp = -1;
1452 pi->running_progs = 0;
1453 pi->stopped_progs = 0;
1405 1454
1406 /* Check if this is a simple builtin (not part of a pipe). 1455 /* Check if this is a simple builtin (not part of a pipe).
1407 * Builtins within pipes have to fork anyway, and are handled in 1456 * Builtins within pipes have to fork anyway, and are handled in
@@ -1418,12 +1467,14 @@ static int run_pipe_real(struct pipe *pi)
1418 return rcode; 1467 return rcode;
1419 } 1468 }
1420 1469
1421 if (single_fg && pi->progs[0].argv != NULL) { 1470 if (single_fg && child->argv != NULL) {
1422 for (i = 0; is_assignment(child->argv[i]); i++) 1471 char **argv = child->argv;
1472
1473 for (i = 0; is_assignment(argv[i]); i++)
1423 continue; 1474 continue;
1424 if (i != 0 && child->argv[i] == NULL) { 1475 if (i != 0 && argv[i] == NULL) {
1425 /* assignments, but no command: set the local environment */ 1476 /* assignments, but no command: set the local environment */
1426 for (i = 0; child->argv[i] != NULL; i++) { 1477 for (i = 0; argv[i] != NULL; i++) {
1427 /* Ok, this case is tricky. We have to decide if this is a 1478 /* Ok, this case is tricky. We have to decide if this is a
1428 * local variable, or an already exported variable. If it is 1479 * local variable, or an already exported variable. If it is
1429 * already exported, we have to export the new value. If it is 1480 * already exported, we have to export the new value. If it is
@@ -1432,7 +1483,7 @@ static int run_pipe_real(struct pipe *pi)
1432 * variable. */ 1483 * variable. */
1433 int export_me = 0; 1484 int export_me = 0;
1434 char *name, *value; 1485 char *name, *value;
1435 name = xstrdup(child->argv[i]); 1486 name = xstrdup(argv[i]);
1436 debug_printf("Local environment set: %s\n", name); 1487 debug_printf("Local environment set: %s\n", name);
1437 value = strchr(name, '='); 1488 value = strchr(name, '=');
1438 if (value) 1489 if (value)
@@ -1441,17 +1492,17 @@ static int run_pipe_real(struct pipe *pi)
1441 export_me = 1; 1492 export_me = 1;
1442 } 1493 }
1443 free(name); 1494 free(name);
1444 p = insert_var_value(child->argv[i]); 1495 p = insert_var_value(argv[i]);
1445 set_local_var(p, export_me); 1496 set_local_var(p, export_me);
1446 if (p != child->argv[i]) 1497 if (p != argv[i])
1447 free(p); 1498 free(p);
1448 } 1499 }
1449 return EXIT_SUCCESS; /* don't worry about errors in set_local_var() yet */ 1500 return EXIT_SUCCESS; /* don't worry about errors in set_local_var() yet */
1450 } 1501 }
1451 for (i = 0; is_assignment(child->argv[i]); i++) { 1502 for (i = 0; is_assignment(argv[i]); i++) {
1452 p = insert_var_value(child->argv[i]); 1503 p = insert_var_value(argv[i]);
1453 putenv(strdup(p)); 1504 putenv(strdup(p));
1454 if (p != child->argv[i]) { 1505 if (p != argv[i]) {
1455 child->sp--; 1506 child->sp--;
1456 free(p); 1507 free(p);
1457 } 1508 }
@@ -1459,27 +1510,25 @@ static int run_pipe_real(struct pipe *pi)
1459 if (child->sp) { 1510 if (child->sp) {
1460 char *str; 1511 char *str;
1461 1512
1462 str = make_string(child->argv + i); 1513 str = make_string(argv + i);
1463 parse_string_outer(str, FLAG_EXIT_FROM_LOOP | FLAG_REPARSING); 1514 parse_string_outer(str, FLAG_EXIT_FROM_LOOP | FLAG_REPARSING);
1464 free(str); 1515 free(str);
1465 return last_return_code; 1516 return last_return_code;
1466 } 1517 }
1467 for (x = bltins; x->cmd; x++) { 1518 for (x = bltins; x->cmd; x++) {
1468 if (strcmp(child->argv[i], x->cmd) == 0) { 1519 if (strcmp(argv[i], x->cmd) == 0) {
1469 if (x->function == builtin_exec && child->argv[i+1] == NULL) { 1520 if (x->function == builtin_exec && argv[i+1] == NULL) {
1470 debug_printf("magic exec\n"); 1521 debug_printf("magic exec\n");
1471 setup_redirects(child, NULL); 1522 setup_redirects(child, NULL);
1472 return EXIT_SUCCESS; 1523 return EXIT_SUCCESS;
1473 } 1524 }
1474 debug_printf("builtin inline %s\n", child->argv[0]); 1525 debug_printf("builtin inline %s\n", argv[0]);
1475 /* XXX setup_redirects acts on file descriptors, not FILEs. 1526 /* XXX setup_redirects acts on file descriptors, not FILEs.
1476 * This is perfect for work that comes after exec(). 1527 * This is perfect for work that comes after exec().
1477 * Is it really safe for inline use? Experimentally, 1528 * Is it really safe for inline use? Experimentally,
1478 * things seem to work with glibc. */ 1529 * things seem to work with glibc. */
1479 setup_redirects(child, squirrel); 1530 setup_redirects(child, squirrel);
1480 child->argv += i; /* XXX horrible hack */ 1531 rcode = x->function(argv + i);
1481 rcode = x->function(child);
1482 child->argv -= i; /* XXX restore hack so free() can work right */
1483 restore_redirects(squirrel); 1532 restore_redirects(squirrel);
1484 return rcode; 1533 return rcode;
1485 } 1534 }
@@ -1488,10 +1537,10 @@ static int run_pipe_real(struct pipe *pi)
1488 { 1537 {
1489// FIXME: applet runs like part of shell - for example, it ignores 1538// FIXME: applet runs like part of shell - for example, it ignores
1490// SIGINT! Try to Ctrl-C out of "rm -i"... doesn't work 1539// SIGINT! Try to Ctrl-C out of "rm -i"... doesn't work
1491 const struct bb_applet *a = find_applet_by_name(child->argv[i]); 1540 const struct bb_applet *a = find_applet_by_name(argv[i]);
1492 if (a && a->nofork) { 1541 if (a && a->nofork) {
1493 setup_redirects(child, squirrel); 1542 setup_redirects(child, squirrel);
1494 rcode = run_nofork_applet(a, child->argv + i); 1543 rcode = run_nofork_applet(a, argv + i);
1495 restore_redirects(squirrel); 1544 restore_redirects(squirrel);
1496 return rcode; 1545 return rcode;
1497 } 1546 }
@@ -1503,7 +1552,6 @@ static int run_pipe_real(struct pipe *pi)
1503 * for initial child code after fork */ 1552 * for initial child code after fork */
1504 set_jobctrl_sighandler(SIG_IGN); 1553 set_jobctrl_sighandler(SIG_IGN);
1505 1554
1506 pi->running_progs = 0;
1507 for (i = 0; i < pi->num_progs; i++) { 1555 for (i = 0; i < pi->num_progs; i++) {
1508 child = &(pi->progs[i]); 1556 child = &(pi->progs[i]);
1509 1557