summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2009-04-22 04:22:51 +0200
committerLennart Poettering <lennart@poettering.net>2009-05-20 02:09:31 +0200
commit44f3a1465a5a3f6d2e022409a960443441662629 (patch)
tree7ade2ca895107f2b5f7de12bbe3bb619cf863477
parent004f01fa451b0341e7ea69ce7f08a1c4690f759a (diff)
cloexec: set FD_CLOEXEC for all full duplex pipes
All users of full duplex pipes enable FD_CLOEXEC later anyway so let's just do it as part of _dbus_full_duplex_pipe. By side effect this allows to make use of SOCK_CLOEXEC which fixes a race when forking/execing from a different thread at the same time as we ar in this function.
-rw-r--r--bus/main.c3
-rw-r--r--dbus/dbus-server-debug-pipe.c3
-rw-r--r--dbus/dbus-spawn.c3
-rw-r--r--dbus/dbus-sysdeps-unix.c29
4 files changed, 26 insertions, 12 deletions
diff --git a/bus/main.c b/bus/main.c
index 51538fe7..d86825a5 100644
--- a/bus/main.c
+++ b/bus/main.c
@@ -208,9 +208,6 @@ setup_reload_pipe (DBusLoop *loop)
exit (1);
}
- _dbus_fd_set_close_on_exec (reload_pipe[0]);
- _dbus_fd_set_close_on_exec (reload_pipe[1]);
-
watch = _dbus_watch_new (reload_pipe[RELOAD_READ_END],
DBUS_WATCH_READABLE, TRUE,
handle_reload_watch, NULL, NULL);
diff --git a/dbus/dbus-server-debug-pipe.c b/dbus/dbus-server-debug-pipe.c
index 24b0ce34..b59f7491 100644
--- a/dbus/dbus-server-debug-pipe.c
+++ b/dbus/dbus-server-debug-pipe.c
@@ -253,9 +253,6 @@ _dbus_transport_debug_pipe_new (const char *server_name,
return NULL;
}
- _dbus_fd_set_close_on_exec (client_fd);
- _dbus_fd_set_close_on_exec (server_fd);
-
client_transport = _dbus_transport_new_for_socket (client_fd,
NULL, &address);
if (client_transport == NULL)
diff --git a/dbus/dbus-spawn.c b/dbus/dbus-spawn.c
index f4e3b587..b0b843ea 100644
--- a/dbus/dbus-spawn.c
+++ b/dbus/dbus-spawn.c
@@ -1123,9 +1123,6 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p,
if (!_dbus_full_duplex_pipe (&babysitter_pipe[0], &babysitter_pipe[1], TRUE, error))
goto cleanup_and_fail;
- _dbus_fd_set_close_on_exec (babysitter_pipe[0]);
- _dbus_fd_set_close_on_exec (babysitter_pipe[1]);
-
/* Setting up the babysitter is only useful in the parent,
* but we don't want to run out of memory and fail
* after we've already forked, since then we'd leak
diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c
index 597398bb..8b225e7e 100644
--- a/dbus/dbus-sysdeps-unix.c
+++ b/dbus/dbus-sysdeps-unix.c
@@ -3067,6 +3067,8 @@ _dbus_print_backtrace (void)
* Creates a full-duplex pipe (as in socketpair()).
* Sets both ends of the pipe nonblocking.
*
+ * Marks both file descriptors as close-on-exec
+ *
* @todo libdbus only uses this for the debug-pipe server, so in
* principle it could be in dbus-sysdeps-util.c, except that
* dbus-sysdeps-util.c isn't in libdbus when tests are enabled and the
@@ -3086,16 +3088,37 @@ _dbus_full_duplex_pipe (int *fd1,
{
#ifdef HAVE_SOCKETPAIR
int fds[2];
+ int retval;
- _DBUS_ASSERT_ERROR_IS_CLEAR (error);
-
- if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) < 0)
+#ifdef SOCK_CLOEXEC
+ dbus_bool_t cloexec_done;
+
+ retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
+ cloexec_done = retval >= 0;
+
+ if (retval < 0 && errno == EINVAL)
+#endif
+ {
+ retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
+ }
+
+ if (retval < 0)
{
dbus_set_error (error, _dbus_error_from_errno (errno),
"Could not create full-duplex pipe");
return FALSE;
}
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+#ifdef SOCK_CLOEXEC
+ if (!cloexec_done)
+#endif
+ {
+ _dbus_fd_set_close_on_exec (fds[0]);
+ _dbus_fd_set_close_on_exec (fds[1]);
+ }
+
if (!blocking &&
(!_dbus_set_fd_nonblocking (fds[0], NULL) ||
!_dbus_set_fd_nonblocking (fds[1], NULL)))