Alexandre Julliard : ntdll: Avoid the close-on-exec race with pipe() on kernels that support pipe2().

Alexandre Julliard julliard at winehq.org
Wed Jul 1 09:28:10 CDT 2009


Module: wine
Branch: master
Commit: 6f68b774d7c04016a05c2d5829d0934baba02dbe
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=6f68b774d7c04016a05c2d5829d0934baba02dbe

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Jul  1 12:13:34 2009 +0200

ntdll: Avoid the close-on-exec race with pipe() on kernels that support pipe2().

---

 configure               |    2 ++
 configure.ac            |    1 +
 dlls/ntdll/ntdll_misc.h |    1 +
 dlls/ntdll/server.c     |   35 ++++++++++++++++++++++++++++-------
 dlls/ntdll/thread.c     |    3 +--
 include/config.h.in     |    3 +++
 6 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/configure b/configure
index 51a5440..8ce9434 100755
--- a/configure
+++ b/configure
@@ -18351,6 +18351,7 @@ CFLAGS="$CFLAGS $BUILTINFLAG"
 
 
 
+
 for ac_func in \
 	_pclose \
 	_popen \
@@ -18388,6 +18389,7 @@ for ac_func in \
 	memmove \
 	mmap \
 	pclose \
+	pipe2 \
 	poll \
 	popen \
 	prctl \
diff --git a/configure.ac b/configure.ac
index 2dafff3..c6843d9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1610,6 +1610,7 @@ AC_CHECK_FUNCS(\
 	memmove \
 	mmap \
 	pclose \
+	pipe2 \
 	poll \
 	popen \
 	prctl \
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index b6a3d88..8da7148 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -85,6 +85,7 @@ extern void server_leave_uninterrupted_section( RTL_CRITICAL_SECTION *cs, sigset
 extern int server_remove_fd_from_cache( HANDLE handle );
 extern int server_get_unix_fd( HANDLE handle, unsigned int access, int *unix_fd,
                                int *needs_close, enum server_fd_type *type, unsigned int *options );
+extern int server_pipe( int fd[2] );
 
 /* security descriptors */
 NTSTATUS NTDLL_create_struct_sd(PSECURITY_DESCRIPTOR nt_sd, struct security_descriptor **server_sd,
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
index 9e54ada..e90ea72 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -663,6 +663,32 @@ void CDECL wine_server_release_fd( HANDLE handle, int unix_fd )
 
 
 /***********************************************************************
+ *           server_pipe
+ *
+ * Create a pipe for communicating with the server.
+ */
+int server_pipe( int fd[2] )
+{
+    int ret;
+#ifdef HAVE_PIPE2
+    static int have_pipe2 = 1;
+
+    if (have_pipe2)
+    {
+        if (!(ret = pipe2( fd, O_CLOEXEC ))) return ret;
+        if (errno == ENOSYS || errno == EINVAL) have_pipe2 = 0;  /* don't try again */
+    }
+#endif
+    if (!(ret = pipe( fd )))
+    {
+        fcntl( fd[0], F_SETFD, FD_CLOEXEC );
+        fcntl( fd[1], F_SETFD, FD_CLOEXEC );
+    }
+    return ret;
+}
+
+
+/***********************************************************************
  *           start_server
  *
  * Start a new wine server.
@@ -1029,18 +1055,13 @@ size_t server_init_thread( void *entry_point )
     sigaction( SIGCHLD, &sig_act, NULL );
 
     /* create the server->client communication pipes */
-    if (pipe( reply_pipe ) == -1) server_protocol_perror( "pipe" );
-    if (pipe( ntdll_get_thread_data()->wait_fd ) == -1) server_protocol_perror( "pipe" );
+    if (server_pipe( reply_pipe ) == -1) server_protocol_perror( "pipe" );
+    if (server_pipe( ntdll_get_thread_data()->wait_fd ) == -1) server_protocol_perror( "pipe" );
     wine_server_send_fd( reply_pipe[1] );
     wine_server_send_fd( ntdll_get_thread_data()->wait_fd[1] );
     ntdll_get_thread_data()->reply_fd = reply_pipe[0];
     close( reply_pipe[1] );
 
-    /* set close on exec flag */
-    fcntl( ntdll_get_thread_data()->reply_fd, F_SETFD, 1 );
-    fcntl( ntdll_get_thread_data()->wait_fd[0], F_SETFD, 1 );
-    fcntl( ntdll_get_thread_data()->wait_fd[1], F_SETFD, 1 );
-
     SERVER_START_REQ( init_thread )
     {
         req->unix_pid    = getpid();
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index 0b924b2..0c73ffd 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -488,8 +488,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
         return result.create_thread.status;
     }
 
-    if (pipe( request_pipe ) == -1) return STATUS_TOO_MANY_OPENED_FILES;
-    fcntl( request_pipe[1], F_SETFD, 1 ); /* set close on exec flag */
+    if (server_pipe( request_pipe ) == -1) return STATUS_TOO_MANY_OPENED_FILES;
     wine_server_send_fd( request_pipe[0] );
 
     SERVER_START_REQ( new_thread )
diff --git a/include/config.h.in b/include/config.h.in
index e12aa1a..6ef0892 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -552,6 +552,9 @@
 /* Define to 1 if the system has the type `pid_t'. */
 #undef HAVE_PID_T
 
+/* Define to 1 if you have the `pipe2' function. */
+#undef HAVE_PIPE2
+
 /* Define to 1 if you have the <png.h> header file. */
 #undef HAVE_PNG_H
 




More information about the wine-cvs mailing list