]> git.saurik.com Git - wxWidgets.git/blobdiff - src/os2/utilsexc.cpp
Remove workarounds for wxTextCtrl::SetValue() events in pickers code.
[wxWidgets.git] / src / os2 / utilsexc.cpp
index 4c6c00399ea55831871991e54fc1ed06d4c15c60..199781f7cfbdb052d1b40f6becef40b15df8dd57 100644 (file)
@@ -1,35 +1,41 @@
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
-// Name:        utilsexec.cpp
+// Name:        src/os2/utilsexec.cpp
 // Purpose:     Various utilities
 // Author:      David Webster
 // Modified by:
 // Created:     10/17/99
 // RCS-ID:      $Id$
 // Copyright:   (c) David Webster
 // Purpose:     Various utilities
 // Author:      David Webster
 // Modified by:
 // Created:     10/17/99
 // RCS-ID:      $Id$
 // Copyright:   (c) David Webster
-// Licence:     wxWindows license
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 #ifndef WX_PRECOMP
 /////////////////////////////////////////////////////////////////////////////
 
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 #ifndef WX_PRECOMP
-#include "wx/setup.h"
-#include "wx/utils.h"
-#include "wx/app.h"
-#include "wx/intl.h"
+    #include "wx/utils.h"
+    #include "wx/app.h"
+    #include "wx/intl.h"
+    #include "wx/log.h"
 #endif
 
 #endif
 
-#include "wx/log.h"
-
 #include "wx/process.h"
 
 #include "wx/os2/private.h"
 
 #include "wx/process.h"
 
 #include "wx/os2/private.h"
 
-#define INCL_DOS
-#include <os2.h>
+#define PURE_32
+#ifndef __EMX__
+    #include <upm.h>
+    #ifndef __WATCOMC__
+        #include <netcons.h>
+        #include <netbios.h>
+    #endif
+#endif
 
 #include <ctype.h>
 
 #include <ctype.h>
-#include <direct.h>
+#ifdef __EMX__
+#include <dirent.h>
+#endif
 
 #include <sys/stat.h>
 #include <io.h>
 
 #include <sys/stat.h>
 #include <io.h>
 #include <errno.h>
 #include <stdarg.h>
 
 #include <errno.h>
 #include <stdarg.h>
 
+
 // this message is sent when the process we're waiting for terminates
 #define wxWM_PROC_TERMINATED (WM_USER + 10000)
 
 // this message is sent when the process we're waiting for terminates
 #define wxWM_PROC_TERMINATED (WM_USER + 10000)
 
+#ifndef NO_ERROR
+#  define NO_ERROR  0
+#endif
+
 // structure describing the process we're being waiting for
 struct wxExecuteData
 {
 public:
     ~wxExecuteData()
     {
 // structure describing the process we're being waiting for
 struct wxExecuteData
 {
 public:
     ~wxExecuteData()
     {
-// TODO:
-/*
-        if ( !::CloseHandle(hProcess) )
-        {
-            wxLogLastError("CloseHandle(hProcess)");
-        }
-*/
+//         cout << "Closing thread: " << endl;
+        DosExit(EXIT_PROCESS, 0);
     }
 
     }
 
-    HWND       hWnd;          // window to send wxWM_PROC_TERMINATED to
-    HANDLE     hProcess;      // handle of the process
-    DWORD      dwProcessId;   // pid of the process
-    wxProcess *handler;
-    DWORD      dwExitCode;    // the exit code of the process
-    bool       state;         // set to FALSE when the process finishes
+    HWND         hWnd;          // window to send wxWM_PROC_TERMINATED to [not used]
+    RESULTCODES  vResultCodes;
+    wxProcess*   pHandler;
+    ULONG        ulExitCode;    // the exit code of the process
+    bool         bState;        // set to false when the process finishes
 };
 
 };
 
-
-static DWORD wxExecuteThread(wxExecuteData *data)
+static ULONG wxExecuteThread(wxExecuteData* pData)
 {
 {
-// TODO:
-/*
-    WaitForSingleObject(data->hProcess, INFINITE);
-
-    // get the exit code
-    if ( !GetExitCodeProcess(data->hProcess, &data->dwExitCode) )
+    ULONG ulRc;
+    PID   vPidChild;
+
+//     cout << "Executing thread: " << endl;
+
+    ulRc = ::DosWaitChild( DCWA_PROCESSTREE
+                          ,DCWW_NOWAIT
+                          ,&pData->vResultCodes
+                          ,&vPidChild
+                          ,pData->vResultCodes.codeTerminate // process PID to look at
+                         );
+    if (ulRc != NO_ERROR)
     {
     {
-        wxLogLastError("GetExitCodeProcess");
+        wxLogLastError(wxT("DosWaitChild"));
     }
     }
-
-    wxASSERT_MSG( data->dwExitCode != STILL_ACTIVE,
-                  wxT("process should have terminated") );
-
-    // send a message indicating process termination to the window
-    SendMessage(data->hWnd, wxWM_PROC_TERMINATED, 0, (LPARAM)data);
-*/
+    delete pData;
     return 0;
 }
 
 // window procedure of a hidden window which is created just to receive
 // the notification message when a process exits
     return 0;
 }
 
 // window procedure of a hidden window which is created just to receive
 // the notification message when a process exits
-MRESULT APIENTRY wxExecuteWindowCbk(HWND hWnd, UINT message,
-                                    MPARAM wParam, MPARAM lParam)
+MRESULT APIENTRY wxExecuteWindowCbk( HWND   hWnd,
+                                     ULONG  ulMessage,
+                                     MPARAM WXUNUSED(wParam),
+                                     MPARAM lParam)
 {
 {
-    if ( message == wxWM_PROC_TERMINATED )
+    if (ulMessage == wxWM_PROC_TERMINATED)
     {
     {
-//        DestroyWindow(hWnd);    // we don't need it any more
+        wxExecuteData*              pData = (wxExecuteData *)lParam;
 
 
-        wxExecuteData *data = (wxExecuteData *)lParam;
-        if ( data->handler )
+        if (pData->pHandler)
         {
         {
-            data->handler->OnTerminate((int)data->dwProcessId,
-                                       (int)data->dwExitCode);
+            pData->pHandler->OnTerminate( (int)pData->vResultCodes.codeTerminate
+                                         ,(int)pData->vResultCodes.codeResult
+                                        );
         }
 
         }
 
-        if ( data->state )
+        if (pData->bState)
         {
             // we're executing synchronously, tell the waiting thread
             // that the process finished
         {
             // we're executing synchronously, tell the waiting thread
             // that the process finished
-            data->state = 0;
+            pData->bState = 0;
         }
         else
         {
             // asynchronous execution - we should do the clean up
         }
         else
         {
             // asynchronous execution - we should do the clean up
-            delete data;
+            delete pData;
         }
         }
+        ::WinDestroyWindow(hWnd);    // we don't need it any more
     }
     }
-
     return 0;
 }
 
     return 0;
 }
 
-extern wxChar wxPanelClassName[];
-
-long wxExecute(const wxString& command, bool sync, wxProcess *handler)
+long wxExecute( const wxString& rCommand,
+                int flags,
+                wxProcess* pHandler,
+                const wxExecuteEnv *env)
 {
 {
-    wxCHECK_MSG( !!command, 0, wxT("empty command in wxExecute") );
-
-    // the old code is disabled because we really need a process handle
-    // if we want to execute it asynchronously or even just get its
-    // return code and for this we must use CreateProcess() and not
-    // ShellExecute()
+    if (rCommand.empty())
+    {
+//         cout << "empty command in wxExecute." << endl;
+        return 0;
+    }
 
     // create the process
 
     // create the process
-// TODO:
-/*
-    STARTUPINFO si;
-    memset(&si, 0, sizeof(si));
-    si.cb = sizeof(si);
-
-    PROCESS_INFORMATION pi;
-
-    if ( ::CreateProcess(
-                         NULL,       // application name (use only cmd line)
-                         (wxChar *)command.c_str(),  // full command line
-                         NULL,       // security attributes: defaults for both
-                         NULL,       //   the process and its main thread
-                         FALSE,      // don't inherit handles
-                         CREATE_DEFAULT_ERROR_MODE,  // flags
-                         NULL,       // environment (use the same)
-                         NULL,       // current directory (use the same)
-                         &si,        // startup info (unused here)
-                         &pi         // process info
-                        ) == 0 )
+    UCHAR                           vLoadError[CCHMAXPATH] = {0};
+    RESULTCODES                     vResultCodes = {0};
+    ULONG                           ulExecFlag;
+    PSZ                             zArgs = NULL;
+    PSZ                             zEnvs = NULL;
+    APIRET                          rc;
+    TID                             vTID;
+
+    if (flags & wxEXEC_SYNC)
+        ulExecFlag = EXEC_SYNC;
+    else
+        ulExecFlag = EXEC_ASYNCRESULT;
+
+    rc = ::DosExecPgm( (PCHAR)vLoadError
+                      ,sizeof(vLoadError)
+                      ,ulExecFlag
+                      ,zArgs
+                      ,zEnvs
+                      ,&vResultCodes
+                      ,rCommand.c_str()
+                     );
+    if (rc != NO_ERROR)
     {
     {
-        wxLogSysError(_("Execution of command '%s' failed"), command.c_str());
-
+        wxLogSysError(_("Execution of command '%s' failed with error: %ul"), rCommand.c_str(), rc);
         return 0;
     }
         return 0;
     }
-
-    // close unneeded handle
-    if ( !::CloseHandle(pi.hThread) )
-        wxLogLastError("CloseHandle(hThread)");
-
-    // create a hidden window to receive notification about process
-    // termination
-    HWND hwnd = ::CreateWindow(wxPanelClassName, NULL, 0, 0, 0, 0, 0, NULL,
-                               (HMENU)NULL, wxGetInstance(), 0);
-    wxASSERT_MSG( hwnd, wxT("can't create a hidden window for wxExecute") );
-
-    FARPROC ExecuteWindowInstance = MakeProcInstance((FARPROC)wxExecuteWindowCbk,
-                                                     wxGetInstance());
-
-    ::SetWindowLong(hwnd, GWL_WNDPROC, (LONG) ExecuteWindowInstance);
-
+//     cout << "Executing: " << rCommand.c_str() << endl;
     // Alloc data
     // Alloc data
-    wxExecuteData *data = new wxExecuteData;
-    data->hProcess    = pi.hProcess;
-    data->dwProcessId = pi.dwProcessId;
-    data->hWnd        = hwnd;
-    data->state       = sync;
-    if ( sync )
-    {
-        wxASSERT_MSG( !handler, wxT("wxProcess param ignored for sync execution") );
+    wxExecuteData*                  pData = new wxExecuteData;
 
 
-        data->handler = NULL;
+    pData->vResultCodes = vResultCodes;
+    pData->hWnd         = NULLHANDLE;
+    pData->bState       = (flags & wxEXEC_SYNC) != 0;
+    if (flags & wxEXEC_SYNC)
+    {
+        wxASSERT_MSG(!pHandler, wxT("wxProcess param ignored for sync execution"));
+        pData->pHandler = NULL;
     }
     else
     {
         // may be NULL or not
     }
     else
     {
         // may be NULL or not
-        data->handler = handler;
+        pData->pHandler = pHandler;
     }
 
     }
 
-    DWORD tid;
-    HANDLE hThread = ::CreateThread(NULL,
-                                    0,
-                                    (LPTHREAD_START_ROUTINE)wxExecuteThread,
-                                    (void *)data,
-                                    0,
-                                    &tid);
-
-    if ( !hThread )
+    rc = ::DosCreateThread( &vTID
+                           ,(PFNTHREAD)&wxExecuteThread
+                           ,(ULONG)pData
+                           ,CREATE_READY|STACK_SPARSE
+                           ,8192
+                          );
+    if (rc != NO_ERROR)
     {
     {
-        wxLogLastError("CreateThread in wxExecute");
-
-        DestroyWindow(hwnd);
-        delete data;
+        wxLogLastError(wxT("CreateThread in wxExecute"));
+        delete pData;
 
         // the process still started up successfully...
 
         // the process still started up successfully...
-        return pi.dwProcessId;
+        return vResultCodes.codeTerminate;
     }
     }
-
-    if ( !sync )
+    if (!(flags & wxEXEC_SYNC))
     {
     {
-        // clean up will be done when the process terminates
-
         // return the pid
         // return the pid
-        return pi.dwProcessId;
+        // warning: don't exit your app unless you actively
+        // kill and cleanup you child processes
+        // Maybe detach the process here???
+        // If cmd.exe need to pass DETACH to detach the process here
+        return vResultCodes.codeTerminate;
     }
 
     // waiting until command executed
     }
 
     // waiting until command executed
-    while ( data->state )
-        wxYield();
+    ::DosWaitThread(&vTID, DCWW_WAIT);
 
 
-    DWORD dwExitCode = data->dwExitCode;
-    delete data;
+    ULONG ulExitCode = pData->vResultCodes.codeResult;
+    delete pData;
 
     // return the exit code
 
     // return the exit code
-    return dwExitCode;
-*/
-    return 0;
+    return (long)ulExitCode;
 }
 
 }
 
-long wxExecute(char **argv, bool sync, wxProcess *handler)
+long wxExecute(
+  char**                            ppArgv
+, int                               flags
+, wxProcess*                        pHandler
+, const wxExecuteEnv *env
+)
 {
 {
-    wxString command;
+    wxString                        sCommand;
 
 
-    while ( *argv != NULL )
+    while (*ppArgv != NULL)
     {
     {
-        command << *argv++ << ' ';
-    }
+        wxString                    sArg((wxChar*)(*ppArgv++));
 
 
-    command.RemoveLast();
 
 
-    return wxExecute(command, sync, handler);
+        sCommand << sArg.c_str() << ' ';
+    }
+    sCommand.RemoveLast();
+    return wxExecute( sCommand
+                     ,flags
+                     ,pHandler
+                     , env
+                    );
 }
 
 }
 
-bool wxGetFullHostName(wxChar *buf, int maxSize)
+bool wxGetFullHostName( wxChar* zBuf, int nMaxSize)
 {
 {
-    DWORD nSize = maxSize ;
-// TODO:
-/*
-    if ( !::GetComputerName(buf, &nSize) )
-    {
-        wxLogLastError("GetComputerName");
-
-        return FALSE;
-    }
-*/
-    return TRUE;
+    return wxGetHostName( zBuf, nMaxSize );
 }
 }
-