Alexandre Julliard : kernel32: Set the stdin/ stdout file descriptors to match the specified Win32 handles when possible.

Alexandre Julliard julliard at winehq.org
Thu Jul 10 08:58:26 CDT 2008


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Jul 10 12:20:56 2008 +0200

kernel32: Set the stdin/stdout file descriptors to match the specified Win32 handles when possible.

---

 dlls/kernel32/process.c |   65 ++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 59 insertions(+), 6 deletions(-)

diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index 3a97c16..759612b 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -1232,10 +1232,10 @@ static char **build_envp( const WCHAR *envW )
  *
  * Fork and exec a new Unix binary, checking for errors.
  */
-static int fork_and_exec( const char *filename, const WCHAR *cmdline,
-                          const WCHAR *env, const char *newdir, DWORD flags )
+static int fork_and_exec( const char *filename, const WCHAR *cmdline, const WCHAR *env,
+                          const char *newdir, DWORD flags, STARTUPINFOW *startup )
 {
-    int fd[2];
+    int fd[2], stdin_fd = -1, stdout_fd = -1;
     int pid, err;
 
     if (!env) env = GetEnvironmentStringsW();
@@ -1246,6 +1246,28 @@ static int fork_and_exec( const char *filename, const WCHAR *cmdline,
         return -1;
     }
     fcntl( fd[1], F_SETFD, 1 );  /* set close on exec */
+
+    if (!(flags & (CREATE_NEW_PROCESS_GROUP | CREATE_NEW_CONSOLE | DETACHED_PROCESS)))
+    {
+        HANDLE hstdin, hstdout;
+
+        if (startup->dwFlags & STARTF_USESTDHANDLES)
+        {
+            hstdin = startup->hStdInput;
+            hstdout = startup->hStdOutput;
+        }
+        else
+        {
+            hstdin = GetStdHandle(STD_INPUT_HANDLE);
+            hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
+        }
+
+        if (is_console_handle( hstdin ))  hstdin  = console_handle_unmap( hstdin );
+        if (is_console_handle( hstdout )) hstdout = console_handle_unmap( hstdout );
+        wine_server_handle_to_fd( hstdin, FILE_READ_DATA, &stdin_fd, NULL );
+        wine_server_handle_to_fd( hstdout, FILE_WRITE_DATA, &stdout_fd, NULL );
+    }
+
     if (!(pid = fork()))  /* child */
     {
         char **argv = build_argv( cmdline, 0 );
@@ -1269,6 +1291,19 @@ static int fork_and_exec( const char *filename, const WCHAR *cmdline,
             }
             else if (pid != -1) _exit(0);  /* parent */
         }
+        else
+        {
+            if (stdin_fd != -1)
+            {
+                dup2( stdin_fd, 0 );
+                close( stdin_fd );
+            }
+            if (stdout_fd != -1)
+            {
+                dup2( stdout_fd, 1 );
+                close( stdout_fd );
+            }
+        }
 
         /* Reset signals that we previously set to SIG_IGN */
         signal( SIGPIPE, SIG_DFL );
@@ -1281,6 +1316,8 @@ static int fork_and_exec( const char *filename, const WCHAR *cmdline,
         write( fd[1], &err, sizeof(err) );
         _exit(1);
     }
+    if (stdin_fd != -1) close( stdin_fd );
+    if (stdout_fd != -1) close( stdout_fd );
     close( fd[1] );
     if ((pid != -1) && (read( fd[0], &err, sizeof(err) ) > 0))  /* exec failed */
     {
@@ -1388,11 +1425,11 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
                             void *res_start, void *res_end, int exec_only )
 {
     BOOL ret, success = FALSE;
-    HANDLE process_info;
+    HANDLE process_info, hstdin, hstdout;
     WCHAR *env_end;
     char *winedebug = NULL;
     RTL_USER_PROCESS_PARAMETERS *params;
-    int socketfd[2];
+    int socketfd[2], stdin_fd = -1, stdout_fd = -1;
     pid_t pid;
     int err;
 
@@ -1452,12 +1489,15 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
             if (is_console_handle(req->hstdin))  req->hstdin  = INVALID_HANDLE_VALUE;
             if (is_console_handle(req->hstdout)) req->hstdout = INVALID_HANDLE_VALUE;
             if (is_console_handle(req->hstderr)) req->hstderr = INVALID_HANDLE_VALUE;
+            hstdin = hstdout = 0;
         }
         else
         {
             if (is_console_handle(req->hstdin))  req->hstdin  = console_handle_unmap(req->hstdin);
             if (is_console_handle(req->hstdout)) req->hstdout = console_handle_unmap(req->hstdout);
             if (is_console_handle(req->hstderr)) req->hstderr = console_handle_unmap(req->hstderr);
+            hstdin  = req->hstdin;
+            hstdout = req->hstdout;
         }
 
         wine_server_add_data( req, params, params->Size );
@@ -1482,6 +1522,9 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
         return FALSE;
     }
 
+    if (hstdin) wine_server_handle_to_fd( hstdin, FILE_READ_DATA, &stdin_fd, NULL );
+    if (hstdout) wine_server_handle_to_fd( hstdout, FILE_WRITE_DATA, &stdout_fd, NULL );
+
     /* create the child process */
 
     if (exec_only || !(pid = fork()))  /* child */
@@ -1505,6 +1548,14 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
             }
             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 );
@@ -1525,6 +1576,8 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
 
     /* this is the parent */
 
+    if (stdin_fd != -1) close( stdin_fd );
+    if (stdout_fd != -1) close( stdout_fd );
     close( socketfd[0] );
     HeapFree( GetProcessHeap(), 0, winedebug );
     if (pid == -1)
@@ -1878,7 +1931,7 @@ BOOL WINAPI CreateProcessW( LPCWSTR app_name, LPWSTR cmd_line, LPSECURITY_ATTRIB
 
             if ((unix_name = wine_get_unix_file_name( name )))
             {
-                retv = (fork_and_exec( unix_name, tidy_cmdline, envW, unixdir, flags ) != -1);
+                retv = (fork_and_exec( unix_name, tidy_cmdline, envW, unixdir, flags, startup_info ) != -1);
                 HeapFree( GetProcessHeap(), 0, unix_name );
             }
         }




More information about the wine-cvs mailing list