From a8b5f8b423e5d54ba8bb6e68cc5b9dc22215d302 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Wed, 15 Jul 2009 10:54:51 -0700 Subject: [PATCH] Add function get_null_fd(), to reduce code redundancy. --- extras/ezio/ezio-term.c | 5 +---- lib/process.c | 2 ++ lib/socket-util.c | 18 ++++++++++++++++++ lib/socket-util.h | 1 + secchan/executer.c | 27 ++++++++++----------------- 5 files changed, 32 insertions(+), 21 deletions(-) diff --git a/extras/ezio/ezio-term.c b/extras/ezio/ezio-term.c index 93ec1c28..846ccfde 100644 --- a/extras/ezio/ezio-term.c +++ b/extras/ezio/ezio-term.c @@ -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. */ diff --git a/lib/process.c b/lib/process.c index f752a356..7b583cac 100644 --- a/lib/process.c +++ b/lib/process.c @@ -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); diff --git a/lib/socket-util.c b/lib/socket-util.c index 33e179e1..086a329e 100644 --- a/lib/socket-util.c +++ b/lib/socket-util.c @@ -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) { diff --git a/lib/socket-util.h b/lib/socket-util.h index 34dc92f6..3ba2c477 100644 --- a/lib/socket-util.h +++ b/lib/socket-util.h @@ -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); diff --git a/secchan/executer.c b/secchan/executer.c index 210d7cbc..6b8c8e52 100644 --- a/secchan/executer.c +++ b/secchan/executer.c @@ -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. */ -- 2.30.2