Added flags argument to wxKill and wxProcess::Kill to allow it to
kill child processes. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@30855 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -23,6 +23,7 @@ All:
|
|||||||
- use wxStream::GetLength() instead of deprecated GetSize()
|
- use wxStream::GetLength() instead of deprecated GetSize()
|
||||||
- wxGetOsDescription() is now more precise (Olly Betts)
|
- wxGetOsDescription() is now more precise (Olly Betts)
|
||||||
- XRC supports system fonts and colours (Ray Gilbert)
|
- XRC supports system fonts and colours (Ray Gilbert)
|
||||||
|
- Added flags argument to wxKill/wxProcess::Kill to kill child processes.
|
||||||
|
|
||||||
All (GUI):
|
All (GUI):
|
||||||
|
|
||||||
|
@@ -577,9 +577,9 @@ happening, i.e. with this flag the child process window will be shown normally.
|
|||||||
|
|
||||||
Under Unix the flag {\tt wxEXEC\_MAKE\_GROUP\_LEADER} may be used to ensure
|
Under Unix the flag {\tt wxEXEC\_MAKE\_GROUP\_LEADER} may be used to ensure
|
||||||
that the new process is a group leader (this will create a new session if
|
that the new process is a group leader (this will create a new session if
|
||||||
needed). Calling \helpref{wxKill}{wxkill} with the argument of -pid where pid
|
needed). Calling \helpref{wxKill}{wxkill} passing wxKILL\_CHILDREN will
|
||||||
is the process ID of the new process will kill this process as well as all of
|
will kill this process as well as all of its children (except those which have
|
||||||
its children (except those which have started their own session).
|
started their own session).
|
||||||
|
|
||||||
Finally, you may use the third overloaded version of this function to execute
|
Finally, you may use the third overloaded version of this function to execute
|
||||||
a process (always synchronously) and capture its output in the array
|
a process (always synchronously) and capture its output in the array
|
||||||
@@ -629,7 +629,7 @@ application. See \helpref{wxCloseEvent}{wxcloseevent} and \helpref{wxApp}{wxapp}
|
|||||||
|
|
||||||
\membersection{::wxKill}\label{wxkill}
|
\membersection{::wxKill}\label{wxkill}
|
||||||
|
|
||||||
\func{int}{wxKill}{\param{long}{ pid}, \param{int}{ sig = wxSIGTERM}, \param{wxKillError }{*rc = NULL}}
|
\func{int}{wxKill}{\param{long}{ pid}, \param{int}{ sig = wxSIGTERM}, \param{wxKillError }{*rc = NULL}, \param{int }{flags = 0}}
|
||||||
|
|
||||||
Equivalent to the Unix kill function: send the given signal {\it sig} to the
|
Equivalent to the Unix kill function: send the given signal {\it sig} to the
|
||||||
process with PID {\it pid}. The valid signal values are
|
process with PID {\it pid}. The valid signal values are
|
||||||
@@ -674,6 +674,12 @@ enum wxKillError
|
|||||||
};
|
};
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
|
||||||
|
The {\it flags} parameter can be wxKILL\_NOCHILDREN (the default),
|
||||||
|
or wxKILL\_CHILDREN, in which case the child processes of this
|
||||||
|
process will be killed too. Note that under Unix, for wxKILL\_CHILDREN
|
||||||
|
to work you should have created the process by passing wxEXEC\_MAKE_GROUP\_LEADER
|
||||||
|
to wxExecute.
|
||||||
|
|
||||||
\wxheading{See also}
|
\wxheading{See also}
|
||||||
|
|
||||||
\helpref{wxProcess::Kill}{wxprocesskill},\rtfsp
|
\helpref{wxProcess::Kill}{wxprocesskill},\rtfsp
|
||||||
|
@@ -155,7 +155,7 @@ Returns {\tt true} if the child process standard output stream is opened.
|
|||||||
|
|
||||||
\membersection{wxProcess::Kill}\label{wxprocesskill}
|
\membersection{wxProcess::Kill}\label{wxprocesskill}
|
||||||
|
|
||||||
\func{static wxKillError}{Kill}{\param{int}{ pid}, \param{wxSignal}{ signal = wxSIGNONE}}
|
\func{static wxKillError}{Kill}{\param{int}{ pid}, \param{wxSignal}{ signal = wxSIGNONE}, \param{int }{flags = wxKILL\_NOCHILDREN}}
|
||||||
|
|
||||||
Send the specified signal to the given process. Possible signal values are:
|
Send the specified signal to the given process. Possible signal values are:
|
||||||
|
|
||||||
@@ -185,6 +185,11 @@ enum wxSignal
|
|||||||
under both Unix and Windows but all the other signals are equivalent to
|
under both Unix and Windows but all the other signals are equivalent to
|
||||||
{\tt wxSIGTERM} under Windows.
|
{\tt wxSIGTERM} under Windows.
|
||||||
|
|
||||||
|
The {\it flags} parameter can be wxKILL\_NOCHILDREN (the default),
|
||||||
|
or wxKILL\_CHILDREN, in which case the child processes of this
|
||||||
|
process will be killed too. Note that under Unix, for wxKILL\_CHILDREN
|
||||||
|
to work you should have created the process passing wxEXEC\_MAKE_GROUP\_LEADER.
|
||||||
|
|
||||||
Returns the element of {\tt wxKillError} enum:
|
Returns the element of {\tt wxKillError} enum:
|
||||||
|
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
|
@@ -43,7 +43,7 @@ class WXDLLIMPEXP_BASE wxProcess : public wxEvtHandler
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// kill the process with the given PID
|
// kill the process with the given PID
|
||||||
static wxKillError Kill(int pid, wxSignal sig = wxSIGTERM);
|
static wxKillError Kill(int pid, wxSignal sig = wxSIGTERM, int flags = wxKILL_NOCHILDREN);
|
||||||
|
|
||||||
// test if the given process exists
|
// test if the given process exists
|
||||||
static bool Exists(int pid);
|
static bool Exists(int pid);
|
||||||
|
@@ -156,7 +156,7 @@ WXDLLIMPEXP_BASE wxString wxDecToHex(int dec);
|
|||||||
// Process management
|
// Process management
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// NB: for backwars compatibility reasons the values of wxEXEC_[A]SYNC *must*
|
// NB: for backwards compatibility reasons the values of wxEXEC_[A]SYNC *must*
|
||||||
// be 0 and 1, don't change!
|
// be 0 and 1, don't change!
|
||||||
|
|
||||||
enum
|
enum
|
||||||
@@ -171,8 +171,8 @@ enum
|
|||||||
// is done by default)
|
// is done by default)
|
||||||
wxEXEC_NOHIDE = 2,
|
wxEXEC_NOHIDE = 2,
|
||||||
|
|
||||||
// under Unix, if the process is the group leader then killing -pid kills
|
// under Unix, if the process is the group leader then passing wxKILL_CHILDREN to wxKill
|
||||||
// all children as well as pid
|
// kills all children as well as pid
|
||||||
wxEXEC_MAKE_GROUP_LEADER = 4
|
wxEXEC_MAKE_GROUP_LEADER = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -228,6 +228,12 @@ enum wxKillError
|
|||||||
wxKILL_ERROR // another, unspecified error
|
wxKILL_ERROR // another, unspecified error
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum wxKillFlags
|
||||||
|
{
|
||||||
|
wxKILL_NOCHILDREN = 0, // don't kill children
|
||||||
|
wxKILL_CHILDREN = 1 // kill children
|
||||||
|
};
|
||||||
|
|
||||||
enum wxShutdownFlags
|
enum wxShutdownFlags
|
||||||
{
|
{
|
||||||
wxSHUTDOWN_POWEROFF, // power off the computer
|
wxSHUTDOWN_POWEROFF, // power off the computer
|
||||||
@@ -243,7 +249,8 @@ WXDLLIMPEXP_BASE bool wxShutdown(wxShutdownFlags wFlags);
|
|||||||
// return detailed error in rc if not NULL
|
// return detailed error in rc if not NULL
|
||||||
WXDLLIMPEXP_BASE int wxKill(long pid,
|
WXDLLIMPEXP_BASE int wxKill(long pid,
|
||||||
wxSignal sig = wxSIGTERM,
|
wxSignal sig = wxSIGTERM,
|
||||||
wxKillError *rc = NULL);
|
wxKillError *rc = NULL,
|
||||||
|
int flags = wxKILL_NOCHILDREN);
|
||||||
|
|
||||||
// Execute a command in an interactive shell window (always synchronously)
|
// Execute a command in an interactive shell window (always synchronously)
|
||||||
// If no command then just the shell
|
// If no command then just the shell
|
||||||
|
@@ -142,10 +142,10 @@ bool wxProcess::IsErrorAvailable() const
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
wxKillError wxProcess::Kill(int pid, wxSignal sig)
|
wxKillError wxProcess::Kill(int pid, wxSignal sig, int flags)
|
||||||
{
|
{
|
||||||
wxKillError rc;
|
wxKillError rc;
|
||||||
(void)wxKill(pid, sig, &rc);
|
(void)wxKill(pid, sig, &rc, flags);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@@ -301,7 +301,7 @@ bool wxGetUserName(wxChar *buf, int maxSize)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxKill(long pid, wxSignal sig , wxKillError *rc )
|
int wxKill(long pid, wxSignal sig , wxKillError *rc, int flags)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -155,7 +155,7 @@ bool wxGetUserName(wxChar *buf, int maxSize)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxKill(long pid, wxSignal sig , wxKillError *rc )
|
int wxKill(long pid, wxSignal sig , wxKillError *rc, int flags)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -94,6 +94,9 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// For wxKillAllChildren
|
||||||
|
#include <tlhelp32.h>
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// constants
|
// constants
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -649,8 +652,13 @@ BOOL CALLBACK wxEnumFindByPidProc(HWND hwnd, LPARAM lParam)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxKill(long pid, wxSignal sig, wxKillError *krc)
|
int wxKillAllChildren(long pid, wxSignal sig, wxKillError *krc);
|
||||||
|
|
||||||
|
int wxKill(long pid, wxSignal sig, wxKillError *krc, int flags)
|
||||||
{
|
{
|
||||||
|
if (flags & wxKILL_CHILDREN)
|
||||||
|
wxKillAllChildren(pid, sig, krc);
|
||||||
|
|
||||||
// get the process handle to operate on
|
// get the process handle to operate on
|
||||||
HANDLE hProcess = ::OpenProcess(SYNCHRONIZE |
|
HANDLE hProcess = ::OpenProcess(SYNCHRONIZE |
|
||||||
PROCESS_TERMINATE |
|
PROCESS_TERMINATE |
|
||||||
@@ -805,6 +813,94 @@ int wxKill(long pid, wxSignal sig, wxKillError *krc)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD,DWORD) ;
|
||||||
|
BOOL (WINAPI *lpfProcess32First)(HANDLE,LPPROCESSENTRY32) ;
|
||||||
|
BOOL (WINAPI *lpfProcess32Next)(HANDLE,LPPROCESSENTRY32) ;
|
||||||
|
|
||||||
|
static void InitToolHelp32()
|
||||||
|
{
|
||||||
|
static bool s_initToolHelpDone = false;
|
||||||
|
|
||||||
|
if (s_initToolHelpDone)
|
||||||
|
return;
|
||||||
|
|
||||||
|
s_initToolHelpDone = true;
|
||||||
|
|
||||||
|
lpfCreateToolhelp32Snapshot = NULL;
|
||||||
|
lpfProcess32First = NULL;
|
||||||
|
lpfProcess32Next = NULL;
|
||||||
|
|
||||||
|
HINSTANCE hInstLib = LoadLibraryA( "Kernel32.DLL" ) ;
|
||||||
|
if( hInstLib == NULL )
|
||||||
|
return ;
|
||||||
|
|
||||||
|
// Get procedure addresses.
|
||||||
|
// We are linking to these functions of Kernel32
|
||||||
|
// explicitly, because otherwise a module using
|
||||||
|
// this code would fail to load under Windows NT,
|
||||||
|
// which does not have the Toolhelp32
|
||||||
|
// functions in the Kernel 32.
|
||||||
|
lpfCreateToolhelp32Snapshot=
|
||||||
|
(HANDLE(WINAPI *)(DWORD,DWORD))
|
||||||
|
GetProcAddress( hInstLib,
|
||||||
|
"CreateToolhelp32Snapshot" ) ;
|
||||||
|
|
||||||
|
lpfProcess32First=
|
||||||
|
(BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
|
||||||
|
GetProcAddress( hInstLib, "Process32First" ) ;
|
||||||
|
|
||||||
|
lpfProcess32Next=
|
||||||
|
(BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
|
||||||
|
GetProcAddress( hInstLib, "Process32Next" ) ;
|
||||||
|
|
||||||
|
FreeLibrary( hInstLib ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// By John Skiff
|
||||||
|
int wxKillAllChildren(long pid, wxSignal sig, wxKillError *krc)
|
||||||
|
{
|
||||||
|
InitToolHelp32();
|
||||||
|
|
||||||
|
if (krc)
|
||||||
|
*krc = wxKILL_OK;
|
||||||
|
|
||||||
|
// If not implemented for this platform (e.g. NT 4.0), silently ignore
|
||||||
|
if (!lpfCreateToolhelp32Snapshot || !lpfProcess32First || !lpfProcess32Next)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Take a snapshot of all processes in the system.
|
||||||
|
HANDLE hProcessSnap = lpfCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||||
|
if (hProcessSnap == INVALID_HANDLE_VALUE) {
|
||||||
|
if (krc)
|
||||||
|
*krc = wxKILL_ERROR;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Fill in the size of the structure before using it.
|
||||||
|
PROCESSENTRY32 pe = {0};
|
||||||
|
pe.dwSize = sizeof(PROCESSENTRY32);
|
||||||
|
|
||||||
|
// Walk the snapshot of the processes, and for each process,
|
||||||
|
// kill it if its parent is pid.
|
||||||
|
if (!lpfProcess32First(hProcessSnap, &pe)) {
|
||||||
|
// Can't get first process.
|
||||||
|
if (krc)
|
||||||
|
*krc = wxKILL_ERROR;
|
||||||
|
CloseHandle (hProcessSnap);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (pe.th32ParentProcessID == (DWORD) pid) {
|
||||||
|
if (wxKill(pe.th32ProcessID, sig, krc))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} while (lpfProcess32Next (hProcessSnap, &pe));
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Execute a program in an Interactive Shell
|
// Execute a program in an Interactive Shell
|
||||||
bool wxShell(const wxString& command)
|
bool wxShell(const wxString& command)
|
||||||
{
|
{
|
||||||
|
@@ -132,6 +132,7 @@ int wxKill(
|
|||||||
long lPid
|
long lPid
|
||||||
, wxSignal eSig
|
, wxSignal eSig
|
||||||
, wxKillError* peError
|
, wxKillError* peError
|
||||||
|
, int flags
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return((int)::DosKillProcess(0, (PID)lPid));
|
return((int)::DosKillProcess(0, (PID)lPid));
|
||||||
|
@@ -126,8 +126,7 @@ bool wxSetEnv(const wxString& var, const wxChar *value)
|
|||||||
// process management
|
// process management
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// structure used to pass parameters from wxKill() to wxEnumFindByPidProc()
|
int wxKill(long pid, wxSignal sig, wxKillError *krc, int flags)
|
||||||
int wxKill(long pid, wxSignal sig, wxKillError *krc)
|
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -200,9 +200,9 @@ void wxMilliSleep(unsigned long milliseconds)
|
|||||||
// process management
|
// process management
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
int wxKill(long pid, wxSignal sig, wxKillError *rc)
|
int wxKill(long pid, wxSignal sig, wxKillError *rc, int flags)
|
||||||
{
|
{
|
||||||
int err = kill((pid_t)pid, (int)sig);
|
int err = kill((pid_t) (flags & wxKILL_CHILDREN) ? -pid : pid, (int)sig);
|
||||||
if ( !err )
|
if ( !err )
|
||||||
*rc = wxKILL_OK;
|
*rc = wxKILL_OK;
|
||||||
else
|
else
|
||||||
|
Reference in New Issue
Block a user