]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/utilsexc.cpp
adding implementation for osx
[wxWidgets.git] / src / msw / utilsexc.cpp
index f5e70e2d915327cdd788853911e31d92eca73321..6fc63c0ee1f7b22dca338f66e11afc58cf7a8601 100644 (file)
@@ -146,7 +146,7 @@ public:
             // running processes
             if ( !::SetEvent(gs_heventShutdown) )
             {
             // running processes
             if ( !::SetEvent(gs_heventShutdown) )
             {
-                wxLogDebug(_T("Failed to set shutdown event in wxExecuteModule"));
+                wxLogDebug(wxT("Failed to set shutdown event in wxExecuteModule"));
             }
 
             ::CloseHandle(gs_heventShutdown);
             }
 
             ::CloseHandle(gs_heventShutdown);
@@ -165,7 +165,7 @@ public:
                         3000    // long but finite value
                        ) == WAIT_TIMEOUT )
                 {
                         3000    // long but finite value
                        ) == WAIT_TIMEOUT )
                 {
-                    wxLogDebug(_T("Failed to stop all wxExecute monitor threads"));
+                    wxLogDebug(wxT("Failed to stop all wxExecute monitor threads"));
                 }
 
                 for ( size_t n = 0; n < numThreads; n++ )
                 }
 
                 for ( size_t n = 0; n < numThreads; n++ )
@@ -181,7 +181,7 @@ public:
         {
             if ( !::UnregisterClass(wxMSWEXEC_WNDCLASSNAME, wxGetInstance()) )
             {
         {
             if ( !::UnregisterClass(wxMSWEXEC_WNDCLASSNAME, wxGetInstance()) )
             {
-                wxLogLastError(_T("UnregisterClass(wxExecClass)"));
+                wxLogLastError(wxT("UnregisterClass(wxExecClass)"));
             }
 
             gs_classForHiddenWindow = NULL;
             }
 
             gs_classForHiddenWindow = NULL;
@@ -336,7 +336,7 @@ static DWORD __stdcall wxExecuteThread(void *arg)
         gs_heventShutdown = ::CreateEvent(NULL, TRUE, FALSE, NULL);
         if ( !gs_heventShutdown )
         {
         gs_heventShutdown = ::CreateEvent(NULL, TRUE, FALSE, NULL);
         if ( !gs_heventShutdown )
         {
-            wxLogDebug(_T("CreateEvent() in wxExecuteThread failed"));
+            wxLogDebug(wxT("CreateEvent() in wxExecuteThread failed"));
         }
     }
 
         }
     }
 
@@ -369,7 +369,7 @@ static DWORD __stdcall wxExecuteThread(void *arg)
             break;
 
         default:
             break;
 
         default:
-            wxLogDebug(_T("Waiting for the process termination failed!"));
+            wxLogDebug(wxT("Waiting for the process termination failed!"));
     }
 
     return 0;
     }
 
     return 0;
@@ -465,7 +465,7 @@ bool wxPipeInputStream::CanRead() const
         if ( ::GetLastError() != ERROR_BROKEN_PIPE )
         {
             // unexpected error
         if ( ::GetLastError() != ERROR_BROKEN_PIPE )
         {
             // unexpected error
-            wxLogLastError(_T("PeekNamedPipe"));
+            wxLogLastError(wxT("PeekNamedPipe"));
         }
 
         // don't try to continue reading from a pipe if an error occurred or if
         }
 
         // don't try to continue reading from a pipe if an error occurred or if
@@ -522,7 +522,7 @@ wxPipeOutputStream::wxPipeOutputStream(HANDLE hOutput)
                 NULL        // timeout (we don't set it neither)
             ) )
     {
                 NULL        // timeout (we don't set it neither)
             ) )
     {
-        wxLogLastError(_T("SetNamedPipeHandleState(PIPE_NOWAIT)"));
+        wxLogLastError(wxT("SetNamedPipeHandleState(PIPE_NOWAIT)"));
     }
 }
 
     }
 }
 
@@ -610,7 +610,8 @@ wxExecuteDDE(const wxString& ddeServer,
 
 #endif // wxUSE_IPC
 
 
 #endif // wxUSE_IPC
 
-long wxExecute(const wxString& cmd, int flags, wxProcess *handler)
+long wxExecute(const wxString& cmd, int flags, wxProcess *handler,
+               const wxExecuteEnv *env)
 {
     wxCHECK_MSG( !cmd.empty(), 0, wxT("empty command in wxExecute") );
 
 {
     wxCHECK_MSG( !cmd.empty(), 0, wxT("empty command in wxExecute") );
 
@@ -619,7 +620,7 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler)
     // thread -- this could be fixed, but as Unix versions don't support this
     // neither I don't want to waste time on this now
     wxASSERT_MSG( wxThread::IsMain(),
     // thread -- this could be fixed, but as Unix versions don't support this
     // neither I don't want to waste time on this now
     wxASSERT_MSG( wxThread::IsMain(),
-                    _T("wxExecute() can be called only from the main thread") );
+                    wxT("wxExecute() can be called only from the main thread") );
 #endif // wxUSE_THREADS
 
     wxString command;
 #endif // wxUSE_THREADS
 
     wxString command;
@@ -635,7 +636,7 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler)
     // case we execute just <command> and process the rest below
     wxString ddeServer, ddeTopic, ddeCommand;
     static const size_t lenDdePrefix = 7;   // strlen("WX_DDE:")
     // case we execute just <command> and process the rest below
     wxString ddeServer, ddeTopic, ddeCommand;
     static const size_t lenDdePrefix = 7;   // strlen("WX_DDE:")
-    if ( cmd.Left(lenDdePrefix) == _T("WX_DDE#") )
+    if ( cmd.Left(lenDdePrefix) == wxT("WX_DDE#") )
     {
         // speed up the concatenations below
         ddeServer.reserve(256);
     {
         // speed up the concatenations below
         ddeServer.reserve(256);
@@ -643,7 +644,7 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler)
         ddeCommand.reserve(256);
 
         const wxChar *p = cmd.c_str() + 7;
         ddeCommand.reserve(256);
 
         const wxChar *p = cmd.c_str() + 7;
-        while ( *p && *p != _T('#') )
+        while ( *p && *p != wxT('#') )
         {
             command += *p++;
         }
         {
             command += *p++;
         }
@@ -655,10 +656,10 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler)
         }
         else
         {
         }
         else
         {
-            wxFAIL_MSG(_T("invalid WX_DDE command in wxExecute"));
+            wxFAIL_MSG(wxT("invalid WX_DDE command in wxExecute"));
         }
 
         }
 
-        while ( *p && *p != _T('#') )
+        while ( *p && *p != wxT('#') )
         {
             ddeServer += *p++;
         }
         {
             ddeServer += *p++;
         }
@@ -670,10 +671,10 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler)
         }
         else
         {
         }
         else
         {
-            wxFAIL_MSG(_T("invalid WX_DDE command in wxExecute"));
+            wxFAIL_MSG(wxT("invalid WX_DDE command in wxExecute"));
         }
 
         }
 
-        while ( *p && *p != _T('#') )
+        while ( *p && *p != wxT('#') )
         {
             ddeTopic += *p++;
         }
         {
             ddeTopic += *p++;
         }
@@ -685,7 +686,7 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler)
         }
         else
         {
         }
         else
         {
-            wxFAIL_MSG(_T("invalid WX_DDE command in wxExecute"));
+            wxFAIL_MSG(wxT("invalid WX_DDE command in wxExecute"));
         }
 
         while ( *p )
         }
 
         while ( *p )
@@ -782,7 +783,7 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler)
                     DUPLICATE_SAME_ACCESS   // same access as for src handle
                 ) )
         {
                     DUPLICATE_SAME_ACCESS   // same access as for src handle
                 ) )
         {
-            wxLogLastError(_T("DuplicateHandle"));
+            wxLogLastError(wxT("DuplicateHandle"));
         }
 
         ::CloseHandle(pipeInWrite);
         }
 
         ::CloseHandle(pipeInWrite);
@@ -800,6 +801,55 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler)
     wxString arguments = command.AfterFirst(wxT(' '));
 #endif
 
     wxString arguments = command.AfterFirst(wxT(' '));
 #endif
 
+    wxWxCharBuffer envBuffer;
+    bool useCwd = false;
+    if ( env )
+    {
+        useCwd = !env->cwd.empty();
+
+        // Translate environment variable map into NUL-terminated list of
+        // NUL-terminated strings.
+        if ( !env->env.empty() )
+        {
+#if wxUSE_UNICODE
+            // Environment variables can contain non-ASCII characters. We could
+            // check for it and not use this flag if everything is really ASCII
+            // only but there doesn't seem to be any reason to do it so just
+            // assume Unicode by default.
+            dwFlags |= CREATE_UNICODE_ENVIRONMENT;
+#endif // wxUSE_UNICODE
+
+            wxEnvVariableHashMap::const_iterator it;
+
+            size_t envSz = 1; // ending '\0'
+            for ( it = env->env.begin(); it != env->env.end(); ++it )
+            {
+                // Add size of env variable name and value, and '=' char and
+                // ending '\0'
+                envSz += it->first.length() + it->second.length() + 2;
+            }
+
+            envBuffer.extend(envSz);
+
+            wxChar *p = envBuffer.data();
+            for ( it = env->env.begin(); it != env->env.end(); ++it )
+            {
+                const wxString line = it->first + wxS("=") + it->second;
+
+                // Include the trailing NUL which will always terminate the
+                // buffer returned by t_str().
+                const size_t len = line.length() + 1;
+
+                wxTmemcpy(p, line.t_str(), len);
+
+                p += len;
+            }
+
+            // And another NUL to terminate the list of NUL-terminated strings.
+            *p = 0;
+        }
+    }
+
     bool ok = ::CreateProcess
                 (
                     // WinCE requires appname to be non null
     bool ok = ::CreateProcess
                 (
                     // WinCE requires appname to be non null
@@ -818,8 +868,10 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler)
                  NULL,               //   the process and its main thread
                  redirect,           // inherit handles if we use pipes
                  dwFlags,            // process creation flags
                  NULL,               //   the process and its main thread
                  redirect,           // inherit handles if we use pipes
                  dwFlags,            // process creation flags
-                 NULL,               // environment (use the same)
-                 NULL,               // current directory (use the same)
+                 envBuffer.data(),   // environment (may be NULL which is fine)
+                 useCwd              // initial working directory
+                    ? const_cast<wxChar *>(env->cwd.wx_str())
+                    : NULL,          //     (or use the same)
                  &si,                // startup info (unused here)
                  &pi                 // process info
                 ) != 0;
                  &si,                // startup info (unused here)
                  &pi                 // process info
                 ) != 0;
@@ -955,14 +1007,14 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler)
         switch ( ::WaitForInputIdle(pi.hProcess, 10000 /* 10 seconds */) )
         {
             default:
         switch ( ::WaitForInputIdle(pi.hProcess, 10000 /* 10 seconds */) )
         {
             default:
-                wxFAIL_MSG( _T("unexpected WaitForInputIdle() return code") );
+                wxFAIL_MSG( wxT("unexpected WaitForInputIdle() return code") );
                 // fall through
 
             case -1:
                 // fall through
 
             case -1:
-                wxLogLastError(_T("WaitForInputIdle() in wxExecute"));
+                wxLogLastError(wxT("WaitForInputIdle() in wxExecute"));
 
             case WAIT_TIMEOUT:
 
             case WAIT_TIMEOUT:
-                wxLogDebug(_T("Timeout too small in WaitForInputIdle"));
+                wxLogDebug(wxT("Timeout too small in WaitForInputIdle"));
 
                 ok = false;
                 break;
 
                 ok = false;
                 break;
@@ -974,7 +1026,7 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler)
 
         if ( !ok )
         {
 
         if ( !ok )
         {
-            wxLogDebug(_T("Failed to send DDE request to the process \"%s\"."),
+            wxLogDebug(wxT("Failed to send DDE request to the process \"%s\"."),
                        cmd.c_str());
         }
     }
                        cmd.c_str());
         }
     }
@@ -989,7 +1041,7 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler)
     }
 
     wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
     }
 
     wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
-    wxCHECK_MSG( traits, -1, _T("no wxAppTraits in wxExecute()?") );
+    wxCHECK_MSG( traits, -1, wxT("no wxAppTraits in wxExecute()?") );
 
     void *cookie = NULL;
     if ( !(flags & wxEXEC_NODISABLE) )
 
     void *cookie = NULL;
     if ( !(flags & wxEXEC_NODISABLE) )
@@ -1039,7 +1091,8 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler)
 }
 
 template <typename CharType>
 }
 
 template <typename CharType>
-long wxExecuteImpl(CharType **argv, int flags, wxProcess *handler)
+long wxExecuteImpl(CharType **argv, int flags, wxProcess *handler,
+                   const wxExecuteEnv *env)
 {
     wxString command;
     command.reserve(1024);
 {
     wxString command;
     command.reserve(1024);
@@ -1078,19 +1131,21 @@ long wxExecuteImpl(CharType **argv, int flags, wxProcess *handler)
         command += ' ';
     }
 
         command += ' ';
     }
 
-    return wxExecute(command, flags, handler);
+    return wxExecute(command, flags, handler, env);
 }
 
 }
 
-long wxExecute(char **argv, int flags, wxProcess *handler)
+long wxExecute(char **argv, int flags, wxProcess *handler,
+               const wxExecuteEnv *env)
 {
 {
-    return wxExecuteImpl(argv, flags, handler);
+    return wxExecuteImpl(argv, flags, handler, env);
 }
 
 #if wxUSE_UNICODE
 
 }
 
 #if wxUSE_UNICODE
 
-long wxExecute(wchar_t **argv, int flags, wxProcess *handler)
+long wxExecute(wchar_t **argv, int flags, wxProcess *handler,
+               const wxExecuteEnv *env)
 {
 {
-    return wxExecuteImpl(argv, flags, handler);
+    return wxExecuteImpl(argv, flags, handler, env);
 }
 
 #endif // wxUSE_UNICODE
 }
 
 #endif // wxUSE_UNICODE