mercurial/testing/ps_util.py
changeset 51992 625cf9621551
child 52350 d4e30c15626d
equal deleted inserted replaced
51991:23cc79e04c28 51992:625cf9621551
       
     1 # This python code can be imported into tests in order to terminate a process
       
     2 # with signal.SIGKILL on posix, or a roughly equivalent procedure on Windows.
       
     3 import os
       
     4 import signal
       
     5 import subprocess
       
     6 import sys
       
     7 import tempfile
       
     8 
       
     9 from .. import (
       
    10     encoding,
       
    11     pycompat,
       
    12 )
       
    13 
       
    14 from ..utils import procutil
       
    15 
       
    16 
       
    17 def kill_nt(pid: int, exit_code: int):
       
    18     fd, pidfile = tempfile.mkstemp(
       
    19         prefix=b"sigkill-", dir=encoding.environ[b"HGTMP"], text=False
       
    20     )
       
    21     try:
       
    22         os.write(fd, b'%d\n' % pid)
       
    23     finally:
       
    24         os.close(fd)
       
    25 
       
    26     env = dict(encoding.environ)
       
    27     env[b"DAEMON_EXITCODE"] = b"%d" % exit_code
       
    28 
       
    29     # Simulate the message written to stderr for this process on non-Windows
       
    30     # platforms, for test consistency.
       
    31     print("Killed!", file=sys.stderr)
       
    32 
       
    33     subprocess.run(
       
    34         [
       
    35             encoding.environ[b"PYTHON"],
       
    36             b"%s/killdaemons.py"
       
    37             % encoding.environ[b'RUNTESTDIR_FORWARD_SLASH'],
       
    38             pidfile,
       
    39         ],
       
    40         env=procutil.tonativeenv(env),
       
    41     )
       
    42 
       
    43 
       
    44 def kill(pid: int):
       
    45     """Kill the process with the given PID with SIGKILL or equivalent."""
       
    46     if pycompat.iswindows:
       
    47         exit_code = 128 + 9
       
    48         kill_nt(pid, exit_code)
       
    49     else:
       
    50         os.kill(pid, signal.SIGKILL)