aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2000-07-14 01:13:11 +0000
committerEric Andersen <andersen@codepoet.org>2000-07-14 01:13:11 +0000
commitec10b9d534d3c7c215144049b10df175aed02aa9 (patch)
tree675a2de47518a4e94f040b44d44e2cc2f8bf7404
parent34623db61895ab5575f7851c9313ab2bf4fecc03 (diff)
downloadbusybox-w32-ec10b9d534d3c7c215144049b10df175aed02aa9.tar.gz
busybox-w32-ec10b9d534d3c7c215144049b10df175aed02aa9.tar.bz2
busybox-w32-ec10b9d534d3c7c215144049b10df175aed02aa9.zip
Add in redimentary backtick suport (doesn't work properly yet, but is
close). -Erik
-rw-r--r--lash.c113
-rw-r--r--sh.c113
-rw-r--r--shell/lash.c113
3 files changed, 219 insertions, 120 deletions
diff --git a/lash.c b/lash.c
index bb258c788..f4564f7f7 100644
--- a/lash.c
+++ b/lash.c
@@ -106,9 +106,9 @@ static int builtin_read(struct job *cmd, struct jobSet *junk);
106/* function prototypes for shell stuff */ 106/* function prototypes for shell stuff */
107static void checkJobs(struct jobSet *jobList); 107static void checkJobs(struct jobSet *jobList);
108static int getCommand(FILE * source, char *command); 108static int getCommand(FILE * source, char *command);
109static int parseCommand(char **commandPtr, struct job *job, int *isBg); 109static int parseCommand(char **commandPtr, struct job *job, struct jobSet *jobList, int *isBg);
110static int setupRedirections(struct childProgram *prog); 110static int setupRedirections(struct childProgram *prog);
111static int runCommand(struct job newJob, struct jobSet *jobList, int inBg); 111static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg);
112static int busy_loop(FILE * input); 112static int busy_loop(FILE * input);
113 113
114 114
@@ -389,6 +389,7 @@ static void freeJob(struct job *cmd)
389 if (cmd->text) 389 if (cmd->text)
390 free(cmd->text); 390 free(cmd->text);
391 free(cmd->cmdBuf); 391 free(cmd->cmdBuf);
392 memset(cmd, 0, sizeof(struct job));
392} 393}
393 394
394/* remove a job from the jobList */ 395/* remove a job from the jobList */
@@ -471,7 +472,7 @@ static int getCommand(FILE * source, char *command)
471 char *promptStr; 472 char *promptStr;
472 len=fprintf(stdout, "%s %s", cwd, prompt); 473 len=fprintf(stdout, "%s %s", cwd, prompt);
473 fflush(stdout); 474 fflush(stdout);
474 promptStr=(char*)malloc(sizeof(char)*(len+1)); 475 promptStr=(char*)xmalloc(sizeof(char)*(len+1));
475 sprintf(promptStr, "%s %s", cwd, prompt); 476 sprintf(promptStr, "%s %s", cwd, prompt);
476 cmdedit_read_input(promptStr, command); 477 cmdedit_read_input(promptStr, command);
477 free( promptStr); 478 free( promptStr);
@@ -550,7 +551,7 @@ static void globLastArgument(struct childProgram *prog, int *argcPtr,
550 the beginning of the next command (if the original command had more 551 the beginning of the next command (if the original command had more
551 then one job associated with it) or NULL if no more commands are 552 then one job associated with it) or NULL if no more commands are
552 present. */ 553 present. */
553static int parseCommand(char **commandPtr, struct job *job, int *isBg) 554static int parseCommand(char **commandPtr, struct job *job, struct jobSet *jobList, int *isBg)
554{ 555{
555 char *command; 556 char *command;
556 char *returnCommand = NULL; 557 char *returnCommand = NULL;
@@ -569,14 +570,13 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
569 570
570 /* this handles empty lines or leading '#' characters */ 571 /* this handles empty lines or leading '#' characters */
571 if (!**commandPtr || (**commandPtr == '#')) { 572 if (!**commandPtr || (**commandPtr == '#')) {
572 job->numProgs = 0; 573 job->numProgs=0;
573 *commandPtr = NULL;
574 return 0; 574 return 0;
575 } 575 }
576 576
577 *isBg = 0; 577 *isBg = 0;
578 job->numProgs = 1; 578 job->numProgs = 1;
579 job->progs = malloc(sizeof(*job->progs)); 579 job->progs = xmalloc(sizeof(*job->progs));
580 580
581 /* We set the argv elements to point inside of this string. The 581 /* We set the argv elements to point inside of this string. The
582 memory is freed by freeJob(). Allocate twice the original 582 memory is freed by freeJob(). Allocate twice the original
@@ -595,7 +595,7 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
595 prog->isStopped = 0; 595 prog->isStopped = 0;
596 596
597 argvAlloced = 5; 597 argvAlloced = 5;
598 prog->argv = malloc(sizeof(*prog->argv) * argvAlloced); 598 prog->argv = xmalloc(sizeof(*prog->argv) * argvAlloced);
599 prog->argv[0] = job->cmdBuf; 599 prog->argv[0] = job->cmdBuf;
600 600
601 buf = command; 601 buf = command;
@@ -688,6 +688,7 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
688 if (!*chptr) { 688 if (!*chptr) {
689 fprintf(stderr, "file name expected after %c\n", *src); 689 fprintf(stderr, "file name expected after %c\n", *src);
690 freeJob(job); 690 freeJob(job);
691 job->numProgs=0;
691 return 1; 692 return 1;
692 } 693 }
693 694
@@ -704,8 +705,9 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
704 if (*prog->argv[argc]) 705 if (*prog->argv[argc])
705 argc++; 706 argc++;
706 if (!argc) { 707 if (!argc) {
707 fprintf(stderr, "empty command in pipe\n"); 708 fprintf(stderr, "empty command in pipe1.\n");
708 freeJob(job); 709 freeJob(job);
710 job->numProgs=0;
709 return 1; 711 return 1;
710 } 712 }
711 prog->argv[argc] = NULL; 713 prog->argv[argc] = NULL;
@@ -721,7 +723,7 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
721 argc = 0; 723 argc = 0;
722 724
723 argvAlloced = 5; 725 argvAlloced = 5;
724 prog->argv = malloc(sizeof(*prog->argv) * argvAlloced); 726 prog->argv = xmalloc(sizeof(*prog->argv) * argvAlloced);
725 prog->argv[0] = ++buf; 727 prog->argv[0] = ++buf;
726 728
727 src++; 729 src++;
@@ -729,7 +731,9 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
729 src++; 731 src++;
730 732
731 if (!*src) { 733 if (!*src) {
732 fprintf(stderr, "empty command in pipe\n"); 734 fprintf(stderr, "empty command in pipe2\n");
735 freeJob(job);
736 job->numProgs=0;
733 return 1; 737 return 1;
734 } 738 }
735 src--; /* we'll ++ it at the end of the loop */ 739 src--; /* we'll ++ it at the end of the loop */
@@ -746,13 +750,40 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
746 case '\\': 750 case '\\':
747 src++; 751 src++;
748 if (!*src) { 752 if (!*src) {
749 freeJob(job);
750 fprintf(stderr, "character expected after \\\n"); 753 fprintf(stderr, "character expected after \\\n");
754 freeJob(job);
751 return 1; 755 return 1;
752 } 756 }
753 if (*src == '*' || *src == '[' || *src == ']' 757 if (*src == '*' || *src == '[' || *src == ']'
754 || *src == '?') *buf++ = '\\'; 758 || *src == '?') *buf++ = '\\';
755 /* fallthrough */ 759 /* fallthrough */
760 case '`':
761 /* Exec a backtick-ed command */
762 {
763 char* newcmd=NULL;
764 char* ptr=NULL;
765 struct job newJob;
766
767 ptr=strchr(++src, '`');
768 if (ptr==NULL) {
769 fprintf(stderr, "Unmatched '`' in command\n");
770 freeJob(job);
771 return 1;
772 }
773
774 newcmd = xmalloc(1+ptr-src);
775 snprintf(newcmd, 1+ptr-src, src);
776
777 if (!parseCommand(&newcmd, &newJob, jobList, isBg) &&
778 newJob.numProgs) {
779 runCommand(&newJob, jobList, *isBg);
780 }
781
782 /* Clip out the the backticked command from the string */
783 memmove(--src, ptr, strlen(ptr)+1);
784 free(newcmd);
785 }
786 break;
756 default: 787 default:
757 *buf++ = *src; 788 *buf++ = *src;
758 } 789 }
@@ -771,12 +802,12 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
771 prog->argv[argc] = NULL; 802 prog->argv[argc] = NULL;
772 803
773 if (!returnCommand) { 804 if (!returnCommand) {
774 job->text = malloc(strlen(*commandPtr) + 1); 805 job->text = xmalloc(strlen(*commandPtr) + 1);
775 strcpy(job->text, *commandPtr); 806 strcpy(job->text, *commandPtr);
776 } else { 807 } else {
777 /* This leaves any trailing spaces, which is a bit sloppy */ 808 /* This leaves any trailing spaces, which is a bit sloppy */
778 count = returnCommand - *commandPtr; 809 count = returnCommand - *commandPtr;
779 job->text = malloc(count + 1); 810 job->text = xmalloc(count + 1);
780 strncpy(job->text, *commandPtr, count); 811 strncpy(job->text, *commandPtr, count);
781 job->text[count] = '\0'; 812 job->text[count] = '\0';
782 } 813 }
@@ -787,7 +818,7 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
787} 818}
788 819
789 820
790static int runCommand(struct job newJob, struct jobSet *jobList, int inBg) 821static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg)
791{ 822{
792 struct job *job; 823 struct job *job;
793 int i; 824 int i;
@@ -800,8 +831,8 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
800 831
801 832
802 nextin = 0, nextout = 1; 833 nextin = 0, nextout = 1;
803 for (i = 0; i < newJob.numProgs; i++) { 834 for (i = 0; i < newJob->numProgs; i++) {
804 if ((i + 1) < newJob.numProgs) { 835 if ((i + 1) < newJob->numProgs) {
805 pipe(pipefds); 836 pipe(pipefds);
806 nextout = pipefds[1]; 837 nextout = pipefds[1];
807 } else { 838 } else {
@@ -810,12 +841,12 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
810 841
811 /* Check if the command matches any non-forking builtins */ 842 /* Check if the command matches any non-forking builtins */
812 for (x = bltins; x->cmd; x++) { 843 for (x = bltins; x->cmd; x++) {
813 if (!strcmp(newJob.progs[i].argv[0], x->cmd)) { 844 if (!strcmp(newJob->progs[i].argv[0], x->cmd)) {
814 return (x->function(&newJob, jobList)); 845 return (x->function(newJob, jobList));
815 } 846 }
816 } 847 }
817 848
818 if (!(newJob.progs[i].pid = fork())) { 849 if (!(newJob->progs[i].pid = fork())) {
819 signal(SIGTTOU, SIG_DFL); 850 signal(SIGTTOU, SIG_DFL);
820 851
821 if (nextin != 0) { 852 if (nextin != 0) {
@@ -829,12 +860,12 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
829 } 860 }
830 861
831 /* explicit redirections override pipes */ 862 /* explicit redirections override pipes */
832 setupRedirections(newJob.progs + i); 863 setupRedirections(newJob->progs + i);
833 864
834 /* Check if the command matches any of the other builtins */ 865 /* Check if the command matches any of the other builtins */
835 for (x = bltins_forking; x->cmd; x++) { 866 for (x = bltins_forking; x->cmd; x++) {
836 if (!strcmp(newJob.progs[i].argv[0], x->cmd)) { 867 if (!strcmp(newJob->progs[i].argv[0], x->cmd)) {
837 exit (x->function(&newJob, jobList)); 868 exit (x->function(newJob, jobList));
838 } 869 }
839 } 870 }
840#ifdef BB_FEATURE_SH_STANDALONE_SHELL 871#ifdef BB_FEATURE_SH_STANDALONE_SHELL
@@ -842,24 +873,24 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
842 /* TODO: Add matching when paths are appended (i.e. 'cat' currently 873 /* TODO: Add matching when paths are appended (i.e. 'cat' currently
843 * works, but '/bin/cat' doesn't ) */ 874 * works, but '/bin/cat' doesn't ) */
844 while (a->name != 0) { 875 while (a->name != 0) {
845 if (strcmp(newJob.progs[i].argv[0], a->name) == 0) { 876 if (strcmp(newJob->progs[i].argv[0], a->name) == 0) {
846 int argc; 877 int argc;
847 char** argv=newJob.progs[i].argv; 878 char** argv=newJob->progs[i].argv;
848 for(argc=0;*argv!=NULL; argv++, argc++); 879 for(argc=0;*argv!=NULL; argv++, argc++);
849 exit((*(a->main)) (argc, newJob.progs[i].argv)); 880 exit((*(a->main)) (argc, newJob->progs[i].argv));
850 } 881 }
851 a++; 882 a++;
852 } 883 }
853#endif 884#endif
854 885
855 execvp(newJob.progs[i].argv[0], newJob.progs[i].argv); 886 execvp(newJob->progs[i].argv[0], newJob->progs[i].argv);
856 fatalError("%s: %s\n", newJob.progs[i].argv[0], 887 fatalError("%s: %s\n", newJob->progs[i].argv[0],
857 strerror(errno)); 888 strerror(errno));
858 } 889 }
859 890
860 /* put our child in the process group whose leader is the 891 /* put our child in the process group whose leader is the
861 first process in this pipe */ 892 first process in this pipe */
862 setpgid(newJob.progs[i].pid, newJob.progs[0].pid); 893 setpgid(newJob->progs[i].pid, newJob->progs[0].pid);
863 894
864 if (nextin != 0) 895 if (nextin != 0)
865 close(nextin); 896 close(nextin);
@@ -871,24 +902,24 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
871 nextin = pipefds[0]; 902 nextin = pipefds[0];
872 } 903 }
873 904
874 newJob.pgrp = newJob.progs[0].pid; 905 newJob->pgrp = newJob->progs[0].pid;
875 906
876 /* find the ID for the job to use */ 907 /* find the ID for the job to use */
877 newJob.jobId = 1; 908 newJob->jobId = 1;
878 for (job = jobList->head; job; job = job->next) 909 for (job = jobList->head; job; job = job->next)
879 if (job->jobId >= newJob.jobId) 910 if (job->jobId >= newJob->jobId)
880 newJob.jobId = job->jobId + 1; 911 newJob->jobId = job->jobId + 1;
881 912
882 /* add the job to the list of running jobs */ 913 /* add the job to the list of running jobs */
883 if (!jobList->head) { 914 if (!jobList->head) {
884 job = jobList->head = malloc(sizeof(*job)); 915 job = jobList->head = xmalloc(sizeof(*job));
885 } else { 916 } else {
886 for (job = jobList->head; job->next; job = job->next); 917 for (job = jobList->head; job->next; job = job->next);
887 job->next = malloc(sizeof(*job)); 918 job->next = xmalloc(sizeof(*job));
888 job = job->next; 919 job = job->next;
889 } 920 }
890 921
891 *job = newJob; 922 *job = *newJob;
892 job->next = NULL; 923 job->next = NULL;
893 job->runningProgs = job->numProgs; 924 job->runningProgs = job->numProgs;
894 job->stoppedProgs = 0; 925 job->stoppedProgs = 0;
@@ -897,13 +928,13 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
897 /* we don't wait for background jobs to return -- append it 928 /* we don't wait for background jobs to return -- append it
898 to the list of backgrounded jobs and leave it alone */ 929 to the list of backgrounded jobs and leave it alone */
899 printf("[%d] %d\n", job->jobId, 930 printf("[%d] %d\n", job->jobId,
900 newJob.progs[newJob.numProgs - 1].pid); 931 newJob->progs[newJob->numProgs - 1].pid);
901 } else { 932 } else {
902 jobList->fg = job; 933 jobList->fg = job;
903 934
904 /* move the new process group into the foreground */ 935 /* move the new process group into the foreground */
905 /* suppress messages when run from /linuxrc mag@sysgo.de */ 936 /* suppress messages when run from /linuxrc mag@sysgo.de */
906 if (tcsetpgrp(0, newJob.pgrp) && errno != ENOTTY) 937 if (tcsetpgrp(0, newJob->pgrp) && errno != ENOTTY)
907 perror("tcsetpgrp"); 938 perror("tcsetpgrp");
908 } 939 }
909 940
@@ -982,9 +1013,11 @@ static int busy_loop(FILE * input)
982 nextCommand = command; 1013 nextCommand = command;
983 } 1014 }
984 1015
985 if (!parseCommand(&nextCommand, &newJob, &inBg) && 1016 if (!parseCommand(&nextCommand, &newJob, &jobList, &inBg) &&
986 newJob.numProgs) { 1017 newJob.numProgs) {
987 runCommand(newJob, &jobList, inBg); 1018 runCommand(&newJob, &jobList, inBg);
1019 } else {
1020 nextCommand=NULL;
988 } 1021 }
989 } else { 1022 } else {
990 /* a job is running in the foreground; wait for it */ 1023 /* a job is running in the foreground; wait for it */
diff --git a/sh.c b/sh.c
index bb258c788..f4564f7f7 100644
--- a/sh.c
+++ b/sh.c
@@ -106,9 +106,9 @@ static int builtin_read(struct job *cmd, struct jobSet *junk);
106/* function prototypes for shell stuff */ 106/* function prototypes for shell stuff */
107static void checkJobs(struct jobSet *jobList); 107static void checkJobs(struct jobSet *jobList);
108static int getCommand(FILE * source, char *command); 108static int getCommand(FILE * source, char *command);
109static int parseCommand(char **commandPtr, struct job *job, int *isBg); 109static int parseCommand(char **commandPtr, struct job *job, struct jobSet *jobList, int *isBg);
110static int setupRedirections(struct childProgram *prog); 110static int setupRedirections(struct childProgram *prog);
111static int runCommand(struct job newJob, struct jobSet *jobList, int inBg); 111static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg);
112static int busy_loop(FILE * input); 112static int busy_loop(FILE * input);
113 113
114 114
@@ -389,6 +389,7 @@ static void freeJob(struct job *cmd)
389 if (cmd->text) 389 if (cmd->text)
390 free(cmd->text); 390 free(cmd->text);
391 free(cmd->cmdBuf); 391 free(cmd->cmdBuf);
392 memset(cmd, 0, sizeof(struct job));
392} 393}
393 394
394/* remove a job from the jobList */ 395/* remove a job from the jobList */
@@ -471,7 +472,7 @@ static int getCommand(FILE * source, char *command)
471 char *promptStr; 472 char *promptStr;
472 len=fprintf(stdout, "%s %s", cwd, prompt); 473 len=fprintf(stdout, "%s %s", cwd, prompt);
473 fflush(stdout); 474 fflush(stdout);
474 promptStr=(char*)malloc(sizeof(char)*(len+1)); 475 promptStr=(char*)xmalloc(sizeof(char)*(len+1));
475 sprintf(promptStr, "%s %s", cwd, prompt); 476 sprintf(promptStr, "%s %s", cwd, prompt);
476 cmdedit_read_input(promptStr, command); 477 cmdedit_read_input(promptStr, command);
477 free( promptStr); 478 free( promptStr);
@@ -550,7 +551,7 @@ static void globLastArgument(struct childProgram *prog, int *argcPtr,
550 the beginning of the next command (if the original command had more 551 the beginning of the next command (if the original command had more
551 then one job associated with it) or NULL if no more commands are 552 then one job associated with it) or NULL if no more commands are
552 present. */ 553 present. */
553static int parseCommand(char **commandPtr, struct job *job, int *isBg) 554static int parseCommand(char **commandPtr, struct job *job, struct jobSet *jobList, int *isBg)
554{ 555{
555 char *command; 556 char *command;
556 char *returnCommand = NULL; 557 char *returnCommand = NULL;
@@ -569,14 +570,13 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
569 570
570 /* this handles empty lines or leading '#' characters */ 571 /* this handles empty lines or leading '#' characters */
571 if (!**commandPtr || (**commandPtr == '#')) { 572 if (!**commandPtr || (**commandPtr == '#')) {
572 job->numProgs = 0; 573 job->numProgs=0;
573 *commandPtr = NULL;
574 return 0; 574 return 0;
575 } 575 }
576 576
577 *isBg = 0; 577 *isBg = 0;
578 job->numProgs = 1; 578 job->numProgs = 1;
579 job->progs = malloc(sizeof(*job->progs)); 579 job->progs = xmalloc(sizeof(*job->progs));
580 580
581 /* We set the argv elements to point inside of this string. The 581 /* We set the argv elements to point inside of this string. The
582 memory is freed by freeJob(). Allocate twice the original 582 memory is freed by freeJob(). Allocate twice the original
@@ -595,7 +595,7 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
595 prog->isStopped = 0; 595 prog->isStopped = 0;
596 596
597 argvAlloced = 5; 597 argvAlloced = 5;
598 prog->argv = malloc(sizeof(*prog->argv) * argvAlloced); 598 prog->argv = xmalloc(sizeof(*prog->argv) * argvAlloced);
599 prog->argv[0] = job->cmdBuf; 599 prog->argv[0] = job->cmdBuf;
600 600
601 buf = command; 601 buf = command;
@@ -688,6 +688,7 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
688 if (!*chptr) { 688 if (!*chptr) {
689 fprintf(stderr, "file name expected after %c\n", *src); 689 fprintf(stderr, "file name expected after %c\n", *src);
690 freeJob(job); 690 freeJob(job);
691 job->numProgs=0;
691 return 1; 692 return 1;
692 } 693 }
693 694
@@ -704,8 +705,9 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
704 if (*prog->argv[argc]) 705 if (*prog->argv[argc])
705 argc++; 706 argc++;
706 if (!argc) { 707 if (!argc) {
707 fprintf(stderr, "empty command in pipe\n"); 708 fprintf(stderr, "empty command in pipe1.\n");
708 freeJob(job); 709 freeJob(job);
710 job->numProgs=0;
709 return 1; 711 return 1;
710 } 712 }
711 prog->argv[argc] = NULL; 713 prog->argv[argc] = NULL;
@@ -721,7 +723,7 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
721 argc = 0; 723 argc = 0;
722 724
723 argvAlloced = 5; 725 argvAlloced = 5;
724 prog->argv = malloc(sizeof(*prog->argv) * argvAlloced); 726 prog->argv = xmalloc(sizeof(*prog->argv) * argvAlloced);
725 prog->argv[0] = ++buf; 727 prog->argv[0] = ++buf;
726 728
727 src++; 729 src++;
@@ -729,7 +731,9 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
729 src++; 731 src++;
730 732
731 if (!*src) { 733 if (!*src) {
732 fprintf(stderr, "empty command in pipe\n"); 734 fprintf(stderr, "empty command in pipe2\n");
735 freeJob(job);
736 job->numProgs=0;
733 return 1; 737 return 1;
734 } 738 }
735 src--; /* we'll ++ it at the end of the loop */ 739 src--; /* we'll ++ it at the end of the loop */
@@ -746,13 +750,40 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
746 case '\\': 750 case '\\':
747 src++; 751 src++;
748 if (!*src) { 752 if (!*src) {
749 freeJob(job);
750 fprintf(stderr, "character expected after \\\n"); 753 fprintf(stderr, "character expected after \\\n");
754 freeJob(job);
751 return 1; 755 return 1;
752 } 756 }
753 if (*src == '*' || *src == '[' || *src == ']' 757 if (*src == '*' || *src == '[' || *src == ']'
754 || *src == '?') *buf++ = '\\'; 758 || *src == '?') *buf++ = '\\';
755 /* fallthrough */ 759 /* fallthrough */
760 case '`':
761 /* Exec a backtick-ed command */
762 {
763 char* newcmd=NULL;
764 char* ptr=NULL;
765 struct job newJob;
766
767 ptr=strchr(++src, '`');
768 if (ptr==NULL) {
769 fprintf(stderr, "Unmatched '`' in command\n");
770 freeJob(job);
771 return 1;
772 }
773
774 newcmd = xmalloc(1+ptr-src);
775 snprintf(newcmd, 1+ptr-src, src);
776
777 if (!parseCommand(&newcmd, &newJob, jobList, isBg) &&
778 newJob.numProgs) {
779 runCommand(&newJob, jobList, *isBg);
780 }
781
782 /* Clip out the the backticked command from the string */
783 memmove(--src, ptr, strlen(ptr)+1);
784 free(newcmd);
785 }
786 break;
756 default: 787 default:
757 *buf++ = *src; 788 *buf++ = *src;
758 } 789 }
@@ -771,12 +802,12 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
771 prog->argv[argc] = NULL; 802 prog->argv[argc] = NULL;
772 803
773 if (!returnCommand) { 804 if (!returnCommand) {
774 job->text = malloc(strlen(*commandPtr) + 1); 805 job->text = xmalloc(strlen(*commandPtr) + 1);
775 strcpy(job->text, *commandPtr); 806 strcpy(job->text, *commandPtr);
776 } else { 807 } else {
777 /* This leaves any trailing spaces, which is a bit sloppy */ 808 /* This leaves any trailing spaces, which is a bit sloppy */
778 count = returnCommand - *commandPtr; 809 count = returnCommand - *commandPtr;
779 job->text = malloc(count + 1); 810 job->text = xmalloc(count + 1);
780 strncpy(job->text, *commandPtr, count); 811 strncpy(job->text, *commandPtr, count);
781 job->text[count] = '\0'; 812 job->text[count] = '\0';
782 } 813 }
@@ -787,7 +818,7 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
787} 818}
788 819
789 820
790static int runCommand(struct job newJob, struct jobSet *jobList, int inBg) 821static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg)
791{ 822{
792 struct job *job; 823 struct job *job;
793 int i; 824 int i;
@@ -800,8 +831,8 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
800 831
801 832
802 nextin = 0, nextout = 1; 833 nextin = 0, nextout = 1;
803 for (i = 0; i < newJob.numProgs; i++) { 834 for (i = 0; i < newJob->numProgs; i++) {
804 if ((i + 1) < newJob.numProgs) { 835 if ((i + 1) < newJob->numProgs) {
805 pipe(pipefds); 836 pipe(pipefds);
806 nextout = pipefds[1]; 837 nextout = pipefds[1];
807 } else { 838 } else {
@@ -810,12 +841,12 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
810 841
811 /* Check if the command matches any non-forking builtins */ 842 /* Check if the command matches any non-forking builtins */
812 for (x = bltins; x->cmd; x++) { 843 for (x = bltins; x->cmd; x++) {
813 if (!strcmp(newJob.progs[i].argv[0], x->cmd)) { 844 if (!strcmp(newJob->progs[i].argv[0], x->cmd)) {
814 return (x->function(&newJob, jobList)); 845 return (x->function(newJob, jobList));
815 } 846 }
816 } 847 }
817 848
818 if (!(newJob.progs[i].pid = fork())) { 849 if (!(newJob->progs[i].pid = fork())) {
819 signal(SIGTTOU, SIG_DFL); 850 signal(SIGTTOU, SIG_DFL);
820 851
821 if (nextin != 0) { 852 if (nextin != 0) {
@@ -829,12 +860,12 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
829 } 860 }
830 861
831 /* explicit redirections override pipes */ 862 /* explicit redirections override pipes */
832 setupRedirections(newJob.progs + i); 863 setupRedirections(newJob->progs + i);
833 864
834 /* Check if the command matches any of the other builtins */ 865 /* Check if the command matches any of the other builtins */
835 for (x = bltins_forking; x->cmd; x++) { 866 for (x = bltins_forking; x->cmd; x++) {
836 if (!strcmp(newJob.progs[i].argv[0], x->cmd)) { 867 if (!strcmp(newJob->progs[i].argv[0], x->cmd)) {
837 exit (x->function(&newJob, jobList)); 868 exit (x->function(newJob, jobList));
838 } 869 }
839 } 870 }
840#ifdef BB_FEATURE_SH_STANDALONE_SHELL 871#ifdef BB_FEATURE_SH_STANDALONE_SHELL
@@ -842,24 +873,24 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
842 /* TODO: Add matching when paths are appended (i.e. 'cat' currently 873 /* TODO: Add matching when paths are appended (i.e. 'cat' currently
843 * works, but '/bin/cat' doesn't ) */ 874 * works, but '/bin/cat' doesn't ) */
844 while (a->name != 0) { 875 while (a->name != 0) {
845 if (strcmp(newJob.progs[i].argv[0], a->name) == 0) { 876 if (strcmp(newJob->progs[i].argv[0], a->name) == 0) {
846 int argc; 877 int argc;
847 char** argv=newJob.progs[i].argv; 878 char** argv=newJob->progs[i].argv;
848 for(argc=0;*argv!=NULL; argv++, argc++); 879 for(argc=0;*argv!=NULL; argv++, argc++);
849 exit((*(a->main)) (argc, newJob.progs[i].argv)); 880 exit((*(a->main)) (argc, newJob->progs[i].argv));
850 } 881 }
851 a++; 882 a++;
852 } 883 }
853#endif 884#endif
854 885
855 execvp(newJob.progs[i].argv[0], newJob.progs[i].argv); 886 execvp(newJob->progs[i].argv[0], newJob->progs[i].argv);
856 fatalError("%s: %s\n", newJob.progs[i].argv[0], 887 fatalError("%s: %s\n", newJob->progs[i].argv[0],
857 strerror(errno)); 888 strerror(errno));
858 } 889 }
859 890
860 /* put our child in the process group whose leader is the 891 /* put our child in the process group whose leader is the
861 first process in this pipe */ 892 first process in this pipe */
862 setpgid(newJob.progs[i].pid, newJob.progs[0].pid); 893 setpgid(newJob->progs[i].pid, newJob->progs[0].pid);
863 894
864 if (nextin != 0) 895 if (nextin != 0)
865 close(nextin); 896 close(nextin);
@@ -871,24 +902,24 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
871 nextin = pipefds[0]; 902 nextin = pipefds[0];
872 } 903 }
873 904
874 newJob.pgrp = newJob.progs[0].pid; 905 newJob->pgrp = newJob->progs[0].pid;
875 906
876 /* find the ID for the job to use */ 907 /* find the ID for the job to use */
877 newJob.jobId = 1; 908 newJob->jobId = 1;
878 for (job = jobList->head; job; job = job->next) 909 for (job = jobList->head; job; job = job->next)
879 if (job->jobId >= newJob.jobId) 910 if (job->jobId >= newJob->jobId)
880 newJob.jobId = job->jobId + 1; 911 newJob->jobId = job->jobId + 1;
881 912
882 /* add the job to the list of running jobs */ 913 /* add the job to the list of running jobs */
883 if (!jobList->head) { 914 if (!jobList->head) {
884 job = jobList->head = malloc(sizeof(*job)); 915 job = jobList->head = xmalloc(sizeof(*job));
885 } else { 916 } else {
886 for (job = jobList->head; job->next; job = job->next); 917 for (job = jobList->head; job->next; job = job->next);
887 job->next = malloc(sizeof(*job)); 918 job->next = xmalloc(sizeof(*job));
888 job = job->next; 919 job = job->next;
889 } 920 }
890 921
891 *job = newJob; 922 *job = *newJob;
892 job->next = NULL; 923 job->next = NULL;
893 job->runningProgs = job->numProgs; 924 job->runningProgs = job->numProgs;
894 job->stoppedProgs = 0; 925 job->stoppedProgs = 0;
@@ -897,13 +928,13 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
897 /* we don't wait for background jobs to return -- append it 928 /* we don't wait for background jobs to return -- append it
898 to the list of backgrounded jobs and leave it alone */ 929 to the list of backgrounded jobs and leave it alone */
899 printf("[%d] %d\n", job->jobId, 930 printf("[%d] %d\n", job->jobId,
900 newJob.progs[newJob.numProgs - 1].pid); 931 newJob->progs[newJob->numProgs - 1].pid);
901 } else { 932 } else {
902 jobList->fg = job; 933 jobList->fg = job;
903 934
904 /* move the new process group into the foreground */ 935 /* move the new process group into the foreground */
905 /* suppress messages when run from /linuxrc mag@sysgo.de */ 936 /* suppress messages when run from /linuxrc mag@sysgo.de */
906 if (tcsetpgrp(0, newJob.pgrp) && errno != ENOTTY) 937 if (tcsetpgrp(0, newJob->pgrp) && errno != ENOTTY)
907 perror("tcsetpgrp"); 938 perror("tcsetpgrp");
908 } 939 }
909 940
@@ -982,9 +1013,11 @@ static int busy_loop(FILE * input)
982 nextCommand = command; 1013 nextCommand = command;
983 } 1014 }
984 1015
985 if (!parseCommand(&nextCommand, &newJob, &inBg) && 1016 if (!parseCommand(&nextCommand, &newJob, &jobList, &inBg) &&
986 newJob.numProgs) { 1017 newJob.numProgs) {
987 runCommand(newJob, &jobList, inBg); 1018 runCommand(&newJob, &jobList, inBg);
1019 } else {
1020 nextCommand=NULL;
988 } 1021 }
989 } else { 1022 } else {
990 /* a job is running in the foreground; wait for it */ 1023 /* a job is running in the foreground; wait for it */
diff --git a/shell/lash.c b/shell/lash.c
index bb258c788..f4564f7f7 100644
--- a/shell/lash.c
+++ b/shell/lash.c
@@ -106,9 +106,9 @@ static int builtin_read(struct job *cmd, struct jobSet *junk);
106/* function prototypes for shell stuff */ 106/* function prototypes for shell stuff */
107static void checkJobs(struct jobSet *jobList); 107static void checkJobs(struct jobSet *jobList);
108static int getCommand(FILE * source, char *command); 108static int getCommand(FILE * source, char *command);
109static int parseCommand(char **commandPtr, struct job *job, int *isBg); 109static int parseCommand(char **commandPtr, struct job *job, struct jobSet *jobList, int *isBg);
110static int setupRedirections(struct childProgram *prog); 110static int setupRedirections(struct childProgram *prog);
111static int runCommand(struct job newJob, struct jobSet *jobList, int inBg); 111static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg);
112static int busy_loop(FILE * input); 112static int busy_loop(FILE * input);
113 113
114 114
@@ -389,6 +389,7 @@ static void freeJob(struct job *cmd)
389 if (cmd->text) 389 if (cmd->text)
390 free(cmd->text); 390 free(cmd->text);
391 free(cmd->cmdBuf); 391 free(cmd->cmdBuf);
392 memset(cmd, 0, sizeof(struct job));
392} 393}
393 394
394/* remove a job from the jobList */ 395/* remove a job from the jobList */
@@ -471,7 +472,7 @@ static int getCommand(FILE * source, char *command)
471 char *promptStr; 472 char *promptStr;
472 len=fprintf(stdout, "%s %s", cwd, prompt); 473 len=fprintf(stdout, "%s %s", cwd, prompt);
473 fflush(stdout); 474 fflush(stdout);
474 promptStr=(char*)malloc(sizeof(char)*(len+1)); 475 promptStr=(char*)xmalloc(sizeof(char)*(len+1));
475 sprintf(promptStr, "%s %s", cwd, prompt); 476 sprintf(promptStr, "%s %s", cwd, prompt);
476 cmdedit_read_input(promptStr, command); 477 cmdedit_read_input(promptStr, command);
477 free( promptStr); 478 free( promptStr);
@@ -550,7 +551,7 @@ static void globLastArgument(struct childProgram *prog, int *argcPtr,
550 the beginning of the next command (if the original command had more 551 the beginning of the next command (if the original command had more
551 then one job associated with it) or NULL if no more commands are 552 then one job associated with it) or NULL if no more commands are
552 present. */ 553 present. */
553static int parseCommand(char **commandPtr, struct job *job, int *isBg) 554static int parseCommand(char **commandPtr, struct job *job, struct jobSet *jobList, int *isBg)
554{ 555{
555 char *command; 556 char *command;
556 char *returnCommand = NULL; 557 char *returnCommand = NULL;
@@ -569,14 +570,13 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
569 570
570 /* this handles empty lines or leading '#' characters */ 571 /* this handles empty lines or leading '#' characters */
571 if (!**commandPtr || (**commandPtr == '#')) { 572 if (!**commandPtr || (**commandPtr == '#')) {
572 job->numProgs = 0; 573 job->numProgs=0;
573 *commandPtr = NULL;
574 return 0; 574 return 0;
575 } 575 }
576 576
577 *isBg = 0; 577 *isBg = 0;
578 job->numProgs = 1; 578 job->numProgs = 1;
579 job->progs = malloc(sizeof(*job->progs)); 579 job->progs = xmalloc(sizeof(*job->progs));
580 580
581 /* We set the argv elements to point inside of this string. The 581 /* We set the argv elements to point inside of this string. The
582 memory is freed by freeJob(). Allocate twice the original 582 memory is freed by freeJob(). Allocate twice the original
@@ -595,7 +595,7 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
595 prog->isStopped = 0; 595 prog->isStopped = 0;
596 596
597 argvAlloced = 5; 597 argvAlloced = 5;
598 prog->argv = malloc(sizeof(*prog->argv) * argvAlloced); 598 prog->argv = xmalloc(sizeof(*prog->argv) * argvAlloced);
599 prog->argv[0] = job->cmdBuf; 599 prog->argv[0] = job->cmdBuf;
600 600
601 buf = command; 601 buf = command;
@@ -688,6 +688,7 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
688 if (!*chptr) { 688 if (!*chptr) {
689 fprintf(stderr, "file name expected after %c\n", *src); 689 fprintf(stderr, "file name expected after %c\n", *src);
690 freeJob(job); 690 freeJob(job);
691 job->numProgs=0;
691 return 1; 692 return 1;
692 } 693 }
693 694
@@ -704,8 +705,9 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
704 if (*prog->argv[argc]) 705 if (*prog->argv[argc])
705 argc++; 706 argc++;
706 if (!argc) { 707 if (!argc) {
707 fprintf(stderr, "empty command in pipe\n"); 708 fprintf(stderr, "empty command in pipe1.\n");
708 freeJob(job); 709 freeJob(job);
710 job->numProgs=0;
709 return 1; 711 return 1;
710 } 712 }
711 prog->argv[argc] = NULL; 713 prog->argv[argc] = NULL;
@@ -721,7 +723,7 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
721 argc = 0; 723 argc = 0;
722 724
723 argvAlloced = 5; 725 argvAlloced = 5;
724 prog->argv = malloc(sizeof(*prog->argv) * argvAlloced); 726 prog->argv = xmalloc(sizeof(*prog->argv) * argvAlloced);
725 prog->argv[0] = ++buf; 727 prog->argv[0] = ++buf;
726 728
727 src++; 729 src++;
@@ -729,7 +731,9 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
729 src++; 731 src++;
730 732
731 if (!*src) { 733 if (!*src) {
732 fprintf(stderr, "empty command in pipe\n"); 734 fprintf(stderr, "empty command in pipe2\n");
735 freeJob(job);
736 job->numProgs=0;
733 return 1; 737 return 1;
734 } 738 }
735 src--; /* we'll ++ it at the end of the loop */ 739 src--; /* we'll ++ it at the end of the loop */
@@ -746,13 +750,40 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
746 case '\\': 750 case '\\':
747 src++; 751 src++;
748 if (!*src) { 752 if (!*src) {
749 freeJob(job);
750 fprintf(stderr, "character expected after \\\n"); 753 fprintf(stderr, "character expected after \\\n");
754 freeJob(job);
751 return 1; 755 return 1;
752 } 756 }
753 if (*src == '*' || *src == '[' || *src == ']' 757 if (*src == '*' || *src == '[' || *src == ']'
754 || *src == '?') *buf++ = '\\'; 758 || *src == '?') *buf++ = '\\';
755 /* fallthrough */ 759 /* fallthrough */
760 case '`':
761 /* Exec a backtick-ed command */
762 {
763 char* newcmd=NULL;
764 char* ptr=NULL;
765 struct job newJob;
766
767 ptr=strchr(++src, '`');
768 if (ptr==NULL) {
769 fprintf(stderr, "Unmatched '`' in command\n");
770 freeJob(job);
771 return 1;
772 }
773
774 newcmd = xmalloc(1+ptr-src);
775 snprintf(newcmd, 1+ptr-src, src);
776
777 if (!parseCommand(&newcmd, &newJob, jobList, isBg) &&
778 newJob.numProgs) {
779 runCommand(&newJob, jobList, *isBg);
780 }
781
782 /* Clip out the the backticked command from the string */
783 memmove(--src, ptr, strlen(ptr)+1);
784 free(newcmd);
785 }
786 break;
756 default: 787 default:
757 *buf++ = *src; 788 *buf++ = *src;
758 } 789 }
@@ -771,12 +802,12 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
771 prog->argv[argc] = NULL; 802 prog->argv[argc] = NULL;
772 803
773 if (!returnCommand) { 804 if (!returnCommand) {
774 job->text = malloc(strlen(*commandPtr) + 1); 805 job->text = xmalloc(strlen(*commandPtr) + 1);
775 strcpy(job->text, *commandPtr); 806 strcpy(job->text, *commandPtr);
776 } else { 807 } else {
777 /* This leaves any trailing spaces, which is a bit sloppy */ 808 /* This leaves any trailing spaces, which is a bit sloppy */
778 count = returnCommand - *commandPtr; 809 count = returnCommand - *commandPtr;
779 job->text = malloc(count + 1); 810 job->text = xmalloc(count + 1);
780 strncpy(job->text, *commandPtr, count); 811 strncpy(job->text, *commandPtr, count);
781 job->text[count] = '\0'; 812 job->text[count] = '\0';
782 } 813 }
@@ -787,7 +818,7 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
787} 818}
788 819
789 820
790static int runCommand(struct job newJob, struct jobSet *jobList, int inBg) 821static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg)
791{ 822{
792 struct job *job; 823 struct job *job;
793 int i; 824 int i;
@@ -800,8 +831,8 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
800 831
801 832
802 nextin = 0, nextout = 1; 833 nextin = 0, nextout = 1;
803 for (i = 0; i < newJob.numProgs; i++) { 834 for (i = 0; i < newJob->numProgs; i++) {
804 if ((i + 1) < newJob.numProgs) { 835 if ((i + 1) < newJob->numProgs) {
805 pipe(pipefds); 836 pipe(pipefds);
806 nextout = pipefds[1]; 837 nextout = pipefds[1];
807 } else { 838 } else {
@@ -810,12 +841,12 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
810 841
811 /* Check if the command matches any non-forking builtins */ 842 /* Check if the command matches any non-forking builtins */
812 for (x = bltins; x->cmd; x++) { 843 for (x = bltins; x->cmd; x++) {
813 if (!strcmp(newJob.progs[i].argv[0], x->cmd)) { 844 if (!strcmp(newJob->progs[i].argv[0], x->cmd)) {
814 return (x->function(&newJob, jobList)); 845 return (x->function(newJob, jobList));
815 } 846 }
816 } 847 }
817 848
818 if (!(newJob.progs[i].pid = fork())) { 849 if (!(newJob->progs[i].pid = fork())) {
819 signal(SIGTTOU, SIG_DFL); 850 signal(SIGTTOU, SIG_DFL);
820 851
821 if (nextin != 0) { 852 if (nextin != 0) {
@@ -829,12 +860,12 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
829 } 860 }
830 861
831 /* explicit redirections override pipes */ 862 /* explicit redirections override pipes */
832 setupRedirections(newJob.progs + i); 863 setupRedirections(newJob->progs + i);
833 864
834 /* Check if the command matches any of the other builtins */ 865 /* Check if the command matches any of the other builtins */
835 for (x = bltins_forking; x->cmd; x++) { 866 for (x = bltins_forking; x->cmd; x++) {
836 if (!strcmp(newJob.progs[i].argv[0], x->cmd)) { 867 if (!strcmp(newJob->progs[i].argv[0], x->cmd)) {
837 exit (x->function(&newJob, jobList)); 868 exit (x->function(newJob, jobList));
838 } 869 }
839 } 870 }
840#ifdef BB_FEATURE_SH_STANDALONE_SHELL 871#ifdef BB_FEATURE_SH_STANDALONE_SHELL
@@ -842,24 +873,24 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
842 /* TODO: Add matching when paths are appended (i.e. 'cat' currently 873 /* TODO: Add matching when paths are appended (i.e. 'cat' currently
843 * works, but '/bin/cat' doesn't ) */ 874 * works, but '/bin/cat' doesn't ) */
844 while (a->name != 0) { 875 while (a->name != 0) {
845 if (strcmp(newJob.progs[i].argv[0], a->name) == 0) { 876 if (strcmp(newJob->progs[i].argv[0], a->name) == 0) {
846 int argc; 877 int argc;
847 char** argv=newJob.progs[i].argv; 878 char** argv=newJob->progs[i].argv;
848 for(argc=0;*argv!=NULL; argv++, argc++); 879 for(argc=0;*argv!=NULL; argv++, argc++);
849 exit((*(a->main)) (argc, newJob.progs[i].argv)); 880 exit((*(a->main)) (argc, newJob->progs[i].argv));
850 } 881 }
851 a++; 882 a++;
852 } 883 }
853#endif 884#endif
854 885
855 execvp(newJob.progs[i].argv[0], newJob.progs[i].argv); 886 execvp(newJob->progs[i].argv[0], newJob->progs[i].argv);
856 fatalError("%s: %s\n", newJob.progs[i].argv[0], 887 fatalError("%s: %s\n", newJob->progs[i].argv[0],
857 strerror(errno)); 888 strerror(errno));
858 } 889 }
859 890
860 /* put our child in the process group whose leader is the 891 /* put our child in the process group whose leader is the
861 first process in this pipe */ 892 first process in this pipe */
862 setpgid(newJob.progs[i].pid, newJob.progs[0].pid); 893 setpgid(newJob->progs[i].pid, newJob->progs[0].pid);
863 894
864 if (nextin != 0) 895 if (nextin != 0)
865 close(nextin); 896 close(nextin);
@@ -871,24 +902,24 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
871 nextin = pipefds[0]; 902 nextin = pipefds[0];
872 } 903 }
873 904
874 newJob.pgrp = newJob.progs[0].pid; 905 newJob->pgrp = newJob->progs[0].pid;
875 906
876 /* find the ID for the job to use */ 907 /* find the ID for the job to use */
877 newJob.jobId = 1; 908 newJob->jobId = 1;
878 for (job = jobList->head; job; job = job->next) 909 for (job = jobList->head; job; job = job->next)
879 if (job->jobId >= newJob.jobId) 910 if (job->jobId >= newJob->jobId)
880 newJob.jobId = job->jobId + 1; 911 newJob->jobId = job->jobId + 1;
881 912
882 /* add the job to the list of running jobs */ 913 /* add the job to the list of running jobs */
883 if (!jobList->head) { 914 if (!jobList->head) {
884 job = jobList->head = malloc(sizeof(*job)); 915 job = jobList->head = xmalloc(sizeof(*job));
885 } else { 916 } else {
886 for (job = jobList->head; job->next; job = job->next); 917 for (job = jobList->head; job->next; job = job->next);
887 job->next = malloc(sizeof(*job)); 918 job->next = xmalloc(sizeof(*job));
888 job = job->next; 919 job = job->next;
889 } 920 }
890 921
891 *job = newJob; 922 *job = *newJob;
892 job->next = NULL; 923 job->next = NULL;
893 job->runningProgs = job->numProgs; 924 job->runningProgs = job->numProgs;
894 job->stoppedProgs = 0; 925 job->stoppedProgs = 0;
@@ -897,13 +928,13 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
897 /* we don't wait for background jobs to return -- append it 928 /* we don't wait for background jobs to return -- append it
898 to the list of backgrounded jobs and leave it alone */ 929 to the list of backgrounded jobs and leave it alone */
899 printf("[%d] %d\n", job->jobId, 930 printf("[%d] %d\n", job->jobId,
900 newJob.progs[newJob.numProgs - 1].pid); 931 newJob->progs[newJob->numProgs - 1].pid);
901 } else { 932 } else {
902 jobList->fg = job; 933 jobList->fg = job;
903 934
904 /* move the new process group into the foreground */ 935 /* move the new process group into the foreground */
905 /* suppress messages when run from /linuxrc mag@sysgo.de */ 936 /* suppress messages when run from /linuxrc mag@sysgo.de */
906 if (tcsetpgrp(0, newJob.pgrp) && errno != ENOTTY) 937 if (tcsetpgrp(0, newJob->pgrp) && errno != ENOTTY)
907 perror("tcsetpgrp"); 938 perror("tcsetpgrp");
908 } 939 }
909 940
@@ -982,9 +1013,11 @@ static int busy_loop(FILE * input)
982 nextCommand = command; 1013 nextCommand = command;
983 } 1014 }
984 1015
985 if (!parseCommand(&nextCommand, &newJob, &inBg) && 1016 if (!parseCommand(&nextCommand, &newJob, &jobList, &inBg) &&
986 newJob.numProgs) { 1017 newJob.numProgs) {
987 runCommand(newJob, &jobList, inBg); 1018 runCommand(&newJob, &jobList, inBg);
1019 } else {
1020 nextCommand=NULL;
988 } 1021 }
989 } else { 1022 } else {
990 /* a job is running in the foreground; wait for it */ 1023 /* a job is running in the foreground; wait for it */