diff options
| author | Eric Andersen <andersen@codepoet.org> | 2000-06-28 16:56:25 +0000 |
|---|---|---|
| committer | Eric Andersen <andersen@codepoet.org> | 2000-06-28 16:56:25 +0000 |
| commit | 1c314ad655af140b8ef4a271f4e657bf50218236 (patch) | |
| tree | 55bc210e98047006b69c5d3831eb3b3fbcfdc576 /shell | |
| parent | 47cac6779a4457e29b956aa864f0292fa7706bc1 (diff) | |
| download | busybox-w32-1c314ad655af140b8ef4a271f4e657bf50218236.tar.gz busybox-w32-1c314ad655af140b8ef4a271f4e657bf50218236.tar.bz2 busybox-w32-1c314ad655af140b8ef4a271f4e657bf50218236.zip | |
* Fixed a _horrible_ bug where 'tar -tvf' could unlink
local files!!! Fix thanks to Marius Groeger <mgroeger@sysgo.de>
* Added support for "sh -c command args...", also thanks to
Marius Groeger <mgroeger@sysgo.de>
-Erik
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/lash.c | 76 |
1 files changed, 56 insertions, 20 deletions
diff --git a/shell/lash.c b/shell/lash.c index 56d94258c..785e9cc3f 100644 --- a/shell/lash.c +++ b/shell/lash.c | |||
| @@ -131,8 +131,8 @@ static struct builtInCommand bltins_forking[] = { | |||
| 131 | }; | 131 | }; |
| 132 | 132 | ||
| 133 | static const char shell_usage[] = | 133 | static const char shell_usage[] = |
| 134 | 134 | "sh [FILE]...\n" | |
| 135 | "sh [FILE]...\n" | 135 | " or: sh -c command [args]...\n" |
| 136 | #ifndef BB_FEATURE_TRIVIAL_HELP | 136 | #ifndef BB_FEATURE_TRIVIAL_HELP |
| 137 | "\nlash: The BusyBox command interpreter (shell).\n\n" | 137 | "\nlash: The BusyBox command interpreter (shell).\n\n" |
| 138 | #endif | 138 | #endif |
| @@ -140,6 +140,7 @@ static const char shell_usage[] = | |||
| 140 | 140 | ||
| 141 | static char cwd[1024]; | 141 | static char cwd[1024]; |
| 142 | static char *prompt = "# "; | 142 | static char *prompt = "# "; |
| 143 | static char *local_pending_command = NULL; | ||
| 143 | 144 | ||
| 144 | #ifdef BB_FEATURE_SH_COMMAND_EDITING | 145 | #ifdef BB_FEATURE_SH_COMMAND_EDITING |
| 145 | void win_changed(int sig) | 146 | void win_changed(int sig) |
| @@ -225,8 +226,9 @@ static int shell_fg_bg(struct job *cmd, struct jobSet *jobList) | |||
| 225 | 226 | ||
| 226 | if (*cmd->progs[0].argv[0] == 'f') { | 227 | if (*cmd->progs[0].argv[0] == 'f') { |
| 227 | /* Make this job the foreground job */ | 228 | /* Make this job the foreground job */ |
| 228 | if (tcsetpgrp(0, job->pgrp)) | 229 | /* suppress messages when run from /linuxrc mag@sysgo.de */ |
| 229 | perror("tcsetpgrp"); | 230 | if (tcsetpgrp(0, job->pgrp) && errno != ENOTTY) |
| 231 | perror("tcsetpgrp"); | ||
| 230 | jobList->fg = job; | 232 | jobList->fg = job; |
| 231 | } | 233 | } |
| 232 | 234 | ||
| @@ -411,6 +413,17 @@ static void checkJobs(struct jobSet *jobList) | |||
| 411 | 413 | ||
| 412 | static int getCommand(FILE * source, char *command) | 414 | static int getCommand(FILE * source, char *command) |
| 413 | { | 415 | { |
| 416 | if (source == NULL) { | ||
| 417 | if (local_pending_command) { | ||
| 418 | /* a command specified (-c option): return it & mark it done */ | ||
| 419 | strcpy(command, local_pending_command); | ||
| 420 | free(local_pending_command); | ||
| 421 | local_pending_command = NULL; | ||
| 422 | return 0; | ||
| 423 | } | ||
| 424 | return 1; | ||
| 425 | } | ||
| 426 | |||
| 414 | if (source == stdin) { | 427 | if (source == stdin) { |
| 415 | #ifdef BB_FEATURE_SH_COMMAND_EDITING | 428 | #ifdef BB_FEATURE_SH_COMMAND_EDITING |
| 416 | int len; | 429 | int len; |
| @@ -842,7 +855,8 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg) | |||
| 842 | jobList->fg = job; | 855 | jobList->fg = job; |
| 843 | 856 | ||
| 844 | /* move the new process group into the foreground */ | 857 | /* move the new process group into the foreground */ |
| 845 | if (tcsetpgrp(0, newJob.pgrp)) | 858 | /* suppress messages when run from /linuxrc mag@sysgo.de */ |
| 859 | if (tcsetpgrp(0, newJob.pgrp) && errno != ENOTTY) | ||
| 846 | perror("tcsetpgrp"); | 860 | perror("tcsetpgrp"); |
| 847 | } | 861 | } |
| 848 | 862 | ||
| @@ -894,10 +908,14 @@ static int busy_loop(FILE * input) | |||
| 894 | char *nextCommand = NULL; | 908 | char *nextCommand = NULL; |
| 895 | struct jobSet jobList = { NULL, NULL }; | 909 | struct jobSet jobList = { NULL, NULL }; |
| 896 | struct job newJob; | 910 | struct job newJob; |
| 911 | pid_t parent_pgrp; | ||
| 897 | int i; | 912 | int i; |
| 898 | int status; | 913 | int status; |
| 899 | int inBg; | 914 | int inBg; |
| 900 | 915 | ||
| 916 | /* save current owner of TTY so we can restore it on exit */ | ||
| 917 | parent_pgrp = tcgetpgrp(0); | ||
| 918 | |||
| 901 | command = (char *) calloc(BUFSIZ, sizeof(char)); | 919 | command = (char *) calloc(BUFSIZ, sizeof(char)); |
| 902 | 920 | ||
| 903 | /* don't pay any attention to this signal; it just confuses | 921 | /* don't pay any attention to this signal; it just confuses |
| @@ -939,10 +957,6 @@ static int busy_loop(FILE * input) | |||
| 939 | 957 | ||
| 940 | removeJob(&jobList, jobList.fg); | 958 | removeJob(&jobList, jobList.fg); |
| 941 | jobList.fg = NULL; | 959 | jobList.fg = NULL; |
| 942 | |||
| 943 | /* move the shell to the foreground */ | ||
| 944 | if (tcsetpgrp(0, getpid())) | ||
| 945 | perror("tcsetpgrp"); | ||
| 946 | } | 960 | } |
| 947 | } else { | 961 | } else { |
| 948 | /* the child was stopped */ | 962 | /* the child was stopped */ |
| @@ -958,13 +972,18 @@ static int busy_loop(FILE * input) | |||
| 958 | 972 | ||
| 959 | if (!jobList.fg) { | 973 | if (!jobList.fg) { |
| 960 | /* move the shell to the foreground */ | 974 | /* move the shell to the foreground */ |
| 961 | if (tcsetpgrp(0, getpid())) | 975 | /* suppress messages when run from /linuxrc mag@sysgo.de */ |
| 962 | perror("tcsetpgrp"); | 976 | if (tcsetpgrp(0, getpid()) && errno != ENOTTY) |
| 977 | perror("tcsetpgrp"); | ||
| 963 | } | 978 | } |
| 964 | } | 979 | } |
| 965 | } | 980 | } |
| 966 | free(command); | 981 | free(command); |
| 967 | 982 | ||
| 983 | /* return controlling TTY back to parent process group before exiting */ | ||
| 984 | if (tcsetpgrp(0, parent_pgrp)) | ||
| 985 | perror("tcsetpgrp"); | ||
| 986 | |||
| 968 | return 0; | 987 | return 0; |
| 969 | } | 988 | } |
| 970 | 989 | ||
| @@ -973,9 +992,6 @@ int shell_main(int argc, char **argv) | |||
| 973 | { | 992 | { |
| 974 | FILE *input = stdin; | 993 | FILE *input = stdin; |
| 975 | 994 | ||
| 976 | if (argc > 2) { | ||
| 977 | usage(shell_usage); | ||
| 978 | } | ||
| 979 | /* initialize the cwd */ | 995 | /* initialize the cwd */ |
| 980 | getcwd(cwd, sizeof(cwd)); | 996 | getcwd(cwd, sizeof(cwd)); |
| 981 | 997 | ||
| @@ -993,13 +1009,33 @@ int shell_main(int argc, char **argv) | |||
| 993 | fprintf(stdout, "\n\nBusyBox v%s (%s) Built-in shell\n", BB_VER, BB_BT); | 1009 | fprintf(stdout, "\n\nBusyBox v%s (%s) Built-in shell\n", BB_VER, BB_BT); |
| 994 | fprintf(stdout, "Enter 'help' for a list of built-in commands.\n\n"); | 1010 | fprintf(stdout, "Enter 'help' for a list of built-in commands.\n\n"); |
| 995 | } else { | 1011 | } else { |
| 996 | if (*argv[1]=='-') { | 1012 | if (argv[1][0]=='-' && argv[1][1]=='c') { |
| 997 | usage("sh\n\nlash -- the BusyBox LAme SHell (command interpreter)\n"); | 1013 | int i; |
| 1014 | local_pending_command = (char *) calloc(BUFSIZ, sizeof(char)); | ||
| 1015 | if (local_pending_command == 0) { | ||
| 1016 | fatalError("sh: out of memory\n"); | ||
| 1017 | } | ||
| 1018 | for(i=2; i<argc; i++) | ||
| 1019 | { | ||
| 1020 | if (strlen(local_pending_command) + strlen(argv[i]) >= BUFSIZ) { | ||
| 1021 | fatalError("sh: commands for -c option too long\n"); | ||
| 1022 | } | ||
| 1023 | strcat(local_pending_command, argv[i]); | ||
| 1024 | if (i + 1 < argc) | ||
| 1025 | strcat(local_pending_command, " "); | ||
| 1026 | } | ||
| 1027 | input = NULL; | ||
| 1028 | |||
| 998 | } | 1029 | } |
| 999 | input = fopen(argv[1], "r"); | 1030 | else if (argv[1][0]=='-') { |
| 1000 | if (!input) { | 1031 | usage(shell_usage); |
| 1001 | fatalError("sh: Couldn't open file '%s': %s\n", argv[1], | 1032 | } |
| 1002 | strerror(errno)); | 1033 | else { |
| 1034 | input = fopen(argv[1], "r"); | ||
| 1035 | if (!input) { | ||
| 1036 | fatalError("sh: Couldn't open file '%s': %s\n", argv[1], | ||
| 1037 | strerror(errno)); | ||
| 1038 | } | ||
| 1003 | } | 1039 | } |
| 1004 | } | 1040 | } |
| 1005 | 1041 | ||
