summaryrefslogtreecommitdiffstats
path: root/dbus
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2009-04-22 04:45:46 +0200
committerLennart Poettering <lennart@poettering.net>2009-05-20 02:09:31 +0200
commit3c319c71938ab06cf6f1750750927ffb5c200de4 (patch)
tree6c0250f8a36394a68950b28673231768fd4f21ac /dbus
parent18b08180aa5a4417fa1d6d268a1aad894e8a4549 (diff)
cloexec: make use of pipe2(O_CLOEXEC) when available
This should fix another CLOEXEC race.
Diffstat (limited to 'dbus')
-rw-r--r--dbus/dbus-spawn.c34
1 files changed, 29 insertions, 5 deletions
diff --git a/dbus/dbus-spawn.c b/dbus/dbus-spawn.c
index b0b843ea..fa2e15c1 100644
--- a/dbus/dbus-spawn.c
+++ b/dbus/dbus-spawn.c
@@ -21,6 +21,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
+
+#include <config.h>
+
#include "dbus-spawn.h"
#include "dbus-sysdeps-unix.h"
#include "dbus-internals.h"
@@ -805,9 +808,25 @@ static dbus_bool_t
make_pipe (int p[2],
DBusError *error)
{
+ int retval;
+
+#ifdef HAVE_PIPE2
+ dbus_bool_t cloexec_done;
+
+ retval = pipe2 (p, O_CLOEXEC);
+ cloexec_done = retval >= 0;
+
+ /* Check if kernel seems to be too old to know pipe2(). We assume
+ that if pipe2 is available, O_CLOEXEC is too. */
+ if (retval < 0 && errno == ENOSYS)
+#endif
+ {
+ retval = pipe(p);
+ }
+
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
-
- if (pipe (p) < 0)
+
+ if (retval < 0)
{
dbus_set_error (error,
DBUS_ERROR_SPAWN_FAILED,
@@ -816,6 +835,14 @@ make_pipe (int p[2],
return FALSE;
}
+#ifdef HAVE_PIPE2
+ if (!cloexec_done)
+#endif
+ {
+ _dbus_fd_set_close_on_exec (p[0]);
+ _dbus_fd_set_close_on_exec (p[1]);
+ }
+
return TRUE;
}
@@ -1117,9 +1144,6 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p,
if (!make_pipe (child_err_report_pipe, error))
goto cleanup_and_fail;
- _dbus_fd_set_close_on_exec (child_err_report_pipe[READ_END]);
- _dbus_fd_set_close_on_exec (child_err_report_pipe[WRITE_END]);
-
if (!_dbus_full_duplex_pipe (&babysitter_pipe[0], &babysitter_pipe[1], TRUE, error))
goto cleanup_and_fail;