commit: 43ad7423ae06e9bcad672a21131f14e3ce790204
Author: Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Sun Feb 6 14:20:35 2022 +0000
Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Sun Feb 6 14:20:35 2022 +0000
URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=43ad7423
libq/xsystem: cleanup/reuse same codepath, allow passing vector
Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>
libq/xsystem.c | 96 ++++++++++++++++++++++++++++++++++++----------------------
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 - <[email protected]>
+ * Copyright 2022 Fabian Groffen - <[email protected]>
*/
#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