aboutsummaryrefslogtreecommitdiff
path: root/shell/ash.c
diff options
context:
space:
mode:
Diffstat (limited to 'shell/ash.c')
-rw-r--r--shell/ash.c66
1 files changed, 59 insertions, 7 deletions
diff --git a/shell/ash.c b/shell/ash.c
index aa291b99d..2e4181b3f 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -9091,8 +9091,16 @@ static int builtinloc = -1; /* index in path of %builtin, or -1 */
9091 9091
9092 9092
9093static void 9093static void
9094#if ENABLE_PLATFORM_MINGW32
9095tryexec(IF_FEATURE_SH_STANDALONE(int applet_no, const char *nfpath,)
9096 const char *cmd, char **argv, char **envp)
9097#else
9094tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, char **envp) 9098tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, char **envp)
9099#endif
9095{ 9100{
9101#if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_SH_STANDALONE
9102 interp_t interp;
9103#endif
9096#if ENABLE_FEATURE_SH_STANDALONE 9104#if ENABLE_FEATURE_SH_STANDALONE
9097 if (applet_no >= 0) { 9105 if (applet_no >= 0) {
9098# if ENABLE_PLATFORM_MINGW32 9106# if ENABLE_PLATFORM_MINGW32
@@ -9101,6 +9109,7 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, c
9101 struct forkshell *fs = (struct forkshell *)sticky_mem_start; 9109 struct forkshell *fs = (struct forkshell *)sticky_mem_start;
9102 if (applet_main[applet_no] != ash_main || 9110 if (applet_main[applet_no] != ash_main ||
9103 (fs && fs->fpid == FS_SHELLEXEC)) { 9111 (fs && fs->fpid == FS_SHELLEXEC)) {
9112 run_noexec:
9104 /* mingw-w64's getopt() uses __argv[0] as the program name */ 9113 /* mingw-w64's getopt() uses __argv[0] as the program name */
9105 __argv[0] = (char *)cmd; 9114 __argv[0] = (char *)cmd;
9106 /* 'which' wants to know if it was invoked from a standalone 9115 /* 'which' wants to know if it was invoked from a standalone
@@ -9141,6 +9150,28 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, c
9141 9150
9142 /* cmd was allocated on the stack with room for an extension */ 9151 /* cmd was allocated on the stack with room for an extension */
9143 add_win32_extension((char *)cmd); 9152 add_win32_extension((char *)cmd);
9153
9154# if ENABLE_FEATURE_SH_STANDALONE
9155 /* If nfpath is non-NULL, evalcommand() has determined this
9156 * command doesn't need a fork(). If the command is a script
9157 * with an interpreter which is an applet we can run it as if
9158 * it were a noexec applet. */
9159 if (nfpath && parse_interpreter(cmd, &interp)) {
9160 applet_no = find_applet_by_name_for_sh(interp.name, nfpath);
9161 if (applet_no >= 0) {
9162 argv[0] = (char *)cmd;
9163 /* evalcommand() has added two elements before argv */
9164 if (interp.opts) {
9165 argv--;
9166 argv[0] = (char *)interp.opts;
9167 }
9168 argv--;
9169 cmd = argv[0] = (char *)interp.name;
9170 goto run_noexec;
9171 }
9172 }
9173# endif
9174
9144 execve(cmd, argv, envp); 9175 execve(cmd, argv, envp);
9145 /* skip POSIX-mandated retry on ENOEXEC */ 9176 /* skip POSIX-mandated retry on ENOEXEC */
9146#else /* !ENABLE_PLATFORM_MINGW32 */ 9177#else /* !ENABLE_PLATFORM_MINGW32 */
@@ -9182,20 +9213,29 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, c
9182#endif /* !ENABLE_PLATFORM_MINGW32 */ 9213#endif /* !ENABLE_PLATFORM_MINGW32 */
9183} 9214}
9184 9215
9216#if !ENABLE_PLATFORM_MINGW32 || !ENABLE_FEATURE_SH_STANDALONE
9217# define shellexec(prg, a, pth, i, n) shellexec(prg, a, pth, i)
9218#endif
9219
9185/* 9220/*
9186 * Exec a program. Never returns. If you change this routine, you may 9221 * Exec a program. Never returns. If you change this routine, you may
9187 * have to change the find_command routine as well. 9222 * have to change the find_command routine as well.
9188 * argv[-1] must exist and be writable! See tryexec() for why. 9223 * argv[-1] must exist and be writable! See tryexec() for why.
9189 */ 9224 */
9190static struct builtincmd *find_builtin(const char *name); 9225static struct builtincmd *find_builtin(const char *name);
9191static void shellexec(char *prog, char **argv, const char *path, int idx) NORETURN; 9226static void shellexec(char *prog, char **argv, const char *path, int idx,
9192static void shellexec(char *prog, char **argv, const char *path, int idx) 9227 int nofork) NORETURN;
9228static void shellexec(char *prog, char **argv, const char *path, int idx,
9229 int nofork)
9193{ 9230{
9194 char *cmdname; 9231 char *cmdname;
9195 int e; 9232 int e;
9196 char **envp; 9233 char **envp;
9197 int exerrno; 9234 int exerrno;
9198 int applet_no = -1; /* used only by FEATURE_SH_STANDALONE */ 9235 int applet_no = -1; /* used only by FEATURE_SH_STANDALONE */
9236#if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_SH_STANDALONE
9237 const char *nfpath = nofork ? path : NULL;
9238#endif
9199 9239
9200 envp = listvars(VEXPORT, VUNSET, /*strlist:*/ NULL, /*end:*/ NULL); 9240 envp = listvars(VEXPORT, VUNSET, /*strlist:*/ NULL, /*end:*/ NULL);
9201#if ENABLE_FEATURE_SH_STANDALONE && ENABLE_PLATFORM_MINGW32 && defined(_UCRT) 9241#if ENABLE_FEATURE_SH_STANDALONE && ENABLE_PLATFORM_MINGW32 && defined(_UCRT)
@@ -9217,7 +9257,8 @@ static void shellexec(char *prog, char **argv, const char *path, int idx)
9217 ) { 9257 ) {
9218#if ENABLE_PLATFORM_MINGW32 9258#if ENABLE_PLATFORM_MINGW32
9219 char *progext = stack_add_ext_space(prog); 9259 char *progext = stack_add_ext_space(prog);
9220 tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) progext, argv, envp); 9260 tryexec(IF_FEATURE_SH_STANDALONE(applet_no, nfpath,)
9261 progext, argv, envp);
9221#else 9262#else
9222 tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) prog, argv, envp); 9263 tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) prog, argv, envp);
9223#endif 9264#endif
@@ -9234,7 +9275,7 @@ static void shellexec(char *prog, char **argv, const char *path, int idx)
9234 const char *name = bb_basename(prog); 9275 const char *name = bb_basename(prog);
9235# if ENABLE_FEATURE_SH_STANDALONE 9276# if ENABLE_FEATURE_SH_STANDALONE
9236 if ((applet_no = find_applet_by_name_for_sh(name, path)) >= 0) { 9277 if ((applet_no = find_applet_by_name_for_sh(name, path)) >= 0) {
9237 tryexec(applet_no, name, argv, envp); 9278 tryexec(applet_no, nfpath, name, argv, envp);
9238 e = errno; 9279 e = errno;
9239 } 9280 }
9240# endif 9281# endif
@@ -9250,7 +9291,12 @@ static void shellexec(char *prog, char **argv, const char *path, int idx)
9250 while (padvance(&path, argv[0]) >= 0) { 9291 while (padvance(&path, argv[0]) >= 0) {
9251 cmdname = stackblock(); 9292 cmdname = stackblock();
9252 if (--idx < 0 && pathopt == NULL) { 9293 if (--idx < 0 && pathopt == NULL) {
9294#if ENABLE_PLATFORM_MINGW32
9295 tryexec(IF_FEATURE_SH_STANDALONE(-1, nfpath,)
9296 cmdname, argv, envp);
9297#else
9253 tryexec(IF_FEATURE_SH_STANDALONE(-1,) cmdname, argv, envp); 9298 tryexec(IF_FEATURE_SH_STANDALONE(-1,) cmdname, argv, envp);
9299#endif
9254 if (errno != ENOENT && errno != ENOTDIR) 9300 if (errno != ENOENT && errno != ENOTDIR)
9255 e = errno; 9301 e = errno;
9256 } 9302 }
@@ -11223,7 +11269,7 @@ execcmd(int argc UNUSED_PARAM, char **argv)
11223 prog = argv[0]; 11269 prog = argv[0];
11224 if (optionarg) 11270 if (optionarg)
11225 argv[0] = optionarg; 11271 argv[0] = optionarg;
11226 shellexec(prog, argv, pathval(), 0); 11272 shellexec(prog, argv, pathval(), 0, FALSE);
11227 /* NOTREACHED */ 11273 /* NOTREACHED */
11228 } 11274 }
11229 return 0; 11275 return 0;
@@ -11581,7 +11627,13 @@ evalcommand(union node *cmd, int flags)
11581 localvar_stop = pushlocalvars(vlocal); 11627 localvar_stop = pushlocalvars(vlocal);
11582 11628
11583#if ENABLE_PLATFORM_MINGW32 11629#if ENABLE_PLATFORM_MINGW32
11630# if ENABLE_FEATURE_SH_STANDALONE
11631 /* Reserve two extra spots at the front for shellexec. */
11632 nargv = stalloc(sizeof(char *) * (argc + 3));
11633 argv = nargv = nargv + 2;
11634# else
11584 argv = nargv = stalloc(sizeof(char *) * (argc + 1)); 11635 argv = nargv = stalloc(sizeof(char *) * (argc + 1));
11636# endif
11585#else 11637#else
11586 /* Reserve one extra spot at the front for shellexec. */ 11638 /* Reserve one extra spot at the front for shellexec. */
11587 nargv = stalloc(sizeof(char *) * (argc + 2)); 11639 nargv = stalloc(sizeof(char *) * (argc + 2));
@@ -11773,7 +11825,7 @@ evalcommand(union node *cmd, int flags)
11773 /* fall through to exec'ing external program */ 11825 /* fall through to exec'ing external program */
11774 } 11826 }
11775#endif 11827#endif
11776 shellexec(argv[0], argv, path, cmdentry.u.index); 11828 shellexec(argv[0], argv, path, cmdentry.u.index, TRUE);
11777 /* NOTREACHED */ 11829 /* NOTREACHED */
11778 } /* default */ 11830 } /* default */
11779 case CMDBUILTIN: 11831 case CMDBUILTIN:
@@ -16492,7 +16544,7 @@ forkshell_shellexec(struct forkshell *fs)
16492 char *path = fs->path; 16544 char *path = fs->path;
16493 16545
16494 FORCE_INT_ON; 16546 FORCE_INT_ON;
16495 shellexec(argv[0], argv, path, idx); 16547 shellexec(argv[0], argv, path, idx, FALSE);
16496} 16548}
16497 16549
16498static void 16550static void