]> git.ipfire.org Git - thirdparty/mlmmj.git/commitdiff
utils: add 2 wrappers around posix_spawn
authorBaptiste Daroussin <bapt@FreeBSD.org>
Mon, 24 Oct 2022 11:36:14 +0000 (13:36 +0200)
committerBaptiste Daroussin <bapt@FreeBSD.org>
Mon, 24 Oct 2022 11:36:14 +0000 (13:36 +0200)
the goal here it to avoid code duplication around fork and execvp

include/utils.h
src/utils.c
tests/mlmmj.c

index 4648e1e23a6ae78a358d98f441e55ed014418356..7e4b4bd8e22566cf7ad869d7873aaaf7b274b472 100644 (file)
@@ -26,3 +26,5 @@ char *lowercase(const char *);
 intmax_t strtoim(const char *np, intmax_t minval, intmax_t maxval,
     const char **errpp);
 uintmax_t strtouim(const char *, uintmax_t, uintmax_t, const char **);
+void exec_or_die(const char *arg, ...);
+int exec_and_wait(const char *arg, ...);
index 7644dc48c6aaf59a6a2b901784540d38aa7c2ec3..0a6eef6bbecf7506dc1af3e8b45d856b01c71825 100644 (file)
  * IN THE SOFTWARE.
  */
 
-#include <inttypes.h>
+#include <sys/wait.h>
+
 #include <ctype.h>
+#include <err.h>
 #include <errno.h>
+#include <inttypes.h>
+#include <spawn.h>
+#include <unistd.h>
 
 #include "xmalloc.h"
 #include "utils.h"
 
+extern char **environ;
+
 intmax_t
 strtoim(const char *np, intmax_t minval, intmax_t maxval, const char **errpp)
 {
@@ -104,3 +111,62 @@ lowercase(const char *address)
        }
        return (loweraddress);
 }
+
+void
+exec_or_die(const char *arg, ...)
+{
+       va_list ap;
+       const char **argv;
+       int n;
+
+       va_start(ap, arg);
+       n = 1;
+       while (va_arg(ap, char *) != NULL)
+               n++;
+       va_end(ap);
+       argv = xmalloc((n +1) * sizeof(argv));
+       va_start(ap, arg);
+       argv[0] = arg;
+       n = 1;
+       while ((argv[n] = va_arg(ap, char *)) != NULL)
+               n++;
+       va_end(ap);
+       execvp(argv[0], (char *const *)argv);
+       err(EXIT_FAILURE, "Execution failed for '%s'", argv[0]);
+}
+
+int
+exec_and_wait(const char *arg, ...)
+{
+       va_list ap;
+       const char **argv;
+       int n;
+       pid_t p;
+       int pstat;
+
+       va_start(ap, arg);
+       n = 1;
+       while (va_arg(ap, char *) != NULL)
+               n++;
+       va_end(ap);
+       argv = xmalloc((n +1) * sizeof(argv));
+       va_start(ap, arg);
+       argv[0] = arg;
+       n = 1;
+       while ((argv[n] = va_arg(ap, char *)) != NULL)
+               n++;
+       va_end(ap);
+
+       if (0 != posix_spawnp(&p, argv[0], NULL, NULL,
+                               (char *const *) argv, environ)) {
+               warn("Execution failed for '%s'", argv[0]);
+               return (-1);
+       }
+       while (waitpid(p, &pstat, 0) == -1) {
+               if (errno != EINTR)
+                       warn("Could not wait for the execution of '%s'", argv[0]);
+               return (-1);
+       }
+
+       return (WEXITSTATUS(pstat));
+}
index c81695ac74d229e2a35f7e70e577b5c1e56aef46..f277f69ef43e51444f38e461662167ad1b9e531f 100644 (file)
@@ -53,6 +53,8 @@ ATF_TC_WITHOUT_HEAD(mygetline);
 ATF_TC_WITHOUT_HEAD(init_sock);
 ATF_TC_WITHOUT_HEAD(genmsgid);
 ATF_TC_WITHOUT_HEAD(lowercase);
+ATF_TC_WITHOUT_HEAD(exec_or_die);
+ATF_TC_WITHOUT_HEAD(exec_and_wait);
 
 #ifndef NELEM
 #define NELEM(array)    (sizeof(array) / sizeof((array)[0]))
@@ -256,6 +258,35 @@ ATF_TC_BODY(genmsgid, tc)
        free(test);
 }
 
+ATF_TC_BODY(exec_or_die, tc)
+{
+       pid_t p = atf_utils_fork();
+       if (p == 0) {
+               exec_or_die("/usr/bin/nopenope", NULL);
+       }
+       atf_utils_wait(p, 1, "", "mlmmj: Execution failed for '/usr/bin/nopenope': No such file or directory\n");
+       p = atf_utils_fork();
+       if (p == 0) {
+               exec_or_die("/usr/bin/true", (char *)NULL);
+       }
+       atf_utils_wait(p, 0, "", "");
+       p = atf_utils_fork();
+       if (p == 0) {
+               exec_or_die("/bin/echo", "a", (char *)NULL);
+       }
+       atf_utils_wait(p, 0, "a\n", "");
+}
+
+ATF_TC_BODY(exec_and_wait, tc)
+{
+       int val = exec_and_wait("/usr/bin/nopenope", NULL);
+       ATF_REQUIRE_EQ(val, -1);
+       val = exec_and_wait("/usr/bin/true", NULL);
+       ATF_REQUIRE_EQ(val, 0);
+       val = exec_and_wait("/usr/bin/false", NULL);
+       ATF_REQUIRE_EQ(val, 1);
+}
+
 ATF_TP_ADD_TCS(tp)
 {
        ATF_TP_ADD_TC(tp, random_int);
@@ -266,6 +297,8 @@ ATF_TP_ADD_TCS(tp)
        ATF_TP_ADD_TC(tp, lowercase);
        ATF_TP_ADD_TC(tp, init_sock);
        ATF_TP_ADD_TC(tp, genmsgid);
+       ATF_TP_ADD_TC(tp, exec_or_die);
+       ATF_TP_ADD_TC(tp, exec_and_wait);
 
        return (atf_no_error());
 }