From 7a53684d422d10d5e89ff0dee7f3c7539de11341 Mon Sep 17 00:00:00 2001 From: Chengwei Yang Date: Tue, 10 Sep 2013 22:29:19 +0800 Subject: [PATCH] Check EINVAL for socketpair and retry without SOCK_CLOEXEC As the same as _dbus_open_socket() and _dbus_full_duplex_pipe(), socketpair() may fail with EINVAL if call with SOCK_CLOEXEC. Check for the failure and retry without SOCK_CLOEXEC, in addition, only call _dbus_fd_set_close_on_exec() if the socketpair failure happened. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=69073 [trivial coding style fixes -smcv] Reviewed-by: Simon McVittie --- dbus/dbus-sysdeps-unix.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c index e31c73558..b84ad0e97 100644 --- a/dbus/dbus-sysdeps-unix.c +++ b/dbus/dbus-sysdeps-unix.c @@ -887,16 +887,24 @@ _dbus_connect_exec (const char *path, { int fds[2]; pid_t pid; + int retval; + dbus_bool_t cloexec_done = 0; _DBUS_ASSERT_ERROR_IS_CLEAR (error); _dbus_verbose ("connecting to process %s\n", path); - if (socketpair (AF_UNIX, SOCK_STREAM #ifdef SOCK_CLOEXEC - |SOCK_CLOEXEC + retval = socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds); + cloexec_done = (retval >= 0); + + if (retval < 0 && (errno == EINVAL)) #endif - , 0, fds) < 0) + { + retval = socketpair (AF_UNIX, SOCK_STREAM, 0, fds); + } + + if (retval < 0) { dbus_set_error (error, _dbus_error_from_errno (errno), @@ -905,8 +913,11 @@ _dbus_connect_exec (const char *path, return -1; } - _dbus_fd_set_close_on_exec (fds[0]); - _dbus_fd_set_close_on_exec (fds[1]); + if (!cloexec_done) + { + _dbus_fd_set_close_on_exec (fds[0]); + _dbus_fd_set_close_on_exec (fds[1]); + } pid = fork (); if (pid < 0) -- 2.47.3