]> git.saurik.com Git - wxWidgets.git/commitdiff
wxExecute() fixes and doc updates: the return value for sync exec case is now
authorVadim Zeitlin <vadim@wxwidgets.org>
Wed, 17 Feb 1999 21:04:47 +0000 (21:04 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Wed, 17 Feb 1999 21:04:47 +0000 (21:04 +0000)
the exit code of the process and not its pid. Warning: MSW code is untested.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1712 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/latex/wx/function.tex
src/gtk/utilsgtk.cpp
src/gtk1/utilsgtk.cpp
src/msw/utilsexc.cpp

index d4888be1db3db647e3bdae4c71b65e8442f30ebd..fe92c20c42d165482ae79a5456d57d2c29a27f06 100644 (file)
@@ -946,9 +946,13 @@ arguments, terminated by NULL.
 If {\it sync} is FALSE (the default), flow of control immediately returns.
 If TRUE, the current application waits until the other program has terminated.
 
-The return value is the process id, not the exit code of invoked program (for
-this you should use wxProcess). A zero value indicates that the command could
-not be executed.
+In the case of synchronous execution, the return value is trhe exit code of
+the process (which terminates by the moment the function returns) and will be
+$-1$ if the process couldn't be started and typically 0 if the process
+terminated successfully.
+
+For asynchronous execution, however, the return value is the process id and
+zero value indicates that the command could not be executed.
 
 If callback isn't NULL and if execution is asynchronous (note that callback
 parameter can not be non NULL for synchronous execution), 
index 9f16f5c0d12fe6a38ee0c961f70a29cfbc542447..a280a4c189827c7c3a9a58cf340b4d653bc7b70a 100644 (file)
@@ -252,10 +252,14 @@ bool wxDirExists( const wxString& dir )
 // subprocess routines
 //------------------------------------------------------------------------
 
+// if pid > 0, the execution is async and the data is freed in
+// GTK_EndProcessDetector, if pid < 0, the execution is synchronous and the
+// caller (wxExecute) frees the data
 struct wxEndProcessData
 {
     gint pid, tag;
     wxProcess *process;
+    int  exitcode;
 };
 
 static void GTK_EndProcessDetector(gpointer data, gint source,
@@ -274,7 +278,7 @@ static void GTK_EndProcessDetector(gpointer data, gint source,
     //     one)
     int status = -1;
 #if !defined(__sgi)
-    wait4(proc_data->pid, &status, 0, (rusage *) NULL);
+    wait4(pid, &status, 0, (rusage *) NULL);
 #else
     wait3(&status, 0, (rusage *) NULL);
 #endif
@@ -286,9 +290,16 @@ static void GTK_EndProcessDetector(gpointer data, gint source,
         proc_data->process->OnTerminate(proc_data->pid, status);
 
     if (proc_data->pid > 0)
+    {
         delete proc_data;
+    }
     else
+    {
+        // wxExecute() will know about it
+        proc_data->exitcode = status;
+
         proc_data->pid = 0;
+    }
 }
 
 long wxExecute( char **argv, bool sync, wxProcess *process )
@@ -356,25 +367,34 @@ long wxExecute( char **argv, bool sync, wxProcess *process )
         close(end_proc_detect[1]); // close writing side
         data->tag = gdk_input_add(end_proc_detect[0], GDK_INPUT_READ,
                                   GTK_EndProcessDetector, (gpointer)data);
-        data->pid = pid;
-        if (!sync)
-        {
-            data->process = process;
-        }
-        else
+        if ( sync )
         {
-            data->process = process;
-            data->pid = -(data->pid);
+            wxASSERT_MSG( !process, "wxProcess param ignored for sync exec" );
+            data->process = NULL;
+
+            // sync execution: indicate it by negating the pid
+            data->pid = -pid;
 
+            // it will be set to 0 from GTK_EndProcessDetector
             while (data->pid != 0)
                 wxYield();
 
+            int exitcode = data->exitcode;
+
             delete data;
+
+            return exitcode;
         }
+        else
+        {
+            // async execution, nothing special to do - caller will be
+            // notified about the process terminationif process != NULL, data
+            // will be deleted in GTK_EndProcessDetector
+            data->process = process;
+            data->pid = pid;
 
-        // @@@ our return value indicates success even if execvp() in the child
-        //     failed!
-        return pid;
+            return pid;
+        }
     }
 }
 
index 9f16f5c0d12fe6a38ee0c961f70a29cfbc542447..a280a4c189827c7c3a9a58cf340b4d653bc7b70a 100644 (file)
@@ -252,10 +252,14 @@ bool wxDirExists( const wxString& dir )
 // subprocess routines
 //------------------------------------------------------------------------
 
+// if pid > 0, the execution is async and the data is freed in
+// GTK_EndProcessDetector, if pid < 0, the execution is synchronous and the
+// caller (wxExecute) frees the data
 struct wxEndProcessData
 {
     gint pid, tag;
     wxProcess *process;
+    int  exitcode;
 };
 
 static void GTK_EndProcessDetector(gpointer data, gint source,
@@ -274,7 +278,7 @@ static void GTK_EndProcessDetector(gpointer data, gint source,
     //     one)
     int status = -1;
 #if !defined(__sgi)
-    wait4(proc_data->pid, &status, 0, (rusage *) NULL);
+    wait4(pid, &status, 0, (rusage *) NULL);
 #else
     wait3(&status, 0, (rusage *) NULL);
 #endif
@@ -286,9 +290,16 @@ static void GTK_EndProcessDetector(gpointer data, gint source,
         proc_data->process->OnTerminate(proc_data->pid, status);
 
     if (proc_data->pid > 0)
+    {
         delete proc_data;
+    }
     else
+    {
+        // wxExecute() will know about it
+        proc_data->exitcode = status;
+
         proc_data->pid = 0;
+    }
 }
 
 long wxExecute( char **argv, bool sync, wxProcess *process )
@@ -356,25 +367,34 @@ long wxExecute( char **argv, bool sync, wxProcess *process )
         close(end_proc_detect[1]); // close writing side
         data->tag = gdk_input_add(end_proc_detect[0], GDK_INPUT_READ,
                                   GTK_EndProcessDetector, (gpointer)data);
-        data->pid = pid;
-        if (!sync)
-        {
-            data->process = process;
-        }
-        else
+        if ( sync )
         {
-            data->process = process;
-            data->pid = -(data->pid);
+            wxASSERT_MSG( !process, "wxProcess param ignored for sync exec" );
+            data->process = NULL;
+
+            // sync execution: indicate it by negating the pid
+            data->pid = -pid;
 
+            // it will be set to 0 from GTK_EndProcessDetector
             while (data->pid != 0)
                 wxYield();
 
+            int exitcode = data->exitcode;
+
             delete data;
+
+            return exitcode;
         }
+        else
+        {
+            // async execution, nothing special to do - caller will be
+            // notified about the process terminationif process != NULL, data
+            // will be deleted in GTK_EndProcessDetector
+            data->process = process;
+            data->pid = pid;
 
-        // @@@ our return value indicates success even if execvp() in the child
-        //     failed!
-        return pid;
+            return pid;
+        }
     }
 }
 
index 730828e34e51742c902fcc2be44ca806bf6e7cad..e54f9811fee9058733ec96804fabcb3b5b4829f4 100644 (file)
@@ -110,7 +110,7 @@ static DWORD wxExecuteThread(wxExecuteData *data)
 
     // send a message indicating process termination to the window
     SendMessage(data->hWnd, wxWM_PROC_TERMINATED, 0, (LPARAM)data);
-    
+
     return 0;
 }
 #endif
@@ -130,7 +130,7 @@ LRESULT APIENTRY _EXPORT wxExecuteWindowCbk(HWND hWnd, UINT message,
             data->handler->OnTerminate((int)data->dwProcessId,
                                        (int)data->dwExitCode);
         }
-        
+
         if ( data->state )
         {
             // we're executing synchronously, tell the waiting thread
@@ -203,7 +203,7 @@ long wxExecute(const wxString& command, bool sync, wxProcess *handler)
     result = ShellExecute(hwndTop, "open", commandName,
                           commandArgs, NULL, SW_SHOWNORMAL);
 #endif // GNUWIN32
-    
+
     if ( ((long)result) <= 32 )
         wxLogSysError(_("Can't execute command '%s'"), command.c_str());
 
@@ -248,19 +248,29 @@ long wxExecute(const wxString& command, bool sync, wxProcess *handler)
     HWND hwnd = ::CreateWindow(wxPanelClassName, NULL, 0, 0, 0, 0, 0, NULL,
                                (HMENU)NULL, wxGetInstance(), 0);
     wxASSERT_MSG( hwnd, "can't create a hidden window for wxExecute" );
-    
+
     FARPROC ExecuteWindowInstance = MakeProcInstance((FARPROC)wxExecuteWindowCbk,
                                                      wxGetInstance());
-    
+
     ::SetWindowLong(hwnd, GWL_WNDPROC, (LONG) ExecuteWindowInstance);
-    
+
     // Alloc data
     wxExecuteData *data = new wxExecuteData;
     data->hProcess    = pi.hProcess;
     data->dwProcessId = pi.dwProcessId;
     data->hWnd        = hwnd;
     data->state       = sync;
-    data->handler     = handler;
+    if ( sync )
+    {
+        wxASSERT_MSG( !handler, "wxProcess param ignored for sync execution" );
+
+        data->handler = NULL;
+    }
+    else
+    {
+        // may be NULL or not
+        data->handler = handler;
+    }
 
     DWORD tid;
     HANDLE hThread = ::CreateThread(NULL,
@@ -280,25 +290,29 @@ long wxExecute(const wxString& command, bool sync, wxProcess *handler)
         // the process still started up successfully...
         return pi.dwProcessId;
     }
-    
+
     if ( !sync )
     {
         // clean up will be done when the process terminates
+
+        // return the pid
         return pi.dwProcessId;
     }
-    
+
     // waiting until command executed
     while ( data->state )
         wxYield();
-    
+
+    DWORD dwExitCode = data->dwExitCode;
     delete data;
 
-    return pi.dwProcessId;
+    // return the exit code
+    return dwExitCode;
 #endif // 0/1
 #else // Win16
     long instanceID = WinExec((LPCSTR) WXSTRINGCAST command, SW_SHOW);
     if (instanceID < 32) return(0);
-    
+
     if (sync) {
         int running;
         do {
@@ -314,7 +328,7 @@ long wxExecute(const wxString& command, bool sync, wxProcess *handler)
 long wxExecute(char **argv, bool sync, wxProcess *handler)
 {
     wxString command;
-    
+
     while ( *argv != NULL )
     {
         command << *argv++ << ' ';