diff options
author | Fabian Groffen <grobian@gentoo.org> | 2022-02-06 15:20:35 +0100 |
---|---|---|
committer | Fabian Groffen <grobian@gentoo.org> | 2022-02-06 15:20:35 +0100 |
commit | 43ad7423ae06e9bcad672a21131f14e3ce790204 (patch) | |
tree | 6626157d2422ebf58fa59ea370ee848e6f99d25f /libq | |
parent | .github: coverity also needs builddeps (diff) | |
download | portage-utils-43ad7423ae06e9bcad672a21131f14e3ce790204.tar.gz portage-utils-43ad7423ae06e9bcad672a21131f14e3ce790204.tar.bz2 portage-utils-43ad7423ae06e9bcad672a21131f14e3ce790204.zip |
libq/xsystem: cleanup/reuse same codepath, allow passing vector
Signed-off-by: Fabian Groffen <grobian@gentoo.org>
Diffstat (limited to 'libq')
-rw-r--r-- | libq/xsystem.c | 96 | ||||
-rw-r--r-- | libq/xsystem.h | 8 |
2 files changed, 65 insertions, 39 deletions
diff --git a/libq/xsystem.c b/libq/xsystem.c index e2dbc5e..05743ce 100644 --- a/libq/xsystem.c +++ b/libq/xsystem.c @@ -17,49 +17,73 @@ #include "xasprintf.h" #include "xsystem.h" -void xsystem(const char *command) -{ - if (unlikely(system(command))) - errp("system(%s) failed", command); -} - -void xsystembash(const char *command, int cwd) +void xsystembash(const char *command, const char **argv, int cwd) { pid_t p = fork(); int status; switch (p) { - case 0: /* child */ - if (cwd != AT_FDCWD) - if (fchdir(cwd)) { - /* fchdir works with O_PATH starting w/linux-3.5 */ - if (errno == EBADF) { - char *path; - xasprintf(&path, "/proc/self/fd/%i", cwd); - if (chdir(path)) - errp("chdir(%s) failed", path); - } else - errp("fchdir(%i) failed", cwd); + case 0: /* child */ + if (cwd != AT_FDCWD) { + if (fchdir(cwd)) { + /* fchdir works with O_PATH starting w/linux-3.5 */ + if (errno == EBADF) { + char *path; + xasprintf(&path, "/proc/self/fd/%i", cwd); + if (chdir(path)) + errp("chdir(%s) failed", path); + } else { + errp("fchdir(%i) failed", cwd); + } + } + } + if (argv == NULL) { + execl(CONFIG_EPREFIX "bin/bash", "bash", + "--norc", "--noprofile", "-c", command, (char *)NULL); + /* Hrm, still here ? Maybe no bash ... */ + _exit(execl("/bin/sh", "sh", "-c", command, (char *)NULL)); + } else { + int argc = 0; + const char *a; + const char **newargv; + + /* count existing args */ + for (a = argv[0]; a != NULL; a++, argc++) + ; + argc += 1 + 1 + 1 + 1; + newargv = xmalloc(sizeof(newargv[0]) * (argc + 1)); + argc = 0; + newargv[argc++] = "bash"; + newargv[argc++] = "--norc"; + newargv[argc++] = "--noprofile"; + newargv[argc++] = "-c"; + for (a = argv[0]; a != NULL; a++) + newargv[argc++] = a; + newargv[argc] = NULL; + + execv(CONFIG_EPREFIX "bin/bash", (char *const *)newargv); + + /* Hrm, still here ? Maybe no bash ... */ + newargv = &newargv[2]; /* shift, two args less */ + argc = 0; + newargv[argc++] = "sh"; + _exit(execv("/bin/sh", (char *const *)newargv)); } - execl(CONFIG_EPREFIX "bin/bash", "bash", - "--norc", "--noprofile", "-c", command, (char *)NULL); - /* Hrm, still here ? Maybe no bash ... */ - _exit(execl("/bin/sh", "sh", "-c", command, (char *)NULL)); - default: /* parent */ - waitpid(p, &status, 0); - if (WIFSIGNALED(status)) { - err("phase crashed with signal %i: %s", WTERMSIG(status), - strsignal(WTERMSIG(status))); - } else if (WIFEXITED(status)) { - if (WEXITSTATUS(status) == 0) - return; - else - err("phase exited %i", WEXITSTATUS(status)); - } - /* fall through */ + default: /* parent */ + waitpid(p, &status, 0); + if (WIFSIGNALED(status)) { + err("phase crashed with signal %i: %s", WTERMSIG(status), + strsignal(WTERMSIG(status))); + } else if (WIFEXITED(status)) { + if (WEXITSTATUS(status) == 0) + return; + else + err("phase exited %i", WEXITSTATUS(status)); + } + /* fall through */ - case -1: /* fucked */ - errp("xsystembash(%s) failed", command); + case -1: /* fucked */ + errp("xsystembash(%s) failed", command); } } diff --git a/libq/xsystem.h b/libq/xsystem.h index 833840d..d6c4fa4 100644 --- a/libq/xsystem.h +++ b/libq/xsystem.h @@ -1,14 +1,16 @@ /* - * Copyright 2010-2019 Gentoo Foundation + * Copyright 2010-2022 Gentoo Foundation * Distributed under the terms of the GNU General Public License v2 * * Copyright 2010-2016 Mike Frysinger - <vapier@gentoo.org> + * Copyright 2022 Fabian Groffen - <grobian@gentoo.org> */ #ifndef _XSYSTEM_H #define _XSYSTEM_H 1 -void xsystem(const char *command); -void xsystembash(const char *command, int cwd); +void xsystembash(const char *command, const char **argv, int cwd); +#define xsystem(C,F) xsystembash(C, NULL, F) +#define xsystemv(V,F) xsystembash(NULL, V, F) #endif |