implemented wxExecute() for wxDFB; share the implementation with wxX11

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@50834 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Václav Slavík
2007-12-19 18:52:55 +00:00
parent 93254327a1
commit 46c7e1a120
6 changed files with 102 additions and 69 deletions

View File

@@ -44,6 +44,10 @@
#include "wx/unix/execute.h"
#include "wx/unix/private.h"
#ifdef wxHAS_GENERIC_PROCESS_CALLBACK
#include "wx/private/fdiodispatcher.h"
#endif
#include <pwd.h>
#include <sys/wait.h> // waitpid()
@@ -1436,6 +1440,78 @@ int wxGUIAppTraits::WaitForChild(wxExecuteData& execData)
}
}
#if wxHAS_GENERIC_PROCESS_CALLBACK
struct wxEndProcessFDIOHandler : public wxFDIOHandler
{
wxEndProcessFDIOHandler(wxEndProcessData *data, int fd)
: m_data(data), m_fd(fd)
{}
virtual void OnReadWaiting()
{ wxFAIL_MSG("this isn't supposed to happen"); }
virtual void OnWriteWaiting()
{ wxFAIL_MSG("this isn't supposed to happen"); }
virtual void OnExceptionWaiting()
{
int pid = (m_data->pid > 0) ? m_data->pid : -(m_data->pid);
int status = 0;
// has the process really terminated?
int rc = waitpid(pid, &status, WNOHANG);
if ( rc == 0 )
{
// This can only happen if the child application closes our dummy
// pipe that is used to monitor its lifetime; in that case, our
// best bet is to pretend the process did terminate, because
// otherwise wxExecute() would hang indefinitely
// (OnExceptionWaiting() won't be called again, the descriptor
// is closed now).
wxLogDebug("Child process (PID %i) still alive, even though notification was received that it terminated.", pid);
}
else if ( rc == -1 )
{
// As above, if waitpid() fails, the best we can do is to log the
// error and pretend the child terminated:
wxLogSysError(_("Failed to check child process' status"));
}
// set exit code to -1 if something bad happened
m_data->exitcode = (rc > 0 && WIFEXITED(status))
? WEXITSTATUS(status)
: -1;
wxLogTrace("exec",
"Child process (PID %i) terminated with exit code %i",
pid, m_data->exitcode);
// child exited, end waiting
wxFDIODispatcher::Get()->UnregisterFD(m_fd);
close(m_fd);
m_data->fdioHandler = NULL;
wxHandleProcessTermination(m_data);
delete this;
}
wxEndProcessData *m_data;
int m_fd;
};
int wxAddProcessCallback(wxEndProcessData *proc_data, int fd)
{
proc_data->fdioHandler = new wxEndProcessFDIOHandler(proc_data, fd);
wxFDIODispatcher::Get()->RegisterFD
(
fd,
proc_data->fdioHandler,
wxFDIO_EXCEPTION
);
return fd; // unused, but return something unique for the tag
}
#endif // wxHAS_GENERIC_PROCESS_CALLBACK
#endif // wxUSE_GUI
#if wxUSE_BASE