aboutsummaryrefslogtreecommitdiff
path: root/libq
diff options
context:
space:
mode:
authorFabian Groffen <grobian@gentoo.org>2022-02-06 15:20:35 +0100
committerFabian Groffen <grobian@gentoo.org>2022-02-06 15:20:35 +0100
commit43ad7423ae06e9bcad672a21131f14e3ce790204 (patch)
tree6626157d2422ebf58fa59ea370ee848e6f99d25f /libq
parent.github: coverity also needs builddeps (diff)
downloadportage-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.c96
-rw-r--r--libq/xsystem.h8
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