diff options
author | Ron Yorston <rmy@pobox.com> | 2012-03-22 13:56:39 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2012-03-22 13:56:39 +0000 |
commit | 811c449748d5bd0505f8510e5582892f94ac0cda (patch) | |
tree | 2640249cb2a9605c7cd59467b9861b205e9bcc8a /shell/ash.c | |
parent | c0d4367d6b581eb5989c02815880cf0fa2851ae8 (diff) | |
parent | 19311bfa7b8e8c6effa9c375de9b0eb4338bee12 (diff) | |
download | busybox-w32-811c449748d5bd0505f8510e5582892f94ac0cda.tar.gz busybox-w32-811c449748d5bd0505f8510e5582892f94ac0cda.tar.bz2 busybox-w32-811c449748d5bd0505f8510e5582892f94ac0cda.zip |
Merge commit '19311bfa7b8e8c6effa9c375de9b0eb4338bee12' into merge
Conflicts:
coreutils/ls.c
shell/ash.c
Diffstat (limited to 'shell/ash.c')
-rw-r--r-- | shell/ash.c | 104 |
1 files changed, 66 insertions, 38 deletions
diff --git a/shell/ash.c b/shell/ash.c index fd9141661..d12a483a3 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -56,6 +56,9 @@ | |||
56 | #include <fnmatch.h> | 56 | #include <fnmatch.h> |
57 | #include <sys/times.h> | 57 | #include <sys/times.h> |
58 | 58 | ||
59 | #include "busybox.h" /* for applet_names */ | ||
60 | #include "unicode.h" | ||
61 | |||
59 | #include "shell_common.h" | 62 | #include "shell_common.h" |
60 | #if ENABLE_SH_MATH_SUPPORT | 63 | #if ENABLE_SH_MATH_SUPPORT |
61 | # include "math.h" | 64 | # include "math.h" |
@@ -86,13 +89,6 @@ | |||
86 | # error "Do not even bother, ash will not run on NOMMU machine" | 89 | # error "Do not even bother, ash will not run on NOMMU machine" |
87 | #endif | 90 | #endif |
88 | 91 | ||
89 | //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP)) | ||
90 | //applet:IF_FEATURE_SH_IS_ASH(APPLET_ODDNAME(sh, ash, BB_DIR_BIN, BB_SUID_DROP, sh)) | ||
91 | //applet:IF_FEATURE_BASH_IS_ASH(APPLET_ODDNAME(bash, ash, BB_DIR_BIN, BB_SUID_DROP, bash)) | ||
92 | |||
93 | //kbuild:lib-$(CONFIG_ASH) += ash.o ash_ptr_hack.o shell_common.o | ||
94 | //kbuild:lib-$(CONFIG_ASH_RANDOM_SUPPORT) += random.o | ||
95 | |||
96 | //config:config ASH | 92 | //config:config ASH |
97 | //config: bool "ash" | 93 | //config: bool "ash" |
98 | //config: default y | 94 | //config: default y |
@@ -204,12 +200,12 @@ | |||
204 | //config: variable each time it is displayed. | 200 | //config: variable each time it is displayed. |
205 | //config: | 201 | //config: |
206 | 202 | ||
207 | //usage:#define ash_trivial_usage NOUSAGE_STR | 203 | //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP)) |
208 | //usage:#define ash_full_usage "" | 204 | //applet:IF_FEATURE_SH_IS_ASH(APPLET_ODDNAME(sh, ash, BB_DIR_BIN, BB_SUID_DROP, sh)) |
209 | //usage:#define sh_trivial_usage NOUSAGE_STR | 205 | //applet:IF_FEATURE_BASH_IS_ASH(APPLET_ODDNAME(bash, ash, BB_DIR_BIN, BB_SUID_DROP, bash)) |
210 | //usage:#define sh_full_usage "" | 206 | |
211 | //usage:#define bash_trivial_usage NOUSAGE_STR | 207 | //kbuild:lib-$(CONFIG_ASH) += ash.o ash_ptr_hack.o shell_common.o |
212 | //usage:#define bash_full_usage "" | 208 | //kbuild:lib-$(CONFIG_ASH_RANDOM_SUPPORT) += random.o |
213 | 209 | ||
214 | #if ENABLE_PLATFORM_MINGW32 | 210 | #if ENABLE_PLATFORM_MINGW32 |
215 | struct forkshell; | 211 | struct forkshell; |
@@ -3705,12 +3701,12 @@ set_curjob(struct job *jp, unsigned mode) | |||
3705 | 3701 | ||
3706 | /* first remove from list */ | 3702 | /* first remove from list */ |
3707 | jpp = curp = &curjob; | 3703 | jpp = curp = &curjob; |
3708 | do { | 3704 | while (1) { |
3709 | jp1 = *jpp; | 3705 | jp1 = *jpp; |
3710 | if (jp1 == jp) | 3706 | if (jp1 == jp) |
3711 | break; | 3707 | break; |
3712 | jpp = &jp1->prev_job; | 3708 | jpp = &jp1->prev_job; |
3713 | } while (1); | 3709 | } |
3714 | *jpp = jp1->prev_job; | 3710 | *jpp = jp1->prev_job; |
3715 | 3711 | ||
3716 | /* Then re-insert in correct position */ | 3712 | /* Then re-insert in correct position */ |
@@ -3726,14 +3722,14 @@ set_curjob(struct job *jp, unsigned mode) | |||
3726 | case CUR_RUNNING: | 3722 | case CUR_RUNNING: |
3727 | /* newly created job or backgrounded job, | 3723 | /* newly created job or backgrounded job, |
3728 | put after all stopped jobs. */ | 3724 | put after all stopped jobs. */ |
3729 | do { | 3725 | while (1) { |
3730 | jp1 = *jpp; | 3726 | jp1 = *jpp; |
3731 | #if JOBS | 3727 | #if JOBS |
3732 | if (!jp1 || jp1->state != JOBSTOPPED) | 3728 | if (!jp1 || jp1->state != JOBSTOPPED) |
3733 | #endif | 3729 | #endif |
3734 | break; | 3730 | break; |
3735 | jpp = &jp1->prev_job; | 3731 | jpp = &jp1->prev_job; |
3736 | } while (1); | 3732 | } |
3737 | /* FALLTHROUGH */ | 3733 | /* FALLTHROUGH */ |
3738 | #if JOBS | 3734 | #if JOBS |
3739 | case CUR_STOPPED: | 3735 | case CUR_STOPPED: |
@@ -3906,7 +3902,7 @@ setjobctl(int on) | |||
3906 | goto out; | 3902 | goto out; |
3907 | /* fd is a tty at this point */ | 3903 | /* fd is a tty at this point */ |
3908 | close_on_exec_on(fd); | 3904 | close_on_exec_on(fd); |
3909 | do { /* while we are in the background */ | 3905 | while (1) { /* while we are in the background */ |
3910 | pgrp = tcgetpgrp(fd); | 3906 | pgrp = tcgetpgrp(fd); |
3911 | if (pgrp < 0) { | 3907 | if (pgrp < 0) { |
3912 | out: | 3908 | out: |
@@ -3917,7 +3913,7 @@ setjobctl(int on) | |||
3917 | if (pgrp == getpgrp()) | 3913 | if (pgrp == getpgrp()) |
3918 | break; | 3914 | break; |
3919 | killpg(0, SIGTTIN); | 3915 | killpg(0, SIGTTIN); |
3920 | } while (1); | 3916 | } |
3921 | initialpgrp = pgrp; | 3917 | initialpgrp = pgrp; |
3922 | 3918 | ||
3923 | setsignal(SIGTSTP); | 3919 | setsignal(SIGTSTP); |
@@ -6328,7 +6324,7 @@ expari(int quotes) | |||
6328 | p = expdest - 1; | 6324 | p = expdest - 1; |
6329 | *p = '\0'; | 6325 | *p = '\0'; |
6330 | p--; | 6326 | p--; |
6331 | do { | 6327 | while (1) { |
6332 | int esc; | 6328 | int esc; |
6333 | 6329 | ||
6334 | while ((unsigned char)*p != CTLARI) { | 6330 | while ((unsigned char)*p != CTLARI) { |
@@ -6346,7 +6342,7 @@ expari(int quotes) | |||
6346 | } | 6342 | } |
6347 | 6343 | ||
6348 | p -= esc + 1; | 6344 | p -= esc + 1; |
6349 | } while (1); | 6345 | } |
6350 | 6346 | ||
6351 | begoff = p - start; | 6347 | begoff = p - start; |
6352 | 6348 | ||
@@ -7754,8 +7750,6 @@ static int builtinloc = -1; /* index in path of %builtin, or -1 */ | |||
7754 | static void | 7750 | static void |
7755 | tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char **envp) | 7751 | tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char **envp) |
7756 | { | 7752 | { |
7757 | int repeated = 0; | ||
7758 | |||
7759 | #if ENABLE_FEATURE_SH_STANDALONE | 7753 | #if ENABLE_FEATURE_SH_STANDALONE |
7760 | if (applet_no >= 0) { | 7754 | if (applet_no >= 0) { |
7761 | if (APPLET_IS_NOEXEC(applet_no)) { | 7755 | if (APPLET_IS_NOEXEC(applet_no)) { |
@@ -7779,25 +7773,36 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char ** | |||
7779 | #else | 7773 | #else |
7780 | execve(cmd, argv, envp); | 7774 | execve(cmd, argv, envp); |
7781 | #endif | 7775 | #endif |
7782 | if (repeated) { | 7776 | if (cmd == (char*) bb_busybox_exec_path) { |
7777 | /* We already visited ENOEXEC branch below, don't do it again */ | ||
7778 | //TODO: try execve(initial_argv0_of_shell, argv, envp) before giving up? | ||
7783 | free(argv); | 7779 | free(argv); |
7784 | return; | 7780 | return; |
7785 | } | 7781 | } |
7786 | if (errno == ENOEXEC) { | 7782 | if (errno == ENOEXEC) { |
7783 | /* Run "cmd" as a shell script: | ||
7784 | * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html | ||
7785 | * "If the execve() function fails with ENOEXEC, the shell | ||
7786 | * shall execute a command equivalent to having a shell invoked | ||
7787 | * with the command name as its first operand, | ||
7788 | * with any remaining arguments passed to the new shell" | ||
7789 | * | ||
7790 | * That is, do not use $SHELL, user's shell, or /bin/sh; | ||
7791 | * just call ourselves. | ||
7792 | */ | ||
7787 | char **ap; | 7793 | char **ap; |
7788 | char **new; | 7794 | char **new; |
7789 | 7795 | ||
7790 | for (ap = argv; *ap; ap++) | 7796 | for (ap = argv; *ap; ap++) |
7791 | continue; | 7797 | continue; |
7792 | ap = new = ckmalloc((ap - argv + 2) * sizeof(ap[0])); | 7798 | new = ckmalloc((ap - argv + 2) * sizeof(new[0])); |
7793 | ap[1] = cmd; | 7799 | new[0] = (char*) "ash"; |
7794 | ap[0] = cmd = (char *)DEFAULT_SHELL; | 7800 | new[1] = cmd; |
7795 | ap += 2; | 7801 | ap = new + 2; |
7796 | argv++; | 7802 | while ((*ap++ = *++argv) != NULL) |
7797 | while ((*ap++ = *argv++) != NULL) | ||
7798 | continue; | 7803 | continue; |
7804 | cmd = (char*) bb_busybox_exec_path; | ||
7799 | argv = new; | 7805 | argv = new; |
7800 | repeated++; | ||
7801 | goto repeat; | 7806 | goto repeat; |
7802 | } | 7807 | } |
7803 | } | 7808 | } |
@@ -10126,6 +10131,11 @@ preadfd(void) | |||
10126 | # if ENABLE_FEATURE_TAB_COMPLETION | 10131 | # if ENABLE_FEATURE_TAB_COMPLETION |
10127 | line_input_state->path_lookup = pathval(); | 10132 | line_input_state->path_lookup = pathval(); |
10128 | # endif | 10133 | # endif |
10134 | /* Unicode support should be activated even if LANG is set | ||
10135 | * _during_ shell execution, not only if it was set when | ||
10136 | * shell was started. Therefore, re-check LANG every time: | ||
10137 | */ | ||
10138 | reinit_unicode(lookupvar("LANG")); | ||
10129 | nr = read_line_input(line_input_state, cmdedit_prompt, buf, IBUFSIZ, timeout); | 10139 | nr = read_line_input(line_input_state, cmdedit_prompt, buf, IBUFSIZ, timeout); |
10130 | if (nr == 0) { | 10140 | if (nr == 0) { |
10131 | /* Ctrl+C pressed */ | 10141 | /* Ctrl+C pressed */ |
@@ -10673,7 +10683,7 @@ options(int cmdline) | |||
10673 | else if (*argptr == NULL) | 10683 | else if (*argptr == NULL) |
10674 | setparam(argptr); | 10684 | setparam(argptr); |
10675 | } | 10685 | } |
10676 | break; /* "-" or "--" terminates options */ | 10686 | break; /* "-" or "--" terminates options */ |
10677 | } | 10687 | } |
10678 | } | 10688 | } |
10679 | /* first char was + or - */ | 10689 | /* first char was + or - */ |
@@ -10775,10 +10785,10 @@ setcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
10775 | 10785 | ||
10776 | if (!argv[1]) | 10786 | if (!argv[1]) |
10777 | return showvars(nullstr, 0, VUNSET); | 10787 | return showvars(nullstr, 0, VUNSET); |
10788 | |||
10778 | INT_OFF; | 10789 | INT_OFF; |
10779 | retval = 1; | 10790 | retval = options(/*cmdline:*/ 0); |
10780 | if (!options(0)) { /* if no parse error... */ | 10791 | if (retval == 0) { /* if no parse error... */ |
10781 | retval = 0; | ||
10782 | optschanged(); | 10792 | optschanged(); |
10783 | if (*argptr != NULL) { | 10793 | if (*argptr != NULL) { |
10784 | setparam(argptr); | 10794 | setparam(argptr); |
@@ -13525,14 +13535,32 @@ init(void) | |||
13525 | setvar("PPID", utoa(getppid()), 0); | 13535 | setvar("PPID", utoa(getppid()), 0); |
13526 | 13536 | ||
13527 | p = lookupvar("PWD"); | 13537 | p = lookupvar("PWD"); |
13528 | if (p) | 13538 | if (p) { |
13529 | if (*p != '/' || stat(p, &st1) || stat(".", &st2) | 13539 | if (*p != '/' || stat(p, &st1) || stat(".", &st2) |
13530 | || st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino) | 13540 | || st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino |
13541 | ) { | ||
13531 | p = '\0'; | 13542 | p = '\0'; |
13543 | } | ||
13544 | } | ||
13532 | setpwd(p, 0); | 13545 | setpwd(p, 0); |
13533 | } | 13546 | } |
13534 | } | 13547 | } |
13535 | 13548 | ||
13549 | |||
13550 | //usage:#define ash_trivial_usage | ||
13551 | //usage: "[-/+OPTIONS] [-/+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS]]" | ||
13552 | //usage:#define ash_full_usage "\n\n" | ||
13553 | //usage: "Unix shell interpreter" | ||
13554 | |||
13555 | //usage:#if ENABLE_FEATURE_SH_IS_ASH | ||
13556 | //usage:# define sh_trivial_usage ash_trivial_usage | ||
13557 | //usage:# define sh_full_usage ash_full_usage | ||
13558 | //usage:#endif | ||
13559 | //usage:#if ENABLE_FEATURE_BASH_IS_ASH | ||
13560 | //usage:# define bash_trivial_usage ash_trivial_usage | ||
13561 | //usage:# define bash_full_usage ash_full_usage | ||
13562 | //usage:#endif | ||
13563 | |||
13536 | /* | 13564 | /* |
13537 | * Process the shell command line arguments. | 13565 | * Process the shell command line arguments. |
13538 | */ | 13566 | */ |
@@ -13550,7 +13578,7 @@ procargs(char **argv) | |||
13550 | for (i = 0; i < NOPTS; i++) | 13578 | for (i = 0; i < NOPTS; i++) |
13551 | optlist[i] = 2; | 13579 | optlist[i] = 2; |
13552 | argptr = xargv; | 13580 | argptr = xargv; |
13553 | if (options(1)) { | 13581 | if (options(/*cmdline:*/ 1)) { |
13554 | /* it already printed err message */ | 13582 | /* it already printed err message */ |
13555 | raise_exception(EXERROR); | 13583 | raise_exception(EXERROR); |
13556 | } | 13584 | } |