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, ...);
* 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)
{
}
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));
+}
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]))
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);
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());
}