pass
-def KillProcess(pid, signal_=signal.SIGTERM, timeout=30):
+def KillProcess(pid, signal_=signal.SIGTERM, timeout=30,
+ waitpid=False):
"""Kill a process given by its pid.
@type pid: int
@param timeout: The timeout after which, if the process is still alive,
a SIGKILL will be sent. If not positive, no such checking
will be done
+ @type waitpid: boolean
+ @param waitpid: If true, we should waitpid on this process after
+ sending signals, since it's our own child and otherwise it
+ would remain as zombie
"""
+ def _helper(pid, signal_, wait):
+ """Simple helper to encapsulate the kill/waitpid sequence"""
+ os.kill(pid, signal_)
+ if wait:
+ try:
+ os.waitpid(pid, os.WNOHANG)
+ except OSError:
+ pass
+
if pid <= 0:
# kill with pid=0 == suicide
raise errors.ProgrammerError("Invalid pid given '%s'" % pid)
if not IsProcessAlive(pid):
return
- os.kill(pid, signal_)
+ _helper(pid, signal_, waitpid)
if timeout <= 0:
return
end = time.time() + timeout
while time.time() < end and IsProcessAlive(pid):
time.sleep(0.1)
if IsProcessAlive(pid):
- os.kill(pid, signal.SIGKILL)
+ _helper(pid, signal.SIGKILL, wait)
def FindFile(name, search_path, test=os.path.exists):
read_pid = utils.ReadPidFile(pid_file)
self.failUnlessEqual(read_pid, new_pid)
self.failUnless(utils.IsProcessAlive(new_pid))
- utils.KillProcess(new_pid)
+ utils.KillProcess(new_pid, waitpid=True)
self.failIf(utils.IsProcessAlive(new_pid))
utils.RemovePidFile('child')
self.failUnlessRaises(ProgrammerError, utils.KillProcess, 0)