File: ipc.py

package info (click to toggle)
python-hupper 1.5-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 536 kB
  • sloc: python: 2,200; makefile: 149
file content (62 lines) | stat: -rw-r--r-- 1,824 bytes parent folder | download | duplicates (2)
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)