diff options
| author | Eric Andersen <andersen@codepoet.org> | 2000-07-18 08:16:39 +0000 |
|---|---|---|
| committer | Eric Andersen <andersen@codepoet.org> | 2000-07-18 08:16:39 +0000 |
| commit | 6efc48c1aebfc7bebd05c6f9c21cc0f9014abbd0 (patch) | |
| tree | 2bf45b0b615aeead7d14492a43e46b66de64cd90 /shell | |
| parent | 9c5fcc3408626c46bc5187554e950b981143bb38 (diff) | |
| download | busybox-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
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/lash.c | 82 |
1 files changed, 43 insertions, 39 deletions
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 | ||
| 149 | static char *prompt = "# "; | 146 | static char *prompt = "# "; |
| 150 | static char *cwd = NULL; | 147 | static char *cwd; |
| 151 | static char *local_pending_command = NULL; | 148 | static 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 */ |
| 290 | static int builtin_pwd(struct job *dummy, struct jobSet *junk) | 287 | static 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 | |||
| 867 | static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int outPipe[2]) | 864 | static 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 | |||
| 1126 | int shell_main(int argc, char **argv) | 1132 | int 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') { |
