[PATCH] add exec -a support (preliminary)
Patrick Pief
p.pief at zoho.com
Fri Jan 27 22:54:37 UTC 2017
Hey,
> And, don't duplicate another function if what you did is only extending a
> functionality of that function. BusyBox is coded with size in mind.
I know, and I am reminded of it whenever I look at Busybox's source code.
:)
I thought that this way it might be easier to comment out, but looking at
how my changes aren't all that drastic it was really unnessary. The #if block
could be put around the new lines in execcmd().
> Besides, if you code within shellexec() we
> can see a better diff on what you have extended.
Makes sense, so here is my updated patch.
Some explanation:
* "zeroarg" is the new target argv[0] the target program will see.
* "realcmd" is the original argv[0], the command string which determines what
gets really called, it's also what identifies the shellexec call in the trace.
I am always open for suggestions on better parameter/variable names.
-Patrick
---
shell/ash.c | 24 +++++++++++++++---------
1 file changed, 15 insertions(+), 9 deletions(-)
diff --git a/shell/ash.c b/shell/ash.c
index d8f4132..7abca3d 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -7706,23 +7706,25 @@ 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 **, char *, const char *, int) NORETURN;
static void
-shellexec(char **argv, const char *path, int idx)
+shellexec(char **argv, char *zeroarg, const char *path, int idx)
{
char *cmdname;
+ char *realcmd = argv[0];
int e;
char **envp;
int exerrno;
int applet_no = -1; /* used only by FEATURE_SH_STANDALONE */
+ argv[0] = zeroarg;
envp = listvars(VEXPORT, VUNSET, /*end:*/ NULL);
- if (strchr(argv[0], '/') != NULL
+ if (strchr(realcmd, '/') != NULL
#if ENABLE_FEATURE_SH_STANDALONE
- || (applet_no = find_applet_by_name(argv[0])) >= 0
+ || (applet_no = find_applet_by_name(realcmd)) >= 0
#endif
) {
- tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) argv[0], argv, envp);
+ tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) realcmd, argv, envp);
if (applet_no >= 0) {
/* We tried execing ourself, but it didn't work.
* Maybe /proc/self/exe doesn't exist?
@@ -7734,7 +7736,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, realcmd)) != NULL) {
if (--idx < 0 && pathopt == NULL) {
tryexec(IF_FEATURE_SH_STANDALONE(-1,) cmdname, argv, envp);
if (errno != ENOENT && errno != ENOTDIR)
@@ -7758,7 +7760,7 @@ 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));
+ realcmd, e, suppress_int));
ash_msg_and_raise(EXEXIT, "%s: %s", argv[0], errmsg(e, "not found"));
/* NOTREACHED */
}
@@ -9333,7 +9335,11 @@ 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);
+ if (strcmp(argv[1], "-a") == 0 && argv[2]) {
+ shellexec(argv + 3, argv[2], pathval(), 0);
+ } else {
+ shellexec(argv + 1, argv[1], pathval(), 0);
+ }
/* NOTREACHED */
}
return 0;
@@ -9735,7 +9741,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, argv[0], path, cmdentry.u.index);
/* NOTREACHED */
} /* default */
case CMDBUILTIN:
--
2.11.0
More information about the busybox
mailing list