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 | |
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
-rw-r--r-- | Changelog | 6 | ||||
-rw-r--r-- | archival/tar.c | 3 | ||||
-rw-r--r-- | lash.c | 76 | ||||
-rw-r--r-- | sh.c | 76 | ||||
-rw-r--r-- | shell/lash.c | 76 | ||||
-rw-r--r-- | tar.c | 3 |
6 files changed, 177 insertions, 63 deletions
@@ -1,13 +1,17 @@ | |||
1 | 0.46 | 1 | 0.46 |
2 | 2 | ||
3 | * Fixed a _horrible_ bug where 'tar -tvf' could unlink | ||
4 | local files!!! Fix thanks to Marius Groeger <mgroeger@sysgo.de> | ||
5 | * Fixed a nasty bug in tar when could mess up saved symlinks. | ||
3 | * Updates to handle Linux 2.4.0 kernels (kludged around the | 6 | * Updates to handle Linux 2.4.0 kernels (kludged around the |
4 | "none" entries in /proc/mounts, added a hack to make sysinfo | 7 | "none" entries in /proc/mounts, added a hack to make sysinfo |
5 | work with both old and new kernels). | 8 | work with both old and new kernels). |
6 | * Fixed a nasty bug in tar when could mess up saved symlinks. | ||
7 | * Fixed insmod module option parsing for options lacking an '='. | 9 | * Fixed insmod module option parsing for options lacking an '='. |
8 | Fix thanks to Marc Nijdam <marc_nijdam@hp.com> | 10 | Fix thanks to Marc Nijdam <marc_nijdam@hp.com> |
9 | * Fixed segfault with 'cut -f 1 -d:' and added 'cut -s' suport. | 11 | * Fixed segfault with 'cut -f 1 -d:' and added 'cut -s' suport. |
10 | Fix thanks to Arne Bernin <arne@matrix.loopback.org> | 12 | Fix thanks to Arne Bernin <arne@matrix.loopback.org> |
13 | * Added support for "sh -c command args...", thanks to | ||
14 | Marius Groeger <mgroeger@sysgo.de> | ||
11 | 15 | ||
12 | -Erik Andersen | 16 | -Erik Andersen |
13 | 17 | ||
diff --git a/archival/tar.c b/archival/tar.c index 836d127e7..611bbd9a0 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
@@ -648,7 +648,8 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag, | |||
648 | } | 648 | } |
649 | 649 | ||
650 | /* Remove any clutter lying in our way */ | 650 | /* Remove any clutter lying in our way */ |
651 | unlink( header.name); | 651 | if (extractFlag == TRUE) /* .. but only if we are extracting (as */ |
652 | unlink( header.name); /* opposed to listing) (rob@sysgo.de) */ | ||
652 | 653 | ||
653 | /* If we got here, we can be certain we have a legitimate | 654 | /* If we got here, we can be certain we have a legitimate |
654 | * header to work with. So work with it. */ | 655 | * header to work with. So work with it. */ |
@@ -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 | ||
@@ -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 | ||
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 | ||
@@ -648,7 +648,8 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag, | |||
648 | } | 648 | } |
649 | 649 | ||
650 | /* Remove any clutter lying in our way */ | 650 | /* Remove any clutter lying in our way */ |
651 | unlink( header.name); | 651 | if (extractFlag == TRUE) /* .. but only if we are extracting (as */ |
652 | unlink( header.name); /* opposed to listing) (rob@sysgo.de) */ | ||
652 | 653 | ||
653 | /* If we got here, we can be certain we have a legitimate | 654 | /* If we got here, we can be certain we have a legitimate |
654 | * header to work with. So work with it. */ | 655 | * header to work with. So work with it. */ |