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  - <vap...@gentoo.org>
+ * Copyright 2022      Fabian Groffen  - <grob...@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

Reply via email to