Alexandre Julliard : kernel32: Create an orphaned process in exec_process so that all initialization is done anew in the child process .

Alexandre Julliard julliard at winehq.org
Fri Jun 17 13:13:45 CDT 2011


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Jun 16 22:46:25 2011 +0200

kernel32: Create an orphaned process in exec_process so that all initialization is done anew in the child process.

---

 dlls/kernel32/process.c |  189 +++++++++++++++++++++++++++-------------------
 1 files changed, 111 insertions(+), 78 deletions(-)

diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index 6b8ff99..f3504af 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -1786,6 +1786,85 @@ static BOOL terminate_main_thread(void)
 #endif
 
 /***********************************************************************
+ *           exec_loader
+ */
+static pid_t exec_loader( LPCWSTR cmd_line, unsigned int flags, int socketfd,
+                          int stdin_fd, int stdout_fd, const char *unixdir, char *winedebug,
+                          const struct binary_info *binary_info, int exec_only )
+{
+    pid_t pid;
+    char *wineloader = NULL;
+    const char *loader = NULL;
+    char **argv;
+
+    argv = build_argv( cmd_line, 1 );
+
+    if (!is_win64 ^ !(binary_info->flags & BINARY_FLAG_64BIT))
+        loader = get_alternate_loader( &wineloader );
+
+    if (exec_only || !(pid = fork()))  /* child */
+    {
+        char preloader_reserve[64], socket_env[64];
+
+        if (flags & (CREATE_NEW_PROCESS_GROUP | CREATE_NEW_CONSOLE | DETACHED_PROCESS))
+        {
+            if (!(pid = fork()))
+            {
+                int fd = open( "/dev/null", O_RDWR );
+                setsid();
+                /* close stdin and stdout */
+                if (fd != -1)
+                {
+                    dup2( fd, 0 );
+                    dup2( fd, 1 );
+                    close( fd );
+                }
+            }
+            else if (pid != -1) _exit(0);  /* parent */
+        }
+        else
+        {
+            if (stdin_fd != -1) dup2( stdin_fd, 0 );
+            if (stdout_fd != -1) dup2( stdout_fd, 1 );
+        }
+
+        if (stdin_fd != -1) close( stdin_fd );
+        if (stdout_fd != -1) close( stdout_fd );
+
+        /* Reset signals that we previously set to SIG_IGN */
+        signal( SIGPIPE, SIG_DFL );
+        signal( SIGCHLD, SIG_DFL );
+
+        sprintf( socket_env, "WINESERVERSOCKET=%u", socketfd );
+        sprintf( preloader_reserve, "WINEPRELOADRESERVE=%lx-%lx",
+                 (unsigned long)binary_info->res_start, (unsigned long)binary_info->res_end );
+
+        putenv( preloader_reserve );
+        putenv( socket_env );
+        if (winedebug) putenv( winedebug );
+        if (wineloader) putenv( wineloader );
+        if (unixdir) chdir(unixdir);
+
+        if (argv)
+        {
+            do
+            {
+                wine_exec_wine_binary( loader, argv, getenv("WINELOADER") );
+            }
+#ifdef __APPLE__
+            while (errno == ENOTSUP && exec_only && terminate_main_thread());
+#else
+            while (0);
+#endif
+        }
+        _exit(1);
+    }
+    HeapFree( GetProcessHeap(), 0, wineloader );
+    HeapFree( GetProcessHeap(), 0, argv );
+    return pid;
+}
+
+/***********************************************************************
  *           create_process
  *
  * Create a new process. If hFile is a valid handle we have an exe
@@ -1801,9 +1880,6 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
     HANDLE process_info;
     WCHAR *env_end;
     char *winedebug = NULL;
-    char *wineloader = NULL;
-    const char *loader = NULL;
-    char **argv;
     startup_info_t *startup_info;
     DWORD startup_info_size;
     int socketfd[2], stdin_fd = -1, stdout_fd = -1;
@@ -1817,12 +1893,42 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
         return FALSE;
     }
 
+    /* create the socket for the new process */
+
+    if (socketpair( PF_UNIX, SOCK_STREAM, 0, socketfd ) == -1)
+    {
+        SetLastError( ERROR_TOO_MANY_OPEN_FILES );
+        return FALSE;
+    }
+
+    if (exec_only)  /* things are much simpler in this case */
+    {
+        wine_server_send_fd( socketfd[1] );
+        close( socketfd[1] );
+        SERVER_START_REQ( new_process )
+        {
+            req->create_flags   = flags;
+            req->socket_fd      = socketfd[1];
+            req->exe_file       = wine_server_obj_handle( hFile );
+            ret = !wine_server_call_err( req );
+        }
+        SERVER_END_REQ;
+
+        if (ret) exec_loader( cmd_line, flags, socketfd[0], stdin_fd, stdout_fd, unixdir,
+                              winedebug, binary_info, TRUE );
+
+        close( socketfd[0] );
+        return FALSE;
+    }
+
     RtlAcquirePebLock();
 
     if (!(startup_info = create_startup_info( filename, cmd_line, cur_dir, env, flags, startup,
                                               &startup_info_size )))
     {
         RtlReleasePebLock();
+        close( socketfd[0] );
+        close( socketfd[1] );
         return FALSE;
     }
     if (!env) env = NtCurrentTeb()->Peb->ProcessParameters->Environment;
@@ -1840,16 +1946,6 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
     }
     env_end++;
 
-    /* create the socket for the new process */
-
-    if (socketpair( PF_UNIX, SOCK_STREAM, 0, socketfd ) == -1)
-    {
-        RtlReleasePebLock();
-        HeapFree( GetProcessHeap(), 0, winedebug );
-        HeapFree( GetProcessHeap(), 0, startup_info );
-        SetLastError( ERROR_TOO_MANY_OPEN_FILES );
-        return FALSE;
-    }
     wine_server_send_fd( socketfd[1] );
     close( socketfd[1] );
 
@@ -1901,77 +1997,14 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
     HeapFree( GetProcessHeap(), 0, startup_info );
 
     /* create the child process */
-    argv = build_argv( cmd_line, 1 );
-
-    if (!is_win64 ^ !(binary_info->flags & BINARY_FLAG_64BIT))
-        loader = get_alternate_loader( &wineloader );
-
-    if (exec_only || !(pid = fork()))  /* child */
-    {
-        char preloader_reserve[64], socket_env[64];
-
-        if (flags & (CREATE_NEW_PROCESS_GROUP | CREATE_NEW_CONSOLE | DETACHED_PROCESS))
-        {
-            if (!(pid = fork()))
-            {
-                int fd = open( "/dev/null", O_RDWR );
-                setsid();
-                /* close stdin and stdout */
-                if (fd != -1)
-                {
-                    dup2( fd, 0 );
-                    dup2( fd, 1 );
-                    close( fd );
-                }
-            }
-            else if (pid != -1) _exit(0);  /* parent */
-        }
-        else
-        {
-            if (stdin_fd != -1) dup2( stdin_fd, 0 );
-            if (stdout_fd != -1) dup2( stdout_fd, 1 );
-        }
-
-        if (stdin_fd != -1) close( stdin_fd );
-        if (stdout_fd != -1) close( stdout_fd );
-
-        /* Reset signals that we previously set to SIG_IGN */
-        signal( SIGPIPE, SIG_DFL );
-        signal( SIGCHLD, SIG_DFL );
-
-        sprintf( socket_env, "WINESERVERSOCKET=%u", socketfd[0] );
-        sprintf( preloader_reserve, "WINEPRELOADRESERVE=%lx-%lx",
-                 (unsigned long)binary_info->res_start, (unsigned long)binary_info->res_end );
-
-        putenv( preloader_reserve );
-        putenv( socket_env );
-        if (winedebug) putenv( winedebug );
-        if (wineloader) putenv( wineloader );
-        if (unixdir) chdir(unixdir);
 
-        if (argv)
-        {
-            do
-            {
-                wine_exec_wine_binary( loader, argv, getenv("WINELOADER") );
-            }
-#ifdef __APPLE__
-            while (errno == ENOTSUP && exec_only && terminate_main_thread());
-#else
-            while (0);
-#endif
-        }
-        _exit(1);
-    }
-
-    /* this is the parent */
+    pid = exec_loader( cmd_line, flags, socketfd[0], stdin_fd, stdout_fd, unixdir,
+                       winedebug, binary_info, FALSE );
 
     if (stdin_fd != -1) close( stdin_fd );
     if (stdout_fd != -1) close( stdout_fd );
     close( socketfd[0] );
-    HeapFree( GetProcessHeap(), 0, argv );
     HeapFree( GetProcessHeap(), 0, winedebug );
-    HeapFree( GetProcessHeap(), 0, wineloader );
     if (pid == -1)
     {
         FILE_SetDosError();




More information about the wine-cvs mailing list