diff --git a/mercurial/testing/ps_util.py b/mercurial/testing/ps_util.py new file mode 100644 --- /dev/null +++ b/mercurial/testing/ps_util.py @@ -0,0 +1,50 @@ +# This python code can be imported into tests in order to terminate a process +# with signal.SIGKILL on posix, or a roughly equivalent procedure on Windows. +import os +import signal +import subprocess +import sys +import tempfile + +from .. import ( + encoding, + pycompat, +) + +from ..utils import procutil + + +def kill_nt(pid: int, exit_code: int): + fd, pidfile = tempfile.mkstemp( + prefix=b"sigkill-", dir=encoding.environ[b"HGTMP"], text=False + ) + try: + os.write(fd, b'%d\n' % pid) + finally: + os.close(fd) + + env = dict(encoding.environ) + env[b"DAEMON_EXITCODE"] = b"%d" % exit_code + + # Simulate the message written to stderr for this process on non-Windows + # platforms, for test consistency. + print("Killed!", file=sys.stderr) + + subprocess.run( + [ + encoding.environ[b"PYTHON"], + b"%s/killdaemons.py" + % encoding.environ[b'RUNTESTDIR_FORWARD_SLASH'], + pidfile, + ], + env=procutil.tonativeenv(env), + ) + + +def kill(pid: int): + """Kill the process with the given PID with SIGKILL or equivalent.""" + if pycompat.iswindows: + exit_code = 128 + 9 + kill_nt(pid, exit_code) + else: + os.kill(pid, signal.SIGKILL)