+ // 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(_T("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(_T("Failed to uninstall our signal handler."));
+ }
+
+ s_savedHandlers = false;
+ }
+ //else: nothing to do
+
+ return ok;
+}
+
+#endif // wxUSE_ON_FATAL_EXCEPTION
+
+#endif // wxUSE_BASE
+
+#if wxUSE_GUI
+
+// ----------------------------------------------------------------------------
+// wxExecute support
+// ----------------------------------------------------------------------------
+
+// Darwin doesn't use the same process end detection mechanisms so we don't
+// need wxExecute-related helpers for it
+#if !(defined(__DARWIN__) && defined(__WXMAC__))
+
+bool wxGUIAppTraits::CreateEndProcessPipe(wxExecuteData& execData)
+{
+ return execData.pipeEndProcDetect.Create();
+}
+
+bool wxGUIAppTraits::IsWriteFDOfEndProcessPipe(wxExecuteData& execData, int fd)
+{
+ return fd == (execData.pipeEndProcDetect)[wxPipe::Write];
+}
+
+void wxGUIAppTraits::DetachWriteFDOfEndProcessPipe(wxExecuteData& execData)
+{
+ execData.pipeEndProcDetect.Detach(wxPipe::Write);
+ execData.pipeEndProcDetect.Close();
+}
+
+#else // !Darwin
+
+bool wxGUIAppTraits::CreateEndProcessPipe(wxExecuteData& WXUNUSED(execData))
+{
+ return true;
+}
+
+bool
+wxGUIAppTraits::IsWriteFDOfEndProcessPipe(wxExecuteData& WXUNUSED(execData),
+ int WXUNUSED(fd))
+{
+ return false;
+}
+
+void
+wxGUIAppTraits::DetachWriteFDOfEndProcessPipe(wxExecuteData& WXUNUSED(execData))
+{
+ // nothing to do here, we don't use the pipe
+}
+
+#endif // !Darwin/Darwin
+
+int wxGUIAppTraits::WaitForChild(wxExecuteData& execData)
+{
+ wxEndProcessData *endProcData = new wxEndProcessData;
+
+ const int flags = execData.flags;
+
+ // wxAddProcessCallback is now (with DARWIN) allowed to call the
+ // callback function directly if the process terminates before
+ // the callback can be added to the run loop. Set up the endProcData.
+ if ( flags & wxEXEC_SYNC )
+ {
+ // we may have process for capturing the program output, but it's
+ // not used in wxEndProcessData in the case of sync execution
+ endProcData->process = NULL;
+
+ // sync execution: indicate it by negating the pid
+ endProcData->pid = -execData.pid;
+ }
+ else
+ {
+ // async execution, nothing special to do -- caller will be
+ // notified about the process termination if process != NULL, endProcData
+ // will be deleted in GTK_EndProcessDetector
+ endProcData->process = execData.process;
+ endProcData->pid = execData.pid;
+ }
+
+
+#if defined(__DARWIN__) && (defined(__WXMAC__) || defined(__WXCOCOA__))
+ endProcData->tag = wxAddProcessCallbackForPid(endProcData, execData.pid);
+#else
+ endProcData->tag = wxAddProcessCallback
+ (
+ endProcData,
+ execData.pipeEndProcDetect.Detach(wxPipe::Read)
+ );
+
+ execData.pipeEndProcDetect.Close();
+#endif // defined(__DARWIN__) && (defined(__WXMAC__) || defined(__WXCOCOA__))
+
+ if ( flags & wxEXEC_SYNC )
+ {
+ wxBusyCursor bc;
+ wxWindowDisabler *wd = flags & wxEXEC_NODISABLE ? NULL
+ : new wxWindowDisabler;
+
+ // endProcData->pid will be set to 0 from GTK_EndProcessDetector when the
+ // process terminates
+ while ( endProcData->pid != 0 )
+ {
+ bool idle = true;
+
+#if wxUSE_STREAMS
+ if ( execData.bufOut )
+ {
+ execData.bufOut->Update();
+ idle = false;
+ }
+
+ if ( execData.bufErr )
+ {
+ execData.bufErr->Update();
+ idle = false;
+ }
+#endif // wxUSE_STREAMS
+
+ // don't consume 100% of the CPU while we're sitting in this
+ // loop
+ if ( idle )
+ wxMilliSleep(1);
+
+ // give GTK+ a chance to call GTK_EndProcessDetector here and
+ // also repaint the GUI
+ wxYield();
+ }
+
+ int exitcode = endProcData->exitcode;
+
+ delete wd;
+ delete endProcData;
+
+ return exitcode;
+ }
+ else // async execution
+ {
+ return execData.pid;
+ }
+}
+
+#endif // wxUSE_GUI
+#if wxUSE_BASE
+
+void wxHandleProcessTermination(wxEndProcessData *proc_data)
+{
+ // notify user about termination if required
+ if ( proc_data->process )
+ {
+ proc_data->process->OnTerminate(proc_data->pid, proc_data->exitcode);
+ }
+
+ // clean up
+ if ( proc_data->pid > 0 )
+ {
+ delete proc_data;
+ }
+ else
+ {
+ // let wxExecute() know that the process has terminated
+ proc_data->pid = 0;
+ }