1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
|
import os
from .compat import WIN
if WIN: # pragma: no cover
import msvcrt
from . import winapi
class ProcessGroup(object):
def __init__(self):
self.h_job = winapi.CreateJobObject(None, None)
info = winapi.JOBOBJECT_BASIC_LIMIT_INFORMATION()
info.LimitFlags = winapi.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
extended_info = winapi.JOBOBJECT_EXTENDED_LIMIT_INFORMATION()
extended_info.BasicLimitInformation = info
winapi.SetInformationJobObject(
self.h_job,
winapi.JobObjectExtendedLimitInformation,
extended_info,
)
def add_child(self, pid):
hp = winapi.OpenProcess(winapi.PROCESS_ALL_ACCESS, False, pid)
return winapi.AssignProcessToJobObject(self.h_job, hp)
def send_fd(pipe, fd, pid):
hf = msvcrt.get_osfhandle(fd)
hp = winapi.OpenProcess(winapi.PROCESS_ALL_ACCESS, False, pid)
tp = winapi.DuplicateHandle(
winapi.GetCurrentProcess(), hf, hp,
0, False, winapi.DUPLICATE_SAME_ACCESS,
).Detach() # do not close the handle
pipe.send(tp)
def recv_fd(pipe, mode):
handle = pipe.recv()
flags = 0
if 'w' not in mode and '+' not in mode:
flags |= os.O_RDONLY
if 'b' not in mode:
flags |= os.O_TEXT
if 'a' in mode:
flags |= os.O_APPEND
fd = msvcrt.open_osfhandle(handle, flags)
return os.fdopen(fd, mode)
else:
class ProcessGroup(object):
def add_child(self, pid):
# nothing to do on *nix
pass
def send_fd(pipe, fd, pid):
pipe.send(fd)
def recv_fd(pipe, mode):
fd = pipe.recv()
return os.fdopen(fd, mode)
|