def fork(self): if self.forked: return self.forked = True master, slave = os.openpty() # Note that master and slave are in blocking mode remove_cloexec(slave) fast_data_types.set_iutf8(master, True) stdin, self.stdin = self.stdin, None if stdin is not None: stdin_read_fd, stdin_write_fd = os.pipe() remove_cloexec(stdin_read_fd) else: stdin_read_fd = stdin_write_fd = -1 env = os.environ.copy() env.update(self.env) env['TERM'] = self.opts.term env['COLORTERM'] = 'truecolor' if os.path.isdir(terminfo_dir): env['TERMINFO'] = terminfo_dir env = tuple('{}={}'.format(k, v) for k, v in env.items()) argv = list(self.argv) exe = argv[0] if is_macos and exe == shell_path: # Some macOS machines need the shell to have argv[0] prefixed by # hyphen, see https://github.com/kovidgoyal/kitty/issues/247 argv[0] = ('-' + exe.split('/')[-1]) pid = fast_data_types.spawn(exe, self.cwd, tuple(argv), env, master, slave, stdin_read_fd, stdin_write_fd) os.close(slave) self.pid = pid self.child_fd = master if stdin is not None: os.close(stdin_read_fd) fast_data_types.thread_write(stdin_write_fd, stdin) return pid
def fork(self): if self.forked: return self.forked = True master, slave = os.openpty( ) # Note that master and slave are in blocking mode remove_cloexec(slave) fast_data_types.set_iutf8(master, True) stdin, self.stdin = self.stdin, None if stdin is not None: stdin_read_fd, stdin_write_fd = os.pipe() remove_cloexec(stdin_read_fd) else: stdin_read_fd = stdin_write_fd = -1 env = os.environ.copy() env.update(self.env) env['TERM'] = self.opts.term env['COLORTERM'] = 'truecolor' if os.path.isdir(terminfo_dir): env['TERMINFO'] = terminfo_dir env = tuple('{}={}'.format(k, v) for k, v in env.items()) pid = fast_data_types.spawn(self.cwd, tuple(self.argv), env, master, slave, stdin_read_fd, stdin_write_fd) os.close(slave) self.pid = pid self.child_fd = master if stdin is not None: os.close(stdin_read_fd) fast_data_types.thread_write(stdin_write_fd, stdin) return pid
def fork(self) -> Optional[int]: if self.forked: return None self.forked = True master, slave = openpty() stdin, self.stdin = self.stdin, None self.is_prewarmed = is_prewarmable(self.argv) if not self.is_prewarmed: ready_read_fd, ready_write_fd = os.pipe() os.set_inheritable(ready_write_fd, False) os.set_inheritable(ready_read_fd, True) if stdin is not None: stdin_read_fd, stdin_write_fd = os.pipe() os.set_inheritable(stdin_write_fd, False) os.set_inheritable(stdin_read_fd, True) else: stdin_read_fd = stdin_write_fd = -1 env = tuple(f'{k}={v}' for k, v in self.final_env().items()) argv = list(self.argv) exe = argv[0] if is_macos and exe == shell_path: # bash will only source ~/.bash_profile if it detects it is a login # shell (see the invocation section of the bash man page), which it # does if argv[0] is prefixed by a hyphen see # https://github.com/kovidgoyal/kitty/issues/247 # it is apparently common to use ~/.bash_profile instead of the # more correct ~/.bashrc on macOS to setup env vars, so if # the default shell is used prefix argv[0] by '-' # # it is arguable whether graphical terminals should start shells # in login mode in general, there are at least a few Linux users # that also make this incorrect assumption, see for example # https://github.com/kovidgoyal/kitty/issues/1870 # xterm, urxvt, konsole and gnome-terminal do not do it in my # testing. argv[0] = (f'-{exe.split("/")[-1]}') self.final_exe = which(exe) or exe self.final_argv0 = argv[0] if self.is_prewarmed: fe = self.final_env() self.prewarmed_child = fast_data_types.get_boss().prewarm( slave, self.argv, self.cwd, fe, stdin) pid = self.prewarmed_child.child_process_pid else: pid = fast_data_types.spawn(self.final_exe, self.cwd, tuple(argv), env, master, slave, stdin_read_fd, stdin_write_fd, ready_read_fd, ready_write_fd, tuple(handled_signals)) os.close(slave) self.pid = pid self.child_fd = master if not self.is_prewarmed: if stdin is not None: os.close(stdin_read_fd) fast_data_types.thread_write(stdin_write_fd, stdin) os.close(ready_read_fd) self.terminal_ready_fd = ready_write_fd if self.child_fd is not None: os.set_blocking(self.child_fd, False) return pid
def fork(self): if self.forked: return self.forked = True master, slave = openpty() stdin, self.stdin = self.stdin, None ready_read_fd, ready_write_fd = os.pipe() remove_cloexec(ready_read_fd) if stdin is not None: if isinstance(stdin, int): stdin_read_fd = stdin stdin_write_fd = -1 remove_cloexec(stdin_read_fd) else: stdin_read_fd, stdin_write_fd = os.pipe() remove_cloexec(stdin_read_fd) else: stdin_read_fd = stdin_write_fd = -1 env = self.final_env env = tuple('{}={}'.format(k, v) for k, v in env.items()) argv = list(self.argv) exe = argv[0] if is_macos and exe == shell_path: # bash will only source ~/.bash_profile if it detects it is a login # shell (see the invocation section of the bash man page), which it # does if argv[0] is prefixed by a hyphen see # https://github.com/kovidgoyal/kitty/issues/247 # it is apparently common to use ~/.bash_profile instead of the # more correct ~/.bashrc on macOS to setup env vars, so if # the default shell is used prefix argv[0] by '-' # # it is arguable whether graphical terminals should start shells # in login mode in general, there are at least a few Linux users # that also make this incorrect assumption, see for example # https://github.com/kovidgoyal/kitty/issues/1870 # xterm, urxvt, konsole and gnome-terminal do not do it in my # testing. argv[0] = ('-' + exe.split('/')[-1]) pid = fast_data_types.spawn(exe, self.cwd, tuple(argv), env, master, slave, stdin_read_fd, stdin_write_fd, ready_read_fd, ready_write_fd) os.close(slave) self.pid = pid self.child_fd = master if stdin is not None and not isinstance(stdin, int): os.close(stdin_read_fd) fast_data_types.thread_write(stdin_write_fd, stdin) os.close(ready_read_fd) self.terminal_ready_fd = ready_write_fd remove_blocking(self.child_fd) return pid
def fork(self): if self.forked: return self.forked = True master, slave = os.openpty( ) # Note that master and slave are in blocking mode remove_cloexec(slave) fast_data_types.set_iutf8(master, True) stdin, self.stdin = self.stdin, None ready_read_fd, ready_write_fd = os.pipe() remove_cloexec(ready_read_fd) if stdin is not None: stdin_read_fd, stdin_write_fd = os.pipe() remove_cloexec(stdin_read_fd) else: stdin_read_fd = stdin_write_fd = -1 env = default_env().copy() env.update(self.env) env['TERM'] = self.opts.term env['COLORTERM'] = 'truecolor' if self.cwd: # needed incase cwd is a symlink, in which case shells # can use it to display the current directory name rather # than the resolved path env['PWD'] = self.cwd if os.path.isdir(terminfo_dir): env['TERMINFO'] = terminfo_dir env = tuple('{}={}'.format(k, v) for k, v in env.items()) argv = list(self.argv) exe = argv[0] if is_macos and exe == shell_path: # Some macOS machines need the shell to have argv[0] prefixed by # hyphen, see https://github.com/kovidgoyal/kitty/issues/247 argv[0] = ('-' + exe.split('/')[-1]) pid = fast_data_types.spawn(exe, self.cwd, tuple(argv), env, master, slave, stdin_read_fd, stdin_write_fd, ready_read_fd, ready_write_fd) os.close(slave) self.pid = pid self.child_fd = master if stdin is not None: os.close(stdin_read_fd) fast_data_types.thread_write(stdin_write_fd, stdin) os.close(ready_read_fd) self.terminal_ready_fd = ready_write_fd fcntl.fcntl(self.child_fd, fcntl.F_SETFL, fcntl.fcntl(self.child_fd, fcntl.F_GETFL) | os.O_NONBLOCK) return pid
def fork(self): if self.forked: return self.forked = True master, slave = os.openpty( ) # Note that master and slave are in blocking mode remove_cloexec(slave) fast_data_types.set_iutf8_fd(master, True) stdin, self.stdin = self.stdin, None ready_read_fd, ready_write_fd = os.pipe() remove_cloexec(ready_read_fd) if stdin is not None: stdin_read_fd, stdin_write_fd = os.pipe() remove_cloexec(stdin_read_fd) else: stdin_read_fd = stdin_write_fd = -1 env = self.final_env env = tuple('{}={}'.format(k, v) for k, v in env.items()) argv = list(self.argv) exe = argv[0] if is_macos and exe == shell_path: # Some macOS machines need the shell to have argv[0] prefixed by # hyphen, see https://github.com/kovidgoyal/kitty/issues/247 argv[0] = ('-' + exe.split('/')[-1]) pid = fast_data_types.spawn(exe, self.cwd, tuple(argv), env, master, slave, stdin_read_fd, stdin_write_fd, ready_read_fd, ready_write_fd) os.close(slave) self.pid = pid self.child_fd = master if stdin is not None: os.close(stdin_read_fd) fast_data_types.thread_write(stdin_write_fd, stdin) os.close(ready_read_fd) self.terminal_ready_fd = ready_write_fd fcntl.fcntl(self.child_fd, fcntl.F_SETFL, fcntl.fcntl(self.child_fd, fcntl.F_GETFL) | os.O_NONBLOCK) return pid