chiark / gitweb /
add non-failing close() variant
[elogind.git] / execute.c
index 5def5ce1af5c8a553867168d9721ff3a1510852e..1ca91fddd78f8b1fdea5e431b4b00e968afa62c0 100644 (file)
--- a/execute.c
+++ b/execute.c
@@ -6,6 +6,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <string.h>
+#include <signal.h>
 
 #include "execute.h"
 #include "strv.h"
@@ -104,6 +105,40 @@ static int shift_fds(int fds[], unsigned n_fds) {
         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;
 
@@ -121,8 +156,16 @@ int exec_spawn(const ExecCommand *command, const ExecContext *context, int *fds,
                 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) {
@@ -144,7 +187,8 @@ int exec_spawn(const ExecCommand *command, const ExecContext *context, int *fds,
                 }
 
                 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;
                 }