ash: make shellexec capable of using separate argv[0] and filename to exec
authorDenys Vlasenko <vda.linux@googlemail.com>
Wed, 12 Apr 2017 19:02:33 +0000 (21:02 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Wed, 12 Apr 2017 19:02:33 +0000 (21:02 +0200)
function                                             old     new   delta
execcmd                                               71      78      +7
shellexec                                            221     224      +3
evalcommand                                         1158    1161      +3
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/0 up/down: 13/0)               Total: 13 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
shell/ash.c

index 983f7b108cfa0ee5b5aca1be4089d88e5cc7f6c6..044f166be3a4bd3d7d3cdf8653151adc713e74a8 100644 (file)
@@ -7744,9 +7744,8 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char **
  * have to change the find_command routine as well.
  * argv[-1] must exist and be writable! See tryexec() for why.
  */
-static void shellexec(char **, const char *, int) NORETURN;
-static void
-shellexec(char **argv, const char *path, int idx)
+static void shellexec(char *prog, char **argv, const char *path, int idx) NORETURN;
+static void shellexec(char *prog, char **argv, const char *path, int idx)
 {
        char *cmdname;
        int e;
@@ -7755,12 +7754,12 @@ shellexec(char **argv, const char *path, int idx)
        int applet_no = -1; /* used only by FEATURE_SH_STANDALONE */
 
        envp = listvars(VEXPORT, VUNSET, /*end:*/ NULL);
-       if (strchr(argv[0], '/') != NULL
+       if (strchr(prog, '/') != NULL
 #if ENABLE_FEATURE_SH_STANDALONE
-        || (applet_no = find_applet_by_name(argv[0])) >= 0
+        || (applet_no = find_applet_by_name(prog)) >= 0
 #endif
        ) {
-               tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) argv[0], argv, envp);
+               tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) prog, argv, envp);
                if (applet_no >= 0) {
                        /* We tried execing ourself, but it didn't work.
                         * Maybe /proc/self/exe doesn't exist?
@@ -7772,7 +7771,7 @@ shellexec(char **argv, const char *path, int idx)
        } else {
  try_PATH:
                e = ENOENT;
-               while ((cmdname = path_advance(&path, argv[0])) != NULL) {
+               while ((cmdname = path_advance(&path, prog)) != NULL) {
                        if (--idx < 0 && pathopt == NULL) {
                                tryexec(IF_FEATURE_SH_STANDALONE(-1,) cmdname, argv, envp);
                                if (errno != ENOENT && errno != ENOTDIR)
@@ -7796,8 +7795,8 @@ shellexec(char **argv, const char *path, int idx)
        }
        exitstatus = exerrno;
        TRACE(("shellexec failed for %s, errno %d, suppress_int %d\n",
-               argv[0], e, suppress_int));
-       ash_msg_and_raise(EXEXIT, "%s: %s", argv[0], errmsg(e, "not found"));
+               prog, e, suppress_int));
+       ash_msg_and_raise(EXEXIT, "%s: %s", prog, errmsg(e, "not found"));
        /* NOTREACHED */
 }
 
@@ -9371,7 +9370,7 @@ execcmd(int argc UNUSED_PARAM, char **argv)
                /*setsignal(SIGTSTP); - unnecessary because of mflag=0 */
                /*setsignal(SIGTTOU); - unnecessary because of mflag=0 */
 
-               shellexec(argv + 1, pathval(), 0);
+               shellexec(argv[1], argv + 1, pathval(), 0);
                /* NOTREACHED */
        }
        return 0;
@@ -9773,7 +9772,7 @@ evalcommand(union node *cmd, int flags)
                        /* fall through to exec'ing external program */
                }
                listsetvar(varlist.list, VEXPORT|VSTACK);
-               shellexec(argv, path, cmdentry.u.index);
+               shellexec(argv[0], argv, path, cmdentry.u.index);
                /* NOTREACHED */
        } /* default */
        case CMDBUILTIN: