git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@45325
c3d73ce0-8a6f-49c7-b76d-
6d57e0e08775
- Added wxMutex::LockTimeout() (Aleksandr Napylov)
- Added wxMemoryInputStream(wxInputStream&) ctor (Stas Sergeev)
- Implemented wxMemoryInputStream::CanRead()
- Added wxMutex::LockTimeout() (Aleksandr Napylov)
- Added wxMemoryInputStream(wxInputStream&) ctor (Stas Sergeev)
- Implemented wxMemoryInputStream::CanRead()
+- Added wxEXEC_BLOCK flag (Hank Schultz)
kill this process as well as all of its children (except those which have
started their own session).
kill this process as well as all of its children (except those which have
started their own session).
+The {\tt wxEXEC\_NOEVENTS} flag prevents processing of any events from taking
+place while the child process is running. It should be only used for very
+short-lived processes as otherwise the application windows risk becoming
+unresponsive from the users point of view. As this flag only makes sense with
+{\tt wxEXEC\_SYNC}, {\tt wxEXEC\_BLOCK} equal to the sum of both of these flags
+is provided as a convenience.
+
Finally, you may use the third overloaded version of this function to execute
a process (always synchronously, the contents of \arg{flags} is or'd with
\texttt{wxEXEC\_SYNC}) and capture its output in the array \arg{output}. The
Finally, you may use the third overloaded version of this function to execute
a process (always synchronously, the contents of \arg{flags} is or'd with
\texttt{wxEXEC\_SYNC}) and capture its output in the array \arg{output}. The
// by default synchronous execution disables all program windows to avoid
// that the user interacts with the program while the child process is
// running, you can use this flag to prevent this from happening
// by default synchronous execution disables all program windows to avoid
// that the user interacts with the program while the child process is
// running, you can use this flag to prevent this from happening
+ wxEXEC_NODISABLE = 8,
+
+ // by default, the event loop is run while waiting for synchronous execution
+ // to complete and this flag can be used to simply block the main process
+ // until the child process finishes
+ wxEXEC_NOEVENTS = 16,
+
+ // convenient synonym for flags given system()-like behaviour
+ wxEXEC_BLOCK = wxEXEC_SYNC | wxEXEC_NOEVENTS
};
// Execute another program.
};
// Execute another program.
#include "wx/unix/private.h"
#include <pwd.h>
#include "wx/unix/private.h"
#include <pwd.h>
+#include <sys/wait.h> // waitpid()
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
+ if ( !(flags & wxEXEC_NOEVENTS) )
+ {
#if defined(__DARWIN__) && (defined(__WXMAC__) || defined(__WXCOCOA__))
#if defined(__DARWIN__) && (defined(__WXMAC__) || defined(__WXCOCOA__))
- endProcData->tag = wxAddProcessCallbackForPid(endProcData, execData.pid);
+ endProcData->tag = wxAddProcessCallbackForPid(endProcData, execData.pid);
- endProcData->tag = wxAddProcessCallback
- (
- endProcData,
- execData.pipeEndProcDetect.Detach(wxPipe::Read)
- );
+ endProcData->tag = wxAddProcessCallback
+ (
+ endProcData,
+ execData.pipeEndProcDetect.Detach(wxPipe::Read)
+ );
- execData.pipeEndProcDetect.Close();
+ execData.pipeEndProcDetect.Close();
#endif // defined(__DARWIN__) && (defined(__WXMAC__) || defined(__WXCOCOA__))
#endif // defined(__DARWIN__) && (defined(__WXMAC__) || defined(__WXCOCOA__))
if ( flags & wxEXEC_SYNC )
{
wxBusyCursor bc;
if ( flags & wxEXEC_SYNC )
{
wxBusyCursor bc;
- wxWindowDisabler *wd = flags & wxEXEC_NODISABLE ? NULL
- : new wxWindowDisabler;
+ int exitcode = 0;
+
+ wxWindowDisabler *wd = flags & (wxEXEC_NODISABLE | wxEXEC_NOEVENTS)
+ ? NULL
+ : new wxWindowDisabler;
- // endProcData->pid will be set to 0 from GTK_EndProcessDetector when the
- // process terminates
- while ( endProcData->pid != 0 )
+ if ( flags & wxEXEC_NOEVENTS )
+ // just block waiting for the child to exit
+ int status = 0;
-#if HAS_PIPE_INPUT_STREAM
- if ( execData.bufOut )
+ int result = waitpid(execData.pid, &status, 0);
+
+ if ( result == -1 )
- execData.bufOut->Update();
- idle = false;
+ wxLogLastError(_T("waitpid"));
+ exitcode = -1;
-
- if ( execData.bufErr )
- execData.bufErr->Update();
- idle = false;
+ wxASSERT_MSG( result == execData.pid,
+ _T("unexpected waitpid() return value") );
+
+ if ( WIFEXITED(status) )
+ {
+ exitcode = WEXITSTATUS(status);
+ }
+ else // abnormal termination?
+ {
+ wxASSERT_MSG( WIFSIGNALED(status),
+ _T("unexpected child wait status") );
+ exitcode = -1;
+ }
+ }
+ else // !wxEXEC_NOEVENTS
+ {
+ // endProcData->pid will be set to 0 from GTK_EndProcessDetector when the
+ // process terminates
+ while ( endProcData->pid != 0 )
+ {
+ bool idle = true;
+
+#if HAS_PIPE_INPUT_STREAM
+ if ( execData.bufOut )
+ {
+ execData.bufOut->Update();
+ idle = false;
+ }
+
+ if ( execData.bufErr )
+ {
+ execData.bufErr->Update();
+ idle = false;
+ }
#endif // HAS_PIPE_INPUT_STREAM
#endif // HAS_PIPE_INPUT_STREAM
- // don't consume 100% of the CPU while we're sitting in this
- // loop
- if ( idle )
- wxMilliSleep(1);
+ // 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();
- }
+ // give GTK+ a chance to call GTK_EndProcessDetector here and
+ // also repaint the GUI
+ wxYield();
+ }
- int exitcode = endProcData->exitcode;
+ exitcode = endProcData->exitcode;
+ }
delete wd;
delete endProcData;
delete wd;
delete endProcData;