[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r22623 - in gnunet: contrib src/include src/util
From: |
gnunet |
Subject: |
[GNUnet-SVN] r22623 - in gnunet: contrib src/include src/util |
Date: |
Thu, 12 Jul 2012 23:06:27 +0200 |
Author: LRN
Date: 2012-07-12 23:06:27 +0200 (Thu, 12 Jul 2012)
New Revision: 22623
Modified:
gnunet/contrib/Makefile.am
gnunet/contrib/gnunet_janitor.py.in
gnunet/src/include/winproc.h
gnunet/src/util/os_priority.c
gnunet/src/util/win.cc
Log:
W32: safer process termination
Modified: gnunet/contrib/Makefile.am
===================================================================
--- gnunet/contrib/Makefile.am 2012-07-12 17:01:29 UTC (rev 22622)
+++ gnunet/contrib/Makefile.am 2012-07-12 21:06:27 UTC (rev 22623)
@@ -13,6 +13,7 @@
endif
noinst_SCRIPTS = \
+ terminate.py \
gnunet_pyexpect.py \
gnunet_janitor.py
@@ -28,6 +29,7 @@
hostlist.cgi \
hostlist.php \
report.sh \
+ terminate.py.in \
gnunet_pyexpect.py.in \
gnunet_janitor.py.in \
gnunet-gns-import.sh
Modified: gnunet/contrib/gnunet_janitor.py.in
===================================================================
--- gnunet/contrib/gnunet_janitor.py.in 2012-07-12 17:01:29 UTC (rev 22622)
+++ gnunet/contrib/gnunet_janitor.py.in 2012-07-12 21:06:27 UTC (rev 22623)
@@ -30,13 +30,11 @@
import shutil
import time
import signal
+import terminate
if os.name == 'nt':
from win32com.client import GetObject
WMI = GetObject('winmgmts:')
- killsignal = signal.SIGTERM # any valid value will result in
TerminateProcess()
-else:
- killsignal = signal.SIGKILL
def get_process_list ():
result = []
@@ -63,7 +61,7 @@
if re.match (r'gnunet-service-arm', p[1]):
print ("killing arm process {0:5} {1}".format (p[0], p[1]))
try:
- os.kill (int (p[0]), killsignal)
+ terminate.safe_terminate_process_by_pid (int (p[0]), 1)
except OSError as e:
print ("failed: {0}".format (e))
pass
@@ -71,7 +69,7 @@
if not re.match (r'gnunet-service-arm', p[1]):
print ("killing non-arm process {0:5} {1}".format (p[0], p[1]))
try:
- os.kill (int (p[0]), killsignal)
+ terminate.safe_terminate_process_by_pid (int (p[0]), 1)
except OSError as e:
print ("failed: {0}".format (e))
pass
Modified: gnunet/src/include/winproc.h
===================================================================
--- gnunet/src/include/winproc.h 2012-07-12 17:01:29 UTC (rev 22622)
+++ gnunet/src/include/winproc.h 2012-07-12 21:06:27 UTC (rev 22623)
@@ -227,6 +227,7 @@
int GNInitWinEnv ();
void GNShutdownWinEnv ();
+ BOOL SafeTerminateProcess (HANDLE hProcess, UINT uExitCode, DWORD dwTimeout);
#ifdef __cplusplus
}
#endif
Modified: gnunet/src/util/os_priority.c
===================================================================
--- gnunet/src/util/os_priority.c 2012-07-12 17:01:29 UTC (rev 22622)
+++ gnunet/src/util/os_priority.c 2012-07-12 21:06:27 UTC (rev 22623)
@@ -461,10 +461,16 @@
if (0 != GetExitCodeProcess (proc->handle, &exitcode))
must_kill = (exitcode == STILL_ACTIVE) ? GNUNET_YES : GNUNET_NO;
if (GNUNET_YES == must_kill)
- if (0 == TerminateProcess (proc->handle, 0))
+ if (0 == SafeTerminateProcess (proc->handle, 0, 0))
{
- SetErrnoFromWinError (GetLastError ());
- return -1;
+ DWORD error_code = GetLastError ();
+ if (error_code != WAIT_TIMEOUT) /* OK, since timeout is 0 */
+ {
+ LOG (GNUNET_ERROR_TYPE_WARNING,
+ "SafeTermiateProcess failed with code %lu\n", error_code);
+ SetErrnoFromWinError (error_code);
+ return -1;
+ }
}
}
return 0;
@@ -1386,7 +1392,7 @@
/* If we can't pass on the socket(s), the child will block forever,
* better put it out of its misery.
*/
- TerminateProcess (gnunet_proc->handle, 0);
+ SafeTerminateProcess (gnunet_proc->handle, 0, 0);
CloseHandle (gnunet_proc->handle);
if (NULL != gnunet_proc->control_pipe)
GNUNET_DISK_file_close (gnunet_proc->control_pipe);
Modified: gnunet/src/util/win.cc
===================================================================
--- gnunet/src/util/win.cc 2012-07-12 17:01:29 UTC (rev 22622)
+++ gnunet/src/util/win.cc 2012-07-12 21:06:27 UTC (rev 22623)
@@ -1261,6 +1261,75 @@
return ret;
}
+/**
+ * Terminate a process by creating a remote thread within it,
+ * which proceeds to call ExitProcess() inside that process.
+ * Safer than TerminateProcess ().
+ *
+ * Code is from From http://private-storm.de/2009/08/11/case-terminateprocess/
+ *
+ * @param hProcess handle of a process to terminate
+ * @param uExitCode exit code to use for ExitProcess()
+ * @param dwTimeout number of ms to wait for the process to terminate
+ * @return TRUE on success, FALSE on failure (check last error for the code)
+ */
+BOOL
+SafeTerminateProcess (HANDLE hProcess, UINT uExitCode, DWORD dwTimeout)
+{
+ DWORD dwTID, dwCode, dwErr = 0;
+ HANDLE hProcessDup = INVALID_HANDLE_VALUE;
+ HANDLE hRT = NULL;
+ HINSTANCE hKernel = GetModuleHandle ("Kernel32");
+ BOOL bSuccess = FALSE;
+
+ BOOL bDup = DuplicateHandle (GetCurrentProcess (), hProcess,
+ GetCurrentProcess (), &hProcessDup, PROCESS_ALL_ACCESS,
+ FALSE, 0);
+
+ /* Detect the special case where the process is
+ * already dead...
+ */
+ if (GetExitCodeProcess (bDup ? hProcessDup : hProcess, &dwCode) &&
+ (STILL_ACTIVE == dwCode))
+ {
+ FARPROC pfnExitProc;
+
+ pfnExitProc = GetProcAddress (hKernel, "ExitProcess");
+
+ hRT = CreateRemoteThread ((bDup) ? hProcessDup : hProcess, NULL, 0,
+ (LPTHREAD_START_ROUTINE) pfnExitProc, (PVOID) uExitCode, 0, &dwTID);
+
+ dwErr = GetLastError ();
+ }
+ else
+ {
+ dwErr = ERROR_PROCESS_ABORTED;
+ }
+
+ if (hRT)
+ {
+ /* Must wait process to terminate to
+ * guarantee that it has exited...
+ */
+ DWORD dwWaitResult = WaitForSingleObject ((bDup) ? hProcessDup : hProcess,
+ dwTimeout);
+ if (dwWaitResult == WAIT_TIMEOUT)
+ dwErr = WAIT_TIMEOUT;
+ else
+ dwErr = GetLastError ();
+
+ CloseHandle (hRT);
+ bSuccess = dwErr == NO_ERROR;
+ }
+
+ if (bDup)
+ CloseHandle (hProcessDup);
+
+ SetLastError (dwErr);
+
+ return bSuccess;
+}
+
} /* extern "C" */
#endif
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r22623 - in gnunet: contrib src/include src/util,
gnunet <=