aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2000-07-18 08:16:39 +0000
committerEric Andersen <andersen@codepoet.org>2000-07-18 08:16:39 +0000
commit6efc48c1aebfc7bebd05c6f9c21cc0f9014abbd0 (patch)
tree2bf45b0b615aeead7d14492a43e46b66de64cd90
parent9c5fcc3408626c46bc5187554e950b981143bb38 (diff)
downloadbusybox-w32-6efc48c1aebfc7bebd05c6f9c21cc0f9014abbd0.tar.gz
busybox-w32-6efc48c1aebfc7bebd05c6f9c21cc0f9014abbd0.tar.bz2
busybox-w32-6efc48c1aebfc7bebd05c6f9c21cc0f9014abbd0.zip
Sigh -- can't sleep. Clean up some mem leaks, fixed some bugs.
-Erik
-rw-r--r--lash.c82
-rw-r--r--sh.c82
-rw-r--r--shell/lash.c82
3 files changed, 129 insertions, 117 deletions
diff --git a/lash.c b/lash.c
index c9ef39f49..6029eaa5c 100644
--- a/lash.c
+++ b/lash.c
@@ -46,10 +46,7 @@
46#include "cmdedit.h" 46#include "cmdedit.h"
47#endif 47#endif
48 48
49#define bb_need_full_version 49#define MAX_LINE 256 /* size of input buffer for `read' builtin */
50#define BB_DECLARE_EXTERN
51#include "messages.c"
52
53#define MAX_READ 128 /* size of input buffer for `read' builtin */ 50#define MAX_READ 128 /* size of input buffer for `read' builtin */
54#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n" 51#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
55 52
@@ -147,7 +144,7 @@ static struct builtInCommand bltins_forking[] = {
147}; 144};
148 145
149static char *prompt = "# "; 146static char *prompt = "# ";
150static char *cwd = NULL; 147static char *cwd;
151static char *local_pending_command = NULL; 148static char *local_pending_command = NULL;
152 149
153#ifdef BB_FEATURE_SH_COMMAND_EDITING 150#ifdef BB_FEATURE_SH_COMMAND_EDITING
@@ -175,7 +172,7 @@ static int builtin_cd(struct job *cmd, struct jobSet *junk)
175 printf("cd: %s: %s\n", newdir, strerror(errno)); 172 printf("cd: %s: %s\n", newdir, strerror(errno));
176 return FALSE; 173 return FALSE;
177 } 174 }
178 getcwd(cwd, sizeof(cwd)); 175 getcwd(cwd, sizeof(char)*MAX_LINE);
179 176
180 return TRUE; 177 return TRUE;
181} 178}
@@ -289,7 +286,7 @@ static int builtin_jobs(struct job *dummy, struct jobSet *jobList)
289/* built-in 'pwd' handler */ 286/* built-in 'pwd' handler */
290static int builtin_pwd(struct job *dummy, struct jobSet *junk) 287static int builtin_pwd(struct job *dummy, struct jobSet *junk)
291{ 288{
292 getcwd(cwd, sizeof(cwd)); 289 getcwd(cwd, sizeof(char)*MAX_LINE);
293 fprintf(stdout, "%s\n", cwd); 290 fprintf(stdout, "%s\n", cwd);
294 return TRUE; 291 return TRUE;
295} 292}
@@ -780,13 +777,8 @@ static int parseCommand(char **commandPtr, struct job *job, struct jobSet *jobLi
780 return 1; 777 return 1;
781 } 778 }
782 779
783 /* Make a copy of any stuff left over in the command
784 * line after the second backtick */
785 charptr2 = xmalloc(strlen(ptr)+1);
786 memcpy(charptr2, ptr+1, strlen(ptr));
787
788 /* Make some space to hold just the backticked command */ 780 /* Make some space to hold just the backticked command */
789 charptr1 = xmalloc(1+ptr-src); 781 charptr1 = charptr2 = xmalloc(1+ptr-src);
790 snprintf(charptr1, 1+ptr-src, src); 782 snprintf(charptr1, 1+ptr-src, src);
791 newJob = xmalloc(sizeof(struct job)); 783 newJob = xmalloc(sizeof(struct job));
792 /* Now parse and run the backticked command */ 784 /* Now parse and run the backticked command */
@@ -796,7 +788,14 @@ static int parseCommand(char **commandPtr, struct job *job, struct jobSet *jobLi
796 runCommand(newJob, &njobList, 0, pipefd); 788 runCommand(newJob, &njobList, 0, pipefd);
797 } 789 }
798 checkJobs(jobList); 790 checkJobs(jobList);
799 free(charptr1); 791 freeJob(newJob);
792 free(charptr2);
793
794 /* Make a copy of any stuff left over in the command
795 * line after the second backtick */
796 charptr2 = xmalloc(strlen(ptr)+1);
797 memcpy(charptr2, ptr+1, strlen(ptr));
798
800 799
801 /* Copy the output from the backtick-ed command into the 800 /* Copy the output from the backtick-ed command into the
802 * command line, making extra room as needed */ 801 * command line, making extra room as needed */
@@ -819,13 +818,12 @@ static int parseCommand(char **commandPtr, struct job *job, struct jobSet *jobLi
819 /* Now paste into the *commandPtr all the stuff 818 /* Now paste into the *commandPtr all the stuff
820 * leftover after the second backtick */ 819 * leftover after the second backtick */
821 memcpy(src, charptr2, strlen(charptr2)); 820 memcpy(src, charptr2, strlen(charptr2));
822 fprintf(stderr,"*commandPtr='%s'\n", *commandPtr);
823 free(charptr2); 821 free(charptr2);
824 822
825
826 /* Now recursively call parseCommand to deal with the new 823 /* Now recursively call parseCommand to deal with the new
827 * and improved version of the command line with the backtick 824 * and improved version of the command line with the backtick
828 * results expanded in place... */ 825 * results expanded in place... */
826 freeJob(job);
829 return(parseCommand(commandPtr, job, jobList, isBg)); 827 return(parseCommand(commandPtr, job, jobList, isBg));
830 } 828 }
831 break; 829 break;
@@ -863,24 +861,29 @@ static int parseCommand(char **commandPtr, struct job *job, struct jobSet *jobLi
863 return 0; 861 return 0;
864} 862}
865 863
866
867static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int outPipe[2]) 864static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int outPipe[2])
868{ 865{
869 struct job *job; 866 struct job *job;
870 int nextin=0, nextout, stdoutfd=fileno(stdout);
871 int i; 867 int i;
868 int nextin, nextout;
872 int pipefds[2]; /* pipefd[0] is for reading */ 869 int pipefds[2]; /* pipefd[0] is for reading */
873 struct builtInCommand *x; 870 struct builtInCommand *x;
874#ifdef BB_FEATURE_SH_STANDALONE_SHELL 871#ifdef BB_FEATURE_SH_STANDALONE_SHELL
875 const struct BB_applet *a = applets; 872 const struct BB_applet *a = applets;
876#endif 873#endif
877 874
875
876 nextin = 0, nextout = 1;
878 for (i = 0; i < newJob->numProgs; i++) { 877 for (i = 0; i < newJob->numProgs; i++) {
879 if ((i + 1) < newJob->numProgs) { 878 if ((i + 1) < newJob->numProgs) {
880 pipe(pipefds); 879 pipe(pipefds);
881 nextout = pipefds[1]; 880 nextout = pipefds[1];
882 } else { 881 } else {
883 nextout = stdoutfd; 882 if (outPipe[1]!=-1) {
883 nextout = outPipe[1];
884 } else {
885 nextout = 1;
886 }
884 } 887 }
885 888
886 /* Check if the command matches any non-forking builtins */ 889 /* Check if the command matches any non-forking builtins */
@@ -895,15 +898,18 @@ static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int
895 898
896 if (outPipe[1]!=-1) { 899 if (outPipe[1]!=-1) {
897 close(outPipe[0]); 900 close(outPipe[0]);
898 nextout = stdoutfd = outPipe[1]; 901 }
902 if (nextin != 0) {
903 dup2(nextin, 0);
904 close(nextin);
905 }
906
907 if (nextout != 1) {
899 dup2(nextout, 1); 908 dup2(nextout, 1);
900 dup2(nextout, 2); 909 dup2(nextout, 2);
901 close(nextout); 910 close(nextout);
902 } 911 }
903 912
904 //dup2(nextin, 0);
905 //close(nextin);
906
907 /* explicit redirections override pipes */ 913 /* explicit redirections override pipes */
908 setupRedirections(newJob->progs + i); 914 setupRedirections(newJob->progs + i);
909 915
@@ -915,8 +921,8 @@ static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int
915 } 921 }
916#ifdef BB_FEATURE_SH_STANDALONE_SHELL 922#ifdef BB_FEATURE_SH_STANDALONE_SHELL
917 /* Check if the command matches any busybox internal commands here */ 923 /* Check if the command matches any busybox internal commands here */
918 /* TODO: Add matching on commands with paths appended (i.e. 'cat' 924 /* TODO: Add matching when paths are appended (i.e. 'cat' currently
919 * currently works, but '/bin/cat' doesn't ) */ 925 * works, but '/bin/cat' doesn't ) */
920 while (a->name != 0) { 926 while (a->name != 0) {
921 if (strcmp(newJob->progs[i].argv[0], a->name) == 0) { 927 if (strcmp(newJob->progs[i].argv[0], a->name) == 0) {
922 int argc; 928 int argc;
@@ -929,20 +935,19 @@ static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int
929#endif 935#endif
930 936
931 execvp(newJob->progs[i].argv[0], newJob->progs[i].argv); 937 execvp(newJob->progs[i].argv[0], newJob->progs[i].argv);
932 fatalError("%s: %s\n", newJob->progs[i].argv[0], 938 fatalError("sh: %s: %s\n", newJob->progs[i].argv[0],
933 strerror(errno)); 939 strerror(errno));
934 } 940 }
935 if (outPipe[1]!=-1) { 941 if (outPipe[1]!=-1) {
936 close(outPipe[1]); 942 close(outPipe[1]);
937 } 943 }
938 944
939 /* put our child in the process group whose leader is the 945 /* put our child in the process group whose leader is the
940 first process in this pipe */ 946 first process in this pipe */
941 setpgid(newJob->progs[i].pid, newJob->progs[0].pid); 947 setpgid(newJob->progs[i].pid, newJob->progs[0].pid);
942
943 if (nextin != 0) 948 if (nextin != 0)
944 close(nextin); 949 close(nextin);
945 if (nextout != stdoutfd) 950 if (nextout != 1)
946 close(nextout); 951 close(nextout);
947 952
948 /* If there isn't another process, nextin is garbage 953 /* If there isn't another process, nextin is garbage
@@ -960,10 +965,10 @@ static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int
960 965
961 /* add the job to the list of running jobs */ 966 /* add the job to the list of running jobs */
962 if (!jobList->head) { 967 if (!jobList->head) {
963 job = jobList->head = xmalloc(sizeof(*job)); 968 job = jobList->head = malloc(sizeof(*job));
964 } else { 969 } else {
965 for (job = jobList->head; job->next; job = job->next); 970 for (job = jobList->head; job->next; job = job->next);
966 job->next = xmalloc(sizeof(*job)); 971 job->next = malloc(sizeof(*job));
967 job = job->next; 972 job = job->next;
968 } 973 }
969 974
@@ -1066,9 +1071,9 @@ static int busy_loop(FILE * input)
1066 int pipefds[2] = {-1,-1}; 1071 int pipefds[2] = {-1,-1};
1067 runCommand(&newJob, &jobList, inBg, pipefds); 1072 runCommand(&newJob, &jobList, inBg, pipefds);
1068 } else { 1073 } else {
1069 nextCommand=NULL;
1070 free(command); 1074 free(command);
1071 command = (char *) calloc(BUFSIZ, sizeof(char)); 1075 command = (char *) calloc(BUFSIZ, sizeof(char));
1076 nextCommand = NULL;
1072 } 1077 }
1073 } else { 1078 } else {
1074 /* a job is running in the foreground; wait for it */ 1079 /* a job is running in the foreground; wait for it */
@@ -1123,16 +1128,14 @@ static int busy_loop(FILE * input)
1123} 1128}
1124 1129
1125 1130
1131
1126int shell_main(int argc, char **argv) 1132int shell_main(int argc, char **argv)
1127{ 1133{
1128 FILE *input = stdin; 1134 FILE *input = stdin;
1129 1135
1130 /* initialize the cwd */ 1136 /* initialize the cwd -- this is never freed...*/
1131 cwd = (char *) calloc(BUFSIZ, sizeof(char)); 1137 cwd=(char*)xmalloc(sizeof(char)*MAX_LINE+1);
1132 if (cwd == 0) { 1138 getcwd(cwd, sizeof(char)*MAX_LINE);
1133 fatalError("out of memory\n");
1134 }
1135 getcwd(cwd, sizeof(char)*BUFSIZ);
1136 1139
1137#ifdef BB_FEATURE_SH_COMMAND_EDITING 1140#ifdef BB_FEATURE_SH_COMMAND_EDITING
1138 cmdedit_init(); 1141 cmdedit_init();
@@ -1144,8 +1147,9 @@ int shell_main(int argc, char **argv)
1144 // builtin_source("/etc/profile"); 1147 // builtin_source("/etc/profile");
1145 //} 1148 //}
1146 1149
1150
1147 if (argc < 2) { 1151 if (argc < 2) {
1148 fprintf(stdout, "\n\n%s Built-in shell\n", full_version); 1152 fprintf(stdout, "\n\nBusyBox v%s (%s) Built-in shell\n", BB_VER, BB_BT);
1149 fprintf(stdout, "Enter 'help' for a list of built-in commands.\n\n"); 1153 fprintf(stdout, "Enter 'help' for a list of built-in commands.\n\n");
1150 } else { 1154 } else {
1151 if (argv[1][0]=='-' && argv[1][1]=='c') { 1155 if (argv[1][0]=='-' && argv[1][1]=='c') {
diff --git a/sh.c b/sh.c
index c9ef39f49..6029eaa5c 100644
--- a/sh.c
+++ b/sh.c
@@ -46,10 +46,7 @@
46#include "cmdedit.h" 46#include "cmdedit.h"
47#endif 47#endif
48 48
49#define bb_need_full_version 49#define MAX_LINE 256 /* size of input buffer for `read' builtin */
50#define BB_DECLARE_EXTERN
51#include "messages.c"
52
53#define MAX_READ 128 /* size of input buffer for `read' builtin */ 50#define MAX_READ 128 /* size of input buffer for `read' builtin */
54#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n" 51#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
55 52
@@ -147,7 +144,7 @@ static struct builtInCommand bltins_forking[] = {
147}; 144};
148 145
149static char *prompt = "# "; 146static char *prompt = "# ";
150static char *cwd = NULL; 147static char *cwd;
151static char *local_pending_command = NULL; 148static char *local_pending_command = NULL;
152 149
153#ifdef BB_FEATURE_SH_COMMAND_EDITING 150#ifdef BB_FEATURE_SH_COMMAND_EDITING
@@ -175,7 +172,7 @@ static int builtin_cd(struct job *cmd, struct jobSet *junk)
175 printf("cd: %s: %s\n", newdir, strerror(errno)); 172 printf("cd: %s: %s\n", newdir, strerror(errno));
176 return FALSE; 173 return FALSE;
177 } 174 }
178 getcwd(cwd, sizeof(cwd)); 175 getcwd(cwd, sizeof(char)*MAX_LINE);
179 176
180 return TRUE; 177 return TRUE;
181} 178}
@@ -289,7 +286,7 @@ static int builtin_jobs(struct job *dummy, struct jobSet *jobList)
289/* built-in 'pwd' handler */ 286/* built-in 'pwd' handler */
290static int builtin_pwd(struct job *dummy, struct jobSet *junk) 287static int builtin_pwd(struct job *dummy, struct jobSet *junk)
291{ 288{
292 getcwd(cwd, sizeof(cwd)); 289 getcwd(cwd, sizeof(char)*MAX_LINE);
293 fprintf(stdout, "%s\n", cwd); 290 fprintf(stdout, "%s\n", cwd);
294 return TRUE; 291 return TRUE;
295} 292}
@@ -780,13 +777,8 @@ static int parseCommand(char **commandPtr, struct job *job, struct jobSet *jobLi
780 return 1; 777 return 1;
781 } 778 }
782 779
783 /* Make a copy of any stuff left over in the command
784 * line after the second backtick */
785 charptr2 = xmalloc(strlen(ptr)+1);
786 memcpy(charptr2, ptr+1, strlen(ptr));
787
788 /* Make some space to hold just the backticked command */ 780 /* Make some space to hold just the backticked command */
789 charptr1 = xmalloc(1+ptr-src); 781 charptr1 = charptr2 = xmalloc(1+ptr-src);
790 snprintf(charptr1, 1+ptr-src, src); 782 snprintf(charptr1, 1+ptr-src, src);
791 newJob = xmalloc(sizeof(struct job)); 783 newJob = xmalloc(sizeof(struct job));
792 /* Now parse and run the backticked command */ 784 /* Now parse and run the backticked command */
@@ -796,7 +788,14 @@ static int parseCommand(char **commandPtr, struct job *job, struct jobSet *jobLi
796 runCommand(newJob, &njobList, 0, pipefd); 788 runCommand(newJob, &njobList, 0, pipefd);
797 } 789 }
798 checkJobs(jobList); 790 checkJobs(jobList);
799 free(charptr1); 791 freeJob(newJob);
792 free(charptr2);
793
794 /* Make a copy of any stuff left over in the command
795 * line after the second backtick */
796 charptr2 = xmalloc(strlen(ptr)+1);
797 memcpy(charptr2, ptr+1, strlen(ptr));
798
800 799
801 /* Copy the output from the backtick-ed command into the 800 /* Copy the output from the backtick-ed command into the
802 * command line, making extra room as needed */ 801 * command line, making extra room as needed */
@@ -819,13 +818,12 @@ static int parseCommand(char **commandPtr, struct job *job, struct jobSet *jobLi
819 /* Now paste into the *commandPtr all the stuff 818 /* Now paste into the *commandPtr all the stuff
820 * leftover after the second backtick */ 819 * leftover after the second backtick */
821 memcpy(src, charptr2, strlen(charptr2)); 820 memcpy(src, charptr2, strlen(charptr2));
822 fprintf(stderr,"*commandPtr='%s'\n", *commandPtr);
823 free(charptr2); 821 free(charptr2);
824 822
825
826 /* Now recursively call parseCommand to deal with the new 823 /* Now recursively call parseCommand to deal with the new
827 * and improved version of the command line with the backtick 824 * and improved version of the command line with the backtick
828 * results expanded in place... */ 825 * results expanded in place... */
826 freeJob(job);
829 return(parseCommand(commandPtr, job, jobList, isBg)); 827 return(parseCommand(commandPtr, job, jobList, isBg));
830 } 828 }
831 break; 829 break;
@@ -863,24 +861,29 @@ static int parseCommand(char **commandPtr, struct job *job, struct jobSet *jobLi
863 return 0; 861 return 0;
864} 862}
865 863
866
867static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int outPipe[2]) 864static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int outPipe[2])
868{ 865{
869 struct job *job; 866 struct job *job;
870 int nextin=0, nextout, stdoutfd=fileno(stdout);
871 int i; 867 int i;
868 int nextin, nextout;
872 int pipefds[2]; /* pipefd[0] is for reading */ 869 int pipefds[2]; /* pipefd[0] is for reading */
873 struct builtInCommand *x; 870 struct builtInCommand *x;
874#ifdef BB_FEATURE_SH_STANDALONE_SHELL 871#ifdef BB_FEATURE_SH_STANDALONE_SHELL
875 const struct BB_applet *a = applets; 872 const struct BB_applet *a = applets;
876#endif 873#endif
877 874
875
876 nextin = 0, nextout = 1;
878 for (i = 0; i < newJob->numProgs; i++) { 877 for (i = 0; i < newJob->numProgs; i++) {
879 if ((i + 1) < newJob->numProgs) { 878 if ((i + 1) < newJob->numProgs) {
880 pipe(pipefds); 879 pipe(pipefds);
881 nextout = pipefds[1]; 880 nextout = pipefds[1];
882 } else { 881 } else {
883 nextout = stdoutfd; 882 if (outPipe[1]!=-1) {
883 nextout = outPipe[1];
884 } else {
885 nextout = 1;
886 }
884 } 887 }
885 888
886 /* Check if the command matches any non-forking builtins */ 889 /* Check if the command matches any non-forking builtins */
@@ -895,15 +898,18 @@ static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int
895 898
896 if (outPipe[1]!=-1) { 899 if (outPipe[1]!=-1) {
897 close(outPipe[0]); 900 close(outPipe[0]);
898 nextout = stdoutfd = outPipe[1]; 901 }
902 if (nextin != 0) {
903 dup2(nextin, 0);
904 close(nextin);
905 }
906
907 if (nextout != 1) {
899 dup2(nextout, 1); 908 dup2(nextout, 1);
900 dup2(nextout, 2); 909 dup2(nextout, 2);
901 close(nextout); 910 close(nextout);
902 } 911 }
903 912
904 //dup2(nextin, 0);
905 //close(nextin);
906
907 /* explicit redirections override pipes */ 913 /* explicit redirections override pipes */
908 setupRedirections(newJob->progs + i); 914 setupRedirections(newJob->progs + i);
909 915
@@ -915,8 +921,8 @@ static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int
915 } 921 }
916#ifdef BB_FEATURE_SH_STANDALONE_SHELL 922#ifdef BB_FEATURE_SH_STANDALONE_SHELL
917 /* Check if the command matches any busybox internal commands here */ 923 /* Check if the command matches any busybox internal commands here */
918 /* TODO: Add matching on commands with paths appended (i.e. 'cat' 924 /* TODO: Add matching when paths are appended (i.e. 'cat' currently
919 * currently works, but '/bin/cat' doesn't ) */ 925 * works, but '/bin/cat' doesn't ) */
920 while (a->name != 0) { 926 while (a->name != 0) {
921 if (strcmp(newJob->progs[i].argv[0], a->name) == 0) { 927 if (strcmp(newJob->progs[i].argv[0], a->name) == 0) {
922 int argc; 928 int argc;
@@ -929,20 +935,19 @@ static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int
929#endif 935#endif
930 936
931 execvp(newJob->progs[i].argv[0], newJob->progs[i].argv); 937 execvp(newJob->progs[i].argv[0], newJob->progs[i].argv);
932 fatalError("%s: %s\n", newJob->progs[i].argv[0], 938 fatalError("sh: %s: %s\n", newJob->progs[i].argv[0],
933 strerror(errno)); 939 strerror(errno));
934 } 940 }
935 if (outPipe[1]!=-1) { 941 if (outPipe[1]!=-1) {
936 close(outPipe[1]); 942 close(outPipe[1]);
937 } 943 }
938 944
939 /* put our child in the process group whose leader is the 945 /* put our child in the process group whose leader is the
940 first process in this pipe */ 946 first process in this pipe */
941 setpgid(newJob->progs[i].pid, newJob->progs[0].pid); 947 setpgid(newJob->progs[i].pid, newJob->progs[0].pid);
942
943 if (nextin != 0) 948 if (nextin != 0)
944 close(nextin); 949 close(nextin);
945 if (nextout != stdoutfd) 950 if (nextout != 1)
946 close(nextout); 951 close(nextout);
947 952
948 /* If there isn't another process, nextin is garbage 953 /* If there isn't another process, nextin is garbage
@@ -960,10 +965,10 @@ static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int
960 965
961 /* add the job to the list of running jobs */ 966 /* add the job to the list of running jobs */
962 if (!jobList->head) { 967 if (!jobList->head) {
963 job = jobList->head = xmalloc(sizeof(*job)); 968 job = jobList->head = malloc(sizeof(*job));
964 } else { 969 } else {
965 for (job = jobList->head; job->next; job = job->next); 970 for (job = jobList->head; job->next; job = job->next);
966 job->next = xmalloc(sizeof(*job)); 971 job->next = malloc(sizeof(*job));
967 job = job->next; 972 job = job->next;
968 } 973 }
969 974
@@ -1066,9 +1071,9 @@ static int busy_loop(FILE * input)
1066 int pipefds[2] = {-1,-1}; 1071 int pipefds[2] = {-1,-1};
1067 runCommand(&newJob, &jobList, inBg, pipefds); 1072 runCommand(&newJob, &jobList, inBg, pipefds);
1068 } else { 1073 } else {
1069 nextCommand=NULL;
1070 free(command); 1074 free(command);
1071 command = (char *) calloc(BUFSIZ, sizeof(char)); 1075 command = (char *) calloc(BUFSIZ, sizeof(char));
1076 nextCommand = NULL;
1072 } 1077 }
1073 } else { 1078 } else {
1074 /* a job is running in the foreground; wait for it */ 1079 /* a job is running in the foreground; wait for it */
@@ -1123,16 +1128,14 @@ static int busy_loop(FILE * input)
1123} 1128}
1124 1129
1125 1130
1131
1126int shell_main(int argc, char **argv) 1132int shell_main(int argc, char **argv)
1127{ 1133{
1128 FILE *input = stdin; 1134 FILE *input = stdin;
1129 1135
1130 /* initialize the cwd */ 1136 /* initialize the cwd -- this is never freed...*/
1131 cwd = (char *) calloc(BUFSIZ, sizeof(char)); 1137 cwd=(char*)xmalloc(sizeof(char)*MAX_LINE+1);
1132 if (cwd == 0) { 1138 getcwd(cwd, sizeof(char)*MAX_LINE);
1133 fatalError("out of memory\n");
1134 }
1135 getcwd(cwd, sizeof(char)*BUFSIZ);
1136 1139
1137#ifdef BB_FEATURE_SH_COMMAND_EDITING 1140#ifdef BB_FEATURE_SH_COMMAND_EDITING
1138 cmdedit_init(); 1141 cmdedit_init();
@@ -1144,8 +1147,9 @@ int shell_main(int argc, char **argv)
1144 // builtin_source("/etc/profile"); 1147 // builtin_source("/etc/profile");
1145 //} 1148 //}
1146 1149
1150
1147 if (argc < 2) { 1151 if (argc < 2) {
1148 fprintf(stdout, "\n\n%s Built-in shell\n", full_version); 1152 fprintf(stdout, "\n\nBusyBox v%s (%s) Built-in shell\n", BB_VER, BB_BT);
1149 fprintf(stdout, "Enter 'help' for a list of built-in commands.\n\n"); 1153 fprintf(stdout, "Enter 'help' for a list of built-in commands.\n\n");
1150 } else { 1154 } else {
1151 if (argv[1][0]=='-' && argv[1][1]=='c') { 1155 if (argv[1][0]=='-' && argv[1][1]=='c') {
diff --git a/shell/lash.c b/shell/lash.c
index c9ef39f49..6029eaa5c 100644
--- a/shell/lash.c
+++ b/shell/lash.c
@@ -46,10 +46,7 @@
46#include "cmdedit.h" 46#include "cmdedit.h"
47#endif 47#endif
48 48
49#define bb_need_full_version 49#define MAX_LINE 256 /* size of input buffer for `read' builtin */
50#define BB_DECLARE_EXTERN
51#include "messages.c"
52
53#define MAX_READ 128 /* size of input buffer for `read' builtin */ 50#define MAX_READ 128 /* size of input buffer for `read' builtin */
54#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n" 51#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
55 52
@@ -147,7 +144,7 @@ static struct builtInCommand bltins_forking[] = {
147}; 144};
148 145
149static char *prompt = "# "; 146static char *prompt = "# ";
150static char *cwd = NULL; 147static char *cwd;
151static char *local_pending_command = NULL; 148static char *local_pending_command = NULL;
152 149
153#ifdef BB_FEATURE_SH_COMMAND_EDITING 150#ifdef BB_FEATURE_SH_COMMAND_EDITING
@@ -175,7 +172,7 @@ static int builtin_cd(struct job *cmd, struct jobSet *junk)
175 printf("cd: %s: %s\n", newdir, strerror(errno)); 172 printf("cd: %s: %s\n", newdir, strerror(errno));
176 return FALSE; 173 return FALSE;
177 } 174 }
178 getcwd(cwd, sizeof(cwd)); 175 getcwd(cwd, sizeof(char)*MAX_LINE);
179 176
180 return TRUE; 177 return TRUE;
181} 178}
@@ -289,7 +286,7 @@ static int builtin_jobs(struct job *dummy, struct jobSet *jobList)
289/* built-in 'pwd' handler */ 286/* built-in 'pwd' handler */
290static int builtin_pwd(struct job *dummy, struct jobSet *junk) 287static int builtin_pwd(struct job *dummy, struct jobSet *junk)
291{ 288{
292 getcwd(cwd, sizeof(cwd)); 289 getcwd(cwd, sizeof(char)*MAX_LINE);
293 fprintf(stdout, "%s\n", cwd); 290 fprintf(stdout, "%s\n", cwd);
294 return TRUE; 291 return TRUE;
295} 292}
@@ -780,13 +777,8 @@ static int parseCommand(char **commandPtr, struct job *job, struct jobSet *jobLi
780 return 1; 777 return 1;
781 } 778 }
782 779
783 /* Make a copy of any stuff left over in the command
784 * line after the second backtick */
785 charptr2 = xmalloc(strlen(ptr)+1);
786 memcpy(charptr2, ptr+1, strlen(ptr));
787
788 /* Make some space to hold just the backticked command */ 780 /* Make some space to hold just the backticked command */
789 charptr1 = xmalloc(1+ptr-src); 781 charptr1 = charptr2 = xmalloc(1+ptr-src);
790 snprintf(charptr1, 1+ptr-src, src); 782 snprintf(charptr1, 1+ptr-src, src);
791 newJob = xmalloc(sizeof(struct job)); 783 newJob = xmalloc(sizeof(struct job));
792 /* Now parse and run the backticked command */ 784 /* Now parse and run the backticked command */
@@ -796,7 +788,14 @@ static int parseCommand(char **commandPtr, struct job *job, struct jobSet *jobLi
796 runCommand(newJob, &njobList, 0, pipefd); 788 runCommand(newJob, &njobList, 0, pipefd);
797 } 789 }
798 checkJobs(jobList); 790 checkJobs(jobList);
799 free(charptr1); 791 freeJob(newJob);
792 free(charptr2);
793
794 /* Make a copy of any stuff left over in the command
795 * line after the second backtick */
796 charptr2 = xmalloc(strlen(ptr)+1);
797 memcpy(charptr2, ptr+1, strlen(ptr));
798
800 799
801 /* Copy the output from the backtick-ed command into the 800 /* Copy the output from the backtick-ed command into the
802 * command line, making extra room as needed */ 801 * command line, making extra room as needed */
@@ -819,13 +818,12 @@ static int parseCommand(char **commandPtr, struct job *job, struct jobSet *jobLi
819 /* Now paste into the *commandPtr all the stuff 818 /* Now paste into the *commandPtr all the stuff
820 * leftover after the second backtick */ 819 * leftover after the second backtick */
821 memcpy(src, charptr2, strlen(charptr2)); 820 memcpy(src, charptr2, strlen(charptr2));
822 fprintf(stderr,"*commandPtr='%s'\n", *commandPtr);
823 free(charptr2); 821 free(charptr2);
824 822
825
826 /* Now recursively call parseCommand to deal with the new 823 /* Now recursively call parseCommand to deal with the new
827 * and improved version of the command line with the backtick 824 * and improved version of the command line with the backtick
828 * results expanded in place... */ 825 * results expanded in place... */
826 freeJob(job);
829 return(parseCommand(commandPtr, job, jobList, isBg)); 827 return(parseCommand(commandPtr, job, jobList, isBg));
830 } 828 }
831 break; 829 break;
@@ -863,24 +861,29 @@ static int parseCommand(char **commandPtr, struct job *job, struct jobSet *jobLi
863 return 0; 861 return 0;
864} 862}
865 863
866
867static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int outPipe[2]) 864static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int outPipe[2])
868{ 865{
869 struct job *job; 866 struct job *job;
870 int nextin=0, nextout, stdoutfd=fileno(stdout);
871 int i; 867 int i;
868 int nextin, nextout;
872 int pipefds[2]; /* pipefd[0] is for reading */ 869 int pipefds[2]; /* pipefd[0] is for reading */
873 struct builtInCommand *x; 870 struct builtInCommand *x;
874#ifdef BB_FEATURE_SH_STANDALONE_SHELL 871#ifdef BB_FEATURE_SH_STANDALONE_SHELL
875 const struct BB_applet *a = applets; 872 const struct BB_applet *a = applets;
876#endif 873#endif
877 874
875
876 nextin = 0, nextout = 1;
878 for (i = 0; i < newJob->numProgs; i++) { 877 for (i = 0; i < newJob->numProgs; i++) {
879 if ((i + 1) < newJob->numProgs) { 878 if ((i + 1) < newJob->numProgs) {
880 pipe(pipefds); 879 pipe(pipefds);
881 nextout = pipefds[1]; 880 nextout = pipefds[1];
882 } else { 881 } else {
883 nextout = stdoutfd; 882 if (outPipe[1]!=-1) {
883 nextout = outPipe[1];
884 } else {
885 nextout = 1;
886 }
884 } 887 }
885 888
886 /* Check if the command matches any non-forking builtins */ 889 /* Check if the command matches any non-forking builtins */
@@ -895,15 +898,18 @@ static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int
895 898
896 if (outPipe[1]!=-1) { 899 if (outPipe[1]!=-1) {
897 close(outPipe[0]); 900 close(outPipe[0]);
898 nextout = stdoutfd = outPipe[1]; 901 }
902 if (nextin != 0) {
903 dup2(nextin, 0);
904 close(nextin);
905 }
906
907 if (nextout != 1) {
899 dup2(nextout, 1); 908 dup2(nextout, 1);
900 dup2(nextout, 2); 909 dup2(nextout, 2);
901 close(nextout); 910 close(nextout);
902 } 911 }
903 912
904 //dup2(nextin, 0);
905 //close(nextin);
906
907 /* explicit redirections override pipes */ 913 /* explicit redirections override pipes */
908 setupRedirections(newJob->progs + i); 914 setupRedirections(newJob->progs + i);
909 915
@@ -915,8 +921,8 @@ static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int
915 } 921 }
916#ifdef BB_FEATURE_SH_STANDALONE_SHELL 922#ifdef BB_FEATURE_SH_STANDALONE_SHELL
917 /* Check if the command matches any busybox internal commands here */ 923 /* Check if the command matches any busybox internal commands here */
918 /* TODO: Add matching on commands with paths appended (i.e. 'cat' 924 /* TODO: Add matching when paths are appended (i.e. 'cat' currently
919 * currently works, but '/bin/cat' doesn't ) */ 925 * works, but '/bin/cat' doesn't ) */
920 while (a->name != 0) { 926 while (a->name != 0) {
921 if (strcmp(newJob->progs[i].argv[0], a->name) == 0) { 927 if (strcmp(newJob->progs[i].argv[0], a->name) == 0) {
922 int argc; 928 int argc;
@@ -929,20 +935,19 @@ static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int
929#endif 935#endif
930 936
931 execvp(newJob->progs[i].argv[0], newJob->progs[i].argv); 937 execvp(newJob->progs[i].argv[0], newJob->progs[i].argv);
932 fatalError("%s: %s\n", newJob->progs[i].argv[0], 938 fatalError("sh: %s: %s\n", newJob->progs[i].argv[0],
933 strerror(errno)); 939 strerror(errno));
934 } 940 }
935 if (outPipe[1]!=-1) { 941 if (outPipe[1]!=-1) {
936 close(outPipe[1]); 942 close(outPipe[1]);
937 } 943 }
938 944
939 /* put our child in the process group whose leader is the 945 /* put our child in the process group whose leader is the
940 first process in this pipe */ 946 first process in this pipe */
941 setpgid(newJob->progs[i].pid, newJob->progs[0].pid); 947 setpgid(newJob->progs[i].pid, newJob->progs[0].pid);
942
943 if (nextin != 0) 948 if (nextin != 0)
944 close(nextin); 949 close(nextin);
945 if (nextout != stdoutfd) 950 if (nextout != 1)
946 close(nextout); 951 close(nextout);
947 952
948 /* If there isn't another process, nextin is garbage 953 /* If there isn't another process, nextin is garbage
@@ -960,10 +965,10 @@ static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int
960 965
961 /* add the job to the list of running jobs */ 966 /* add the job to the list of running jobs */
962 if (!jobList->head) { 967 if (!jobList->head) {
963 job = jobList->head = xmalloc(sizeof(*job)); 968 job = jobList->head = malloc(sizeof(*job));
964 } else { 969 } else {
965 for (job = jobList->head; job->next; job = job->next); 970 for (job = jobList->head; job->next; job = job->next);
966 job->next = xmalloc(sizeof(*job)); 971 job->next = malloc(sizeof(*job));
967 job = job->next; 972 job = job->next;
968 } 973 }
969 974
@@ -1066,9 +1071,9 @@ static int busy_loop(FILE * input)
1066 int pipefds[2] = {-1,-1}; 1071 int pipefds[2] = {-1,-1};
1067 runCommand(&newJob, &jobList, inBg, pipefds); 1072 runCommand(&newJob, &jobList, inBg, pipefds);
1068 } else { 1073 } else {
1069 nextCommand=NULL;
1070 free(command); 1074 free(command);
1071 command = (char *) calloc(BUFSIZ, sizeof(char)); 1075 command = (char *) calloc(BUFSIZ, sizeof(char));
1076 nextCommand = NULL;
1072 } 1077 }
1073 } else { 1078 } else {
1074 /* a job is running in the foreground; wait for it */ 1079 /* a job is running in the foreground; wait for it */
@@ -1123,16 +1128,14 @@ static int busy_loop(FILE * input)
1123} 1128}
1124 1129
1125 1130
1131
1126int shell_main(int argc, char **argv) 1132int shell_main(int argc, char **argv)
1127{ 1133{
1128 FILE *input = stdin; 1134 FILE *input = stdin;
1129 1135
1130 /* initialize the cwd */ 1136 /* initialize the cwd -- this is never freed...*/
1131 cwd = (char *) calloc(BUFSIZ, sizeof(char)); 1137 cwd=(char*)xmalloc(sizeof(char)*MAX_LINE+1);
1132 if (cwd == 0) { 1138 getcwd(cwd, sizeof(char)*MAX_LINE);
1133 fatalError("out of memory\n");
1134 }
1135 getcwd(cwd, sizeof(char)*BUFSIZ);
1136 1139
1137#ifdef BB_FEATURE_SH_COMMAND_EDITING 1140#ifdef BB_FEATURE_SH_COMMAND_EDITING
1138 cmdedit_init(); 1141 cmdedit_init();
@@ -1144,8 +1147,9 @@ int shell_main(int argc, char **argv)
1144 // builtin_source("/etc/profile"); 1147 // builtin_source("/etc/profile");
1145 //} 1148 //}
1146 1149
1150
1147 if (argc < 2) { 1151 if (argc < 2) {
1148 fprintf(stdout, "\n\n%s Built-in shell\n", full_version); 1152 fprintf(stdout, "\n\nBusyBox v%s (%s) Built-in shell\n", BB_VER, BB_BT);
1149 fprintf(stdout, "Enter 'help' for a list of built-in commands.\n\n"); 1153 fprintf(stdout, "Enter 'help' for a list of built-in commands.\n\n");
1150 } else { 1154 } else {
1151 if (argv[1][0]=='-' && argv[1][1]=='c') { 1155 if (argv[1][0]=='-' && argv[1][1]=='c') {