Add ability to open null fds to process_start().
authorBen Pfaff <blp@nicira.com>
Tue, 13 Jan 2009 21:15:55 +0000 (13:15 -0800)
committerBen Pfaff <blp@nicira.com>
Tue, 13 Jan 2009 21:16:48 +0000 (13:16 -0800)
lib/process.c
lib/process.h
vswitchd/bridge.c

index 3315e361abbff20e3c4c4878e9035236129213f5..d787b7bf94f3b15b97be195910c41120b949c905 100644 (file)
@@ -35,6 +35,7 @@
 #include "process.h"
 #include <assert.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <signal.h>
 #include <stdlib.h>
 #include <string.h>
@@ -111,13 +112,16 @@ process_init(void)
  * variable to find the program to execute.
  *
  * All file descriptors are closed before executing the subprocess, except for
- * fds 0, 1, and 2 and the 'n_keep_fds' fds listed in 'keep_fds'.
+ * fds 0, 1, and 2 and the 'n_keep_fds' fds listed in 'keep_fds'.  Also, any of
+ * the 'n_null_fds' fds listed in 'null_fds' are replaced by /dev/null.
  *
  * Returns 0 if successful, otherwise a positive errno value indicating the
  * error.  If successful, '*pp' is assigned a new struct process that may be
  * used to query the process's status.  On failure, '*pp' is set to NULL. */
 int
-process_start(char **argv, const int keep_fds[], size_t n_keep_fds,
+process_start(char **argv,
+              const int keep_fds[], size_t n_keep_fds,
+              const int null_fds[], size_t n_null_fds,
               struct process **pp)
 {
     sigset_t oldsigs;
@@ -187,8 +191,12 @@ process_start(char **argv, const int keep_fds[], size_t n_keep_fds,
         int fd;
 
         unblock_sigchld(&oldsigs);
-        for (fd = 3; fd < fd_max; fd++) {
-            if (!is_member(fd, keep_fds, n_keep_fds)) {
+        for (fd = 0; fd < fd_max; fd++) {
+            if (is_member(fd, null_fds, n_null_fds)) {
+                int nullfd = open("/dev/null", O_RDWR);
+                dup2(nullfd, fd);
+                close(nullfd);
+            } else if (fd >= 3 && !is_member(fd, keep_fds, n_keep_fds)) {
                 close(fd);
             }
         }
@@ -264,12 +272,16 @@ process_status(const struct process *p)
 }
 
 int
-process_run(char **argv, int *status)
+process_run(char **argv,
+            const int keep_fds[], size_t n_keep_fds,
+            const int null_fds[], size_t n_null_fds,
+            int *status)
 {
     struct process *p;
     int retval;
 
-    retval = process_start(argv, NULL, 0, &p);
+    retval = process_start(argv, keep_fds, n_keep_fds, null_fds, n_null_fds,
+                           &p);
     if (retval) {
         *status = 0;
         return retval;
index b9c80913b3fe32083f6b03fdd9fef6e33ff336e2..fcdd91303de8bfebab48a02bdc20adfb0a966056 100644 (file)
 
 struct process;
 void process_init(void);
-int process_start(char **argv, const int *keep_fds, size_t n_keep_fds,
+int process_start(char **argv,
+                  const int *keep_fds, size_t n_keep_fds,
+                  const int *null_fds, size_t n_null_fds,
                   struct process **);
 void process_destroy(struct process *);
 int process_kill(const struct process *, int signr);
 
-int process_run(char **argv, int *status);
+int process_run(char **argv,
+                const int *keep_fds, size_t n_keep_fds,
+                  const int *null_fds, size_t n_null_fds,
+                int *status);
 
 pid_t process_pid(const struct process *);
 const char *process_name(const struct process *);
index f4735c76748ecb8246d46b34118d167568dae534..49b294ec2e939f2ea88f63b8def43a92e9e69a74 100644 (file)
@@ -653,10 +653,11 @@ start_secchan(struct bridge *br)
 
     /* Start secchan. */
     if (!br->controller) {
-        retval = process_start(argv.names, &sockets[1], 1, &br->secchan);
+        retval = process_start(argv.names, &sockets[1], 1, NULL, 0,
+                               &br->secchan);
         close(sockets[1]);
     } else {
-        retval = process_start(argv.names, NULL, 0, &br->secchan);
+        retval = process_start(argv.names, NULL, 0, NULL, 0, &br->secchan);
     }
     svec_destroy(&argv);
     if (retval) {