diff options
author | Chengwei Yang <chengwei.yang@intel.com> | 2013-09-10 22:29:19 +0800 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2013-09-13 13:33:21 +0100 |
commit | 7a53684d422d10d5e89ff0dee7f3c7539de11341 (patch) | |
tree | 0d352c17a66e5f850acbeac484053e62352fb5ba | |
parent | 37df7c316bf2ab4ed3a64910fc0030c095f7b5ab (diff) | |
download | dbus-7a53684d422d10d5e89ff0dee7f3c7539de11341.tar.gz |
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 <simon.mcvittie@collabora.co.uk>
-rw-r--r-- | dbus/dbus-sysdeps-unix.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c index e31c7355..b84ad0e9 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) |