Пример #1
0
def fork_prewarm_process(opts: Options,
                         use_exec: bool = False) -> Optional[PrewarmProcess]:
    stdin_read, stdin_write = safe_pipe()
    stdout_read, stdout_write = safe_pipe()
    death_notify_read, death_notify_write = safe_pipe()
    if use_exec:
        import subprocess
        tp = subprocess.Popen([
            kitty_exe(), '+runpy',
            f'from kitty.prewarm import exec_main; exec_main({stdin_read}, {stdout_write}, {death_notify_write})'
        ],
                              pass_fds=(stdin_read, stdout_write,
                                        death_notify_write))
        child_pid = tp.pid
        tp.returncode = 0  # prevent a warning when the popen object is deleted with the process still running
    else:
        child_pid = os.fork()
    if child_pid:
        # master
        os.close(stdin_read)
        os.close(stdout_write)
        os.close(death_notify_write)
        p = PrewarmProcess(child_pid, stdin_write, stdout_read,
                           death_notify_read)
        if use_exec:
            p.reload_kitty_config()
        return p
    # child
    os.close(stdin_write)
    os.close(stdout_read)
    os.close(death_notify_read)
    set_options(opts)
    exec_main(stdin_read, stdout_write, death_notify_write)
    raise SystemExit(0)
Пример #2
0
def fork(shm_address: str,
         all_non_child_fds: Iterable[int]) -> Tuple[int, int]:
    sz = pos = 0
    with SharedMemory(name=shm_address, unlink_on_exit=True) as shm:
        data = shm.read_data_with_size()
        cmd = json.loads(data)
        sz = cmd.get('stdin_size', 0)
        if sz:
            pos = shm.tell()
            shm.unlink_on_exit = False

    r, w = safe_pipe()
    ready_fd_read, ready_fd_write = safe_pipe()
    try:
        child_pid = os.fork()
    except OSError:
        if sz:
            with SharedMemory(shm_address, unlink_on_exit=True):
                pass
    if child_pid:
        # master process
        os.close(w)
        os.close(ready_fd_read)
        poll = select.poll()
        poll.register(r, select.POLLIN)
        tuple(poll.poll())
        os.close(r)
        return child_pid, ready_fd_write
    # child process
    remove_signal_handlers()
    os.close(r)
    os.close(ready_fd_write)
    for fd in all_non_child_fds:
        os.close(fd)
    os.setsid()
    tty_name = cmd.get('tty_name')
    if tty_name:
        from kitty.fast_data_types import establish_controlling_tty
        sys.__stdout__.flush()
        sys.__stderr__.flush()
        establish_controlling_tty(tty_name, sys.__stdin__.fileno(),
                                  sys.__stdout__.fileno(),
                                  sys.__stderr__.fileno())
    os.close(w)
    if shm.unlink_on_exit:
        child_main(cmd, ready_fd_read)
    else:
        with SharedMemory(shm_address, unlink_on_exit=True) as shm:
            stdin_data = memoryview(shm.mmap)[pos:pos + sz]
            if stdin_data:
                sys.stdin = MemoryViewReadWrapper(stdin_data)
            try:
                child_main(cmd, ready_fd_read)
            finally:
                stdin_data.release()
                sys.stdin = sys.__stdin__
Пример #3
0
 def __init__(
     self,
     sanitize_bracketed_paste='[\x03\x04\x0e\x0f\r\x07\x7f\x8d\x8e\x8f\x90\x9b\x9d\x9e\x9f]'
 ):
     self.wakeup_read_fd, self.wakeup_write_fd = safe_pipe()
     # For some reason on macOS the DefaultSelector fails when tty_fd is
     # open('/dev/tty')
     self.sel = s = selectors.PollSelector()
     s.register(self.wakeup_read_fd, selectors.EVENT_READ)
     self.return_code = 0
     self.read_allowed = True
     self.read_buf = ''
     self.decoder = codecs.getincrementaldecoder('utf-8')('ignore')
     try:
         self.iov_limit = max(os.sysconf('SC_IOV_MAX') - 1, 255)
     except Exception:
         self.iov_limit = 255
     self.parse_input_from_terminal = partial(parse_input_from_terminal,
                                              self._on_text, self._on_dcs,
                                              self._on_csi, self._on_osc,
                                              self._on_pm, self._on_apc)
     self.ebs_pat = re.compile('([\177\r\x03\x04])')
     self.in_bracketed_paste = False
     self.sanitize_bracketed_paste = bool(sanitize_bracketed_paste)
     if self.sanitize_bracketed_paste:
         self.sanitize_ibp_pat = re.compile(sanitize_bracketed_paste)
     self.jobs_queue = Queue()