#include <fcntl.h>
#include <unistd.h>
#include <string.h>
+#include <signal.h>
#include "execute.h"
#include "strv.h"
if ((nfd = fcntl(fds[i], F_DUPFD, i+3)) < 0)
return -errno;
- assert_se(close_nointr(fds[i]));
+ assert_se(close_nointr(fds[i]) == 0);
fds[i] = nfd;
/* Hmm, the fd we wanted isn't free? Then
return 0;
}
+static int flags_fds(int fds[], unsigned n_fds) {
+ unsigned i;
+
+ if (n_fds <= 0)
+ return 0;
+
+ assert(fds);
+
+ /* Drops O_NONBLOCK and FD_CLOEXEC from the file flags */
+
+ for (i = 0; i < n_fds; i++) {
+ int flags;
+
+ if ((flags = fcntl(fds[i], F_GETFL, 0)) < 0)
+ return -errno;
+
+ /* Since we are at it, let's make sure that nobody
+ * forgot setting O_NONBLOCK for all our fds */
+
+ if (fcntl(fds[i], F_SETFL, flags &~O_NONBLOCK) < 0)
+ return -errno;
+
+ if ((flags = fcntl(fds[i], F_GETFD, 0)) < 0)
+ return -errno;
+
+ /* Also make sure nobody forgot O_CLOEXEC for all our
+ * fds */
+ if (fcntl(fds[i], F_SETFD, flags &~FD_CLOEXEC) < 0)
+ return -errno;
+ }
+
+ return 0;
+}
+
int exec_spawn(const ExecCommand *command, const ExecContext *context, int *fds, unsigned n_fds, pid_t *ret) {
pid_t pid;
assert(ret);
assert(fds || n_fds <= 0);
- log_debug("About to execute %s", command->path);
+ log_debug("about to execute %s", command->path);
if ((pid = fork()) < 0)
return -errno;
char **e, **f = NULL;
int i, r;
char t[16];
+ sigset_t ss;
+
/* child */
+ if (sigemptyset(&ss) < 0 ||
+ sigprocmask(SIG_SETMASK, &ss, NULL) < 0) {
+ r = EXIT_SIGNAL_MASK;
+ goto fail;
+ }
+
umask(context->umask);
if (chdir(context->directory ? context->directory : "/") < 0) {
}
if (close_fds(fds, n_fds) < 0 ||
- shift_fds(fds, n_fds) < 0) {
+ shift_fds(fds, n_fds) < 0 ||
+ flags_fds(fds, n_fds) < 0) {
r = EXIT_FDS;
goto fail;
}
_exit(r);
}
+
+ log_debug("executed %s as %llu", command->path, (unsigned long long) pid);
+
*ret = pid;
return 0;
}