killdaemons.py
71 lines
| 2.1 KiB
| text/x-python
|
PythonLexer
/ tests / killdaemons.py
|
r7344 | #!/usr/bin/env python | ||
|
r17466 | import os, sys, time, errno, signal | ||
|
r7344 | |||
|
r17465 | if os.name =='nt': | ||
import ctypes | ||||
|
r20493 | |||
def _check(ret, expectederr=None): | ||||
if ret == 0: | ||||
winerrno = ctypes.GetLastError() | ||||
if winerrno == expectederr: | ||||
return True | ||||
raise ctypes.WinError(winerrno) | ||||
|
r17465 | def kill(pid, logfn, tryhard=True): | ||
logfn('# Killing daemon process %d' % pid) | ||||
PROCESS_TERMINATE = 1 | ||||
handle = ctypes.windll.kernel32.OpenProcess( | ||||
PROCESS_TERMINATE, False, pid) | ||||
|
r20493 | if handle == 0: | ||
# TODO: call _check(0, expected) to check if "process not found" | ||||
return # process not found, already finished | ||||
try: | ||||
_check(ctypes.windll.kernel32.TerminateProcess(handle, -1), 5) | ||||
# windows error 5 when process does not exist or no access TODO | ||||
except: #re-raises | ||||
ctypes.windll.kernel32.CloseHandle(handle) # no _check, keep error | ||||
raise | ||||
_check(ctypes.windll.kernel32.CloseHandle(handle)) | ||||
|
r17465 | else: | ||
def kill(pid, logfn, tryhard=True): | ||||
try: | ||||
os.kill(pid, 0) | ||||
logfn('# Killing daemon process %d' % pid) | ||||
os.kill(pid, signal.SIGTERM) | ||||
if tryhard: | ||||
for i in range(10): | ||||
time.sleep(0.05) | ||||
os.kill(pid, 0) | ||||
else: | ||||
time.sleep(0.1) | ||||
os.kill(pid, 0) | ||||
logfn('# Daemon process %d is stuck - really killing it' % pid) | ||||
os.kill(pid, signal.SIGKILL) | ||||
except OSError, err: | ||||
if err.errno != errno.ESRCH: | ||||
raise | ||||
|
r17464 | def killdaemons(pidfile, tryhard=True, remove=False, logfn=None): | ||
if not logfn: | ||||
logfn = lambda s: s | ||||
# Kill off any leftover daemon processes | ||||
try: | ||||
fp = open(pidfile) | ||||
for line in fp: | ||||
try: | ||||
pid = int(line) | ||||
except ValueError: | ||||
continue | ||||
|
r17465 | kill(pid, logfn, tryhard) | ||
|
r17464 | fp.close() | ||
if remove: | ||||
os.unlink(pidfile) | ||||
except IOError: | ||||
pass | ||||
if __name__ == '__main__': | ||||
|
r17466 | path, = sys.argv[1:] | ||
killdaemons(path) | ||||
|
r17464 | |||