aboutsummaryrefslogtreecommitdiff
path: root/shell/ash.c
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2012-03-22 13:56:39 +0000
committerRon Yorston <rmy@pobox.com>2012-03-22 13:56:39 +0000
commit811c449748d5bd0505f8510e5582892f94ac0cda (patch)
tree2640249cb2a9605c7cd59467b9861b205e9bcc8a /shell/ash.c
parentc0d4367d6b581eb5989c02815880cf0fa2851ae8 (diff)
parent19311bfa7b8e8c6effa9c375de9b0eb4338bee12 (diff)
downloadbusybox-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.c104
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
215struct forkshell; 211struct 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 */
7754static void 7750static void
7755tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char **envp) 7751tryexec(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 }