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()
|
||||
- wxGetOsDescription() is now more precise (Olly Betts)
|
||||
- XRC supports system fonts and colours (Ray Gilbert)
|
||||
- Added flags argument to wxKill/wxProcess::Kill to kill child processes.
|
||||
|
||||
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
|
||||
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
|
||||
is the process ID of the new process will kill this process as well as all of
|
||||
its children (except those which have started their own session).
|
||||
needed). Calling \helpref{wxKill}{wxkill} passing wxKILL\_CHILDREN will
|
||||
will kill this process as well as all of its children (except those which have
|
||||
started their own session).
|
||||
|
||||
Finally, you may use the third overloaded version of this function to execute
|
||||
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}
|
||||
|
||||
\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
|
||||
process with PID {\it pid}. The valid signal values are
|
||||
@@ -674,6 +674,12 @@ enum wxKillError
|
||||
};
|
||||
\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}
|
||||
|
||||
\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}
|
||||
|
||||
\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:
|
||||
|
||||
@@ -185,6 +185,11 @@ enum wxSignal
|
||||
under both Unix and Windows but all the other signals are equivalent to
|
||||
{\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:
|
||||
|
||||
\begin{verbatim}
|
||||
|
@@ -43,7 +43,7 @@ class WXDLLIMPEXP_BASE wxProcess : public wxEvtHandler
|
||||
{
|
||||
public:
|
||||
// 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
|
||||
static bool Exists(int pid);
|
||||
|
@@ -156,7 +156,7 @@ WXDLLIMPEXP_BASE wxString wxDecToHex(int dec);
|
||||
// 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!
|
||||
|
||||
enum
|
||||
@@ -171,8 +171,8 @@ enum
|
||||
// is done by default)
|
||||
wxEXEC_NOHIDE = 2,
|
||||
|
||||
// under Unix, if the process is the group leader then killing -pid kills
|
||||
// all children as well as pid
|
||||
// under Unix, if the process is the group leader then passing wxKILL_CHILDREN to wxKill
|
||||
// kills all children as well as pid
|
||||
wxEXEC_MAKE_GROUP_LEADER = 4
|
||||
};
|
||||
|
||||
@@ -228,6 +228,12 @@ enum wxKillError
|
||||
wxKILL_ERROR // another, unspecified error
|
||||
};
|
||||
|
||||
enum wxKillFlags
|
||||
{
|
||||
wxKILL_NOCHILDREN = 0, // don't kill children
|
||||
wxKILL_CHILDREN = 1 // kill children
|
||||
};
|
||||
|
||||
enum wxShutdownFlags
|
||||
{
|
||||
wxSHUTDOWN_POWEROFF, // power off the computer
|
||||
@@ -243,7 +249,8 @@ WXDLLIMPEXP_BASE bool wxShutdown(wxShutdownFlags wFlags);
|
||||
// return detailed error in rc if not NULL
|
||||
WXDLLIMPEXP_BASE int wxKill(long pid,
|
||||
wxSignal sig = wxSIGTERM,
|
||||
wxKillError *rc = NULL);
|
||||
wxKillError *rc = NULL,
|
||||
int flags = wxKILL_NOCHILDREN);
|
||||
|
||||
// Execute a command in an interactive shell window (always synchronously)
|
||||
// If no command then just the shell
|
||||
|
@@ -142,10 +142,10 @@ bool wxProcess::IsErrorAvailable() const
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/* static */
|
||||
wxKillError wxProcess::Kill(int pid, wxSignal sig)
|
||||
wxKillError wxProcess::Kill(int pid, wxSignal sig, int flags)
|
||||
{
|
||||
wxKillError rc;
|
||||
(void)wxKill(pid, sig, &rc);
|
||||
(void)wxKill(pid, sig, &rc, flags);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@@ -301,7 +301,7 @@ bool wxGetUserName(wxChar *buf, int maxSize)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int wxKill(long pid, wxSignal sig , wxKillError *rc )
|
||||
int wxKill(long pid, wxSignal sig , wxKillError *rc, int flags)
|
||||
{
|
||||
// TODO
|
||||
return 0;
|
||||
|
@@ -155,7 +155,7 @@ bool wxGetUserName(wxChar *buf, int maxSize)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int wxKill(long pid, wxSignal sig , wxKillError *rc )
|
||||
int wxKill(long pid, wxSignal sig , wxKillError *rc, int flags)
|
||||
{
|
||||
// TODO
|
||||
return 0;
|
||||
|
@@ -94,6 +94,9 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// For wxKillAllChildren
|
||||
#include <tlhelp32.h>
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// constants
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -649,8 +652,13 @@ BOOL CALLBACK wxEnumFindByPidProc(HWND hwnd, LPARAM lParam)
|
||||
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
|
||||
HANDLE hProcess = ::OpenProcess(SYNCHRONIZE |
|
||||
PROCESS_TERMINATE |
|
||||
@@ -805,6 +813,94 @@ int wxKill(long pid, wxSignal sig, wxKillError *krc)
|
||||
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
|
||||
bool wxShell(const wxString& command)
|
||||
{
|
||||
|
@@ -132,6 +132,7 @@ int wxKill(
|
||||
long lPid
|
||||
, wxSignal eSig
|
||||
, wxKillError* peError
|
||||
, int flags
|
||||
)
|
||||
{
|
||||
return((int)::DosKillProcess(0, (PID)lPid));
|
||||
|
@@ -126,8 +126,7 @@ bool wxSetEnv(const wxString& var, const wxChar *value)
|
||||
// process management
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// structure used to pass parameters from wxKill() to wxEnumFindByPidProc()
|
||||
int wxKill(long pid, wxSignal sig, wxKillError *krc)
|
||||
int wxKill(long pid, wxSignal sig, wxKillError *krc, int flags)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@@ -200,9 +200,9 @@ void wxMilliSleep(unsigned long milliseconds)
|
||||
// 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 )
|
||||
*rc = wxKILL_OK;
|
||||
else
|
||||
|
Reference in New Issue
Block a user