+bool wxSetEnv(const wxString& variable, const wxString& value)
+{
+ return wxDoSetEnv(variable, value.mb_str());
+}
+
+bool wxUnsetEnv(const wxString& variable)
+{
+ return wxDoSetEnv(variable, NULL);
+}
+
+// ----------------------------------------------------------------------------
+// signal handling
+// ----------------------------------------------------------------------------
+
+#if wxUSE_ON_FATAL_EXCEPTION
+
+#include <signal.h>
+
+extern "C" void wxFatalSignalHandler(wxTYPE_SA_HANDLER)
+{
+ if ( wxTheApp )
+ {
+ // give the user a chance to do something special about this
+ wxTheApp->OnFatalException();
+ }
+
+ abort();
+}
+
+bool wxHandleFatalExceptions(bool doit)
+{
+ // old sig handlers
+ static bool s_savedHandlers = false;
+ static struct sigaction s_handlerFPE,
+ s_handlerILL,
+ s_handlerBUS,
+ s_handlerSEGV;
+
+ bool ok = true;
+ if ( doit && !s_savedHandlers )
+ {
+ // install the signal handler
+ struct sigaction act;
+
+ // some systems extend it with non std fields, so zero everything
+ memset(&act, 0, sizeof(act));
+
+ act.sa_handler = wxFatalSignalHandler;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+
+ ok &= sigaction(SIGFPE, &act, &s_handlerFPE) == 0;
+ ok &= sigaction(SIGILL, &act, &s_handlerILL) == 0;
+ ok &= sigaction(SIGBUS, &act, &s_handlerBUS) == 0;
+ ok &= sigaction(SIGSEGV, &act, &s_handlerSEGV) == 0;
+ if ( !ok )
+ {
+ wxLogDebug(wxT("Failed to install our signal handler."));
+ }
+
+ s_savedHandlers = true;
+ }
+ else if ( s_savedHandlers )
+ {
+ // uninstall the signal handler
+ ok &= sigaction(SIGFPE, &s_handlerFPE, NULL) == 0;
+ ok &= sigaction(SIGILL, &s_handlerILL, NULL) == 0;
+ ok &= sigaction(SIGBUS, &s_handlerBUS, NULL) == 0;
+ ok &= sigaction(SIGSEGV, &s_handlerSEGV, NULL) == 0;
+ if ( !ok )
+ {
+ wxLogDebug(wxT("Failed to uninstall our signal handler."));
+ }
+
+ s_savedHandlers = false;
+ }
+ //else: nothing to do
+
+ return ok;
+}
+
+#endif // wxUSE_ON_FATAL_EXCEPTION
+
+// ----------------------------------------------------------------------------
+// wxExecute support
+// ----------------------------------------------------------------------------
+
+int wxAppTraits::WaitForChild(wxExecuteData& execData)
+{
+#if wxUSE_CONSOLE_EVENTLOOP
+ wxConsoleEventLoop loop;
+ return RunLoopUntilChildExit(execData, loop);
+#else // !wxUSE_CONSOLE_EVENTLOOP
+ wxFAIL_MSG( wxS("Can't wait for child process without wxConsoleEventLoop") );
+
+ return -1;
+#endif // wxUSE_CONSOLE_EVENTLOOP/!wxUSE_CONSOLE_EVENTLOOP
+}
+
+// This function is common code for both console and GUI applications and used
+// by wxExecute() to wait for the child exit while dispatching events.
+//
+// Notice that it should not be used for all the other cases, e.g. when we
+// don't need to wait for the child (wxEXEC_ASYNC) or when the events must not
+// dispatched (wxEXEC_NOEVENTS).
+int
+wxAppTraits::RunLoopUntilChildExit(wxExecuteData& execData,
+ wxEventLoopBase& loop)
+{
+ // It is possible that wxExecuteData::OnExit() had already been called
+ // and reset the PID to 0, in which case we don't need to do anything
+ // at all.
+ if ( !execData.pid )
+ return execData.exitcode;
+
+#if wxUSE_STREAMS
+ // Monitor the child streams if necessary.
+ wxScopedPtr<wxEventLoopSourceHandler>
+ stdoutHandler,
+ stderrHandler;
+ if ( execData.IsRedirected() )
+ {
+ stdoutHandler.reset(new wxExecuteEventLoopSourceHandler
+ (
+ execData.fdOut, execData.bufOut
+ ));
+ stderrHandler.reset(new wxExecuteEventLoopSourceHandler
+ (
+ execData.fdErr, execData.bufErr
+ ));
+ }
+#endif // wxUSE_STREAMS
+
+ // Store the event loop in the data associated with the child
+ // process so that it could exit the loop when the child exits.
+ execData.syncEventLoop = &loop;
+
+ // And run it.
+ loop.Run();
+
+ // The exit code will have been set when the child termination was detected.
+ return execData.exitcode;
+}
+