Add function get_null_fd(), to reduce code redundancy.
authorBen Pfaff <blp@nicira.com>
Wed, 15 Jul 2009 17:54:51 +0000 (10:54 -0700)
committerBen Pfaff <blp@nicira.com>
Thu, 16 Jul 2009 16:17:03 +0000 (09:17 -0700)
extras/ezio/ezio-term.c
lib/process.c
lib/socket-util.c
lib/socket-util.h
secchan/executer.c

index 93ec1c28056e4bb2ba0b3a3f9a61edccb97ba14d..846ccfded7cfffce0904e05f094b05e2f8663eec 100644 (file)
@@ -106,7 +106,7 @@ main(int argc, char *argv[])
     argv += optind;
 
     /* Make sure that the ezio3 terminfo entry is available. */
-    dummy_fd = open("/dev/null", O_RDWR);
+    dummy_fd = get_null_fd();
     if (dummy_fd >= 0) {
         if (setupterm("ezio3", dummy_fd, &retval) == ERR) {
             if (retval == 0) {
@@ -118,9 +118,6 @@ main(int argc, char *argv[])
             }
         }
         del_curterm(cur_term);
-        close(dummy_fd);
-    } else {
-        ovs_error(errno, "failed to open /dev/null");
     }
 
     /* Lock serial port. */
index f752a3560c39ee7fbcf2e385c1cfd1c41ce6b8f5..7b583cac0d33d69b2c7cd123dbff15a3753397f5 100644 (file)
@@ -187,6 +187,8 @@ process_start(char **argv,
         unblock_sigchld(&oldsigs);
         for (fd = 0; fd < fd_max; fd++) {
             if (is_member(fd, null_fds, n_null_fds)) {
+                /* We can't use get_null_fd() here because we might have
+                 * already closed its fd. */
                 int nullfd = open("/dev/null", O_RDWR);
                 dup2(nullfd, fd);
                 close(nullfd);
index 33e179e1cf55e93321a508dabc2639a9d12388e7..086a329eab937897f7c7412c18487774e00777be 100644 (file)
@@ -299,6 +299,24 @@ guess_netmask(uint32_t ip)
             : htonl(0));                          /* ??? */
 }
 
+/* Returns a readable and writable fd for /dev/null, if successful, otherwise
+ * a negative errno value.  The caller must not close the returned fd (because
+ * the same fd will be handed out to subsequent callers). */
+int
+get_null_fd(void)
+{
+    static int null_fd = -1;
+    if (null_fd < 0) {
+        null_fd = open("/dev/null", O_RDWR);
+        if (null_fd < 0) {
+            int error = errno;
+            VLOG_ERR("could not open /dev/null: %s", strerror(error));
+            return -error;
+        }
+    }
+    return null_fd;
+}
+
 int
 read_fully(int fd, void *p_, size_t size, size_t *bytes_read)
 {
index 34dc92f6be2e3989a17900203ed46a6d3264f231..3ba2c477be1e2a311df950df841b0723ad9218ed 100644 (file)
@@ -32,6 +32,7 @@ int make_unix_socket(int style, bool nonblock, bool passcred,
                      const char *bind_path, const char *connect_path);
 int get_unix_name_len(socklen_t sun_len);
 uint32_t guess_netmask(uint32_t ip);
+int get_null_fd(void);
 
 int read_fully(int fd, void *, size_t, size_t *bytes_read);
 int write_fully(int fd, const void *, size_t, size_t *bytes_written);
index 210d7cbcf039bdd8f7a6f7fbafb99848104b8c2a..6b8c8e52b133dcf3c9470670c5018411cb3edc1e 100644 (file)
@@ -71,10 +71,7 @@ struct executer {
 };
 
 /* File descriptors for waking up when a child dies. */
-static int signal_fds[2];
-
-/* File descriptor for /dev/null. */
-static int null_fd = -1;
+static int signal_fds[2] = {-1, -1};
 
 static void send_child_status(struct rconn *, uint32_t xid, uint32_t status,
                               const void *data, size_t size);
@@ -205,9 +202,9 @@ executer_handle_request(struct executer *e, struct rconn *rconn,
          * subprocesses at once?  Would also want to catch fatal signals and
          * kill them at the same time though. */
         fatal_signal_fork();
-        dup2(null_fd, 0);
+        dup2(get_null_fd(), 0);
         dup2(output_fds[1], 1);
-        dup2(null_fd, 2);
+        dup2(get_null_fd(), 2);
         max_fds = get_max_fds();
         for (i = 3; i < max_fds; i++) {
             close(i);
@@ -448,7 +445,13 @@ executer_create(const char *command_acl, const char *command_dir,
     struct sigaction sa;
 
     *executerp = NULL;
-    if (null_fd == -1) {
+    if (signal_fds[0] == -1) {
+        /* Make sure we can get a fd for /dev/null. */
+        int null_fd = get_null_fd();
+        if (null_fd < 0) {
+            return -null_fd;
+        }
+
         /* Create pipe for notifying us that SIGCHLD was invoked. */
         if (pipe(signal_fds)) {
             VLOG_ERR("pipe failed: %s", strerror(errno));
@@ -456,16 +459,6 @@ executer_create(const char *command_acl, const char *command_dir,
         }
         set_nonblocking(signal_fds[0]);
         set_nonblocking(signal_fds[1]);
-
-        /* Open /dev/null. */
-        null_fd = open("/dev/null", O_RDWR);
-        if (null_fd < 0) {
-            int error = errno;
-            VLOG_ERR("could not open /dev/null: %s", strerror(error));
-            close(signal_fds[0]);
-            close(signal_fds[1]);
-            return error;
-        }
     }
 
     /* Set up signal handler. */