diff --git a/kitty/child.c b/kitty/child.c index 46fc20455..23d1f4f85 100644 --- a/kitty/child.c +++ b/kitty/child.c @@ -183,18 +183,17 @@ spawn(PyObject *self UNUSED, PyObject *args) { static PyObject* establish_controlling_tty(PyObject *self UNUSED, PyObject *args) { - int tty_fd=-1, stdin_fd = -1, stdout_fd = -1, stderr_fd = -1; + int stdin_fd = -1, stdout_fd = -1, stderr_fd = -1; const char *tty_name; - if (!PyArg_ParseTuple(args, "s|iiii", &tty_name, &tty_fd, &stdin_fd, &stdout_fd, &stderr_fd)) return NULL; + if (!PyArg_ParseTuple(args, "s|iii", &tty_name, &stdin_fd, &stdout_fd, &stderr_fd)) return NULL; int tfd = safe_open(tty_name, O_RDWR, 0); -#define cleanup() if (tfd >= 0) safe_close(tfd, __FILE__, __LINE__); if (tty_fd >= 0) safe_close(tty_fd, __FILE__, __LINE__); +#define cleanup() if (tfd >= 0) safe_close(tfd, __FILE__, __LINE__); #define fail() { cleanup(); return PyErr_SetFromErrno(PyExc_OSError); } if (tfd < 0) { cleanup(); return PyErr_SetFromErrnoWithFilename(PyExc_OSError, tty_name); } - if (tty_fd < 0) { tty_fd = tfd; tfd = -1; } - if (ioctl(tty_fd, TIOCSCTTY, 0) == -1) fail(); - if (stdin_fd > -1 && safe_dup2(tty_fd, stdin_fd) == -1) fail(); - if (stdout_fd > -1 && safe_dup2(tty_fd, stdout_fd) == -1) fail(); - if (stderr_fd > -1 && safe_dup2(tty_fd, stderr_fd) == -1) fail(); + if (ioctl(tfd, TIOCSCTTY, 0) == -1) fail(); + if (stdin_fd > -1 && safe_dup2(tfd, stdin_fd) == -1) fail(); + if (stdout_fd > -1 && safe_dup2(tfd, stdout_fd) == -1) fail(); + if (stderr_fd > -1 && safe_dup2(tfd, stderr_fd) == -1) fail(); cleanup(); #undef cleanup #undef fail diff --git a/kitty/fast_data_types.pyi b/kitty/fast_data_types.pyi index 71e94f15a..b0570b433 100644 --- a/kitty/fast_data_types.pyi +++ b/kitty/fast_data_types.pyi @@ -1395,7 +1395,7 @@ def sigqueue(pid: int, signal: int, value: int) -> None: pass -def establish_controlling_tty(tty_name: str, tty_fd: int = -1, stdin: int = -1, stdout: int = -1, stderr: int = -1) -> None: +def establish_controlling_tty(tty_name: str, stdin: int = -1, stdout: int = -1, stderr: int = -1) -> None: pass diff --git a/kitty/prewarm.py b/kitty/prewarm.py index 93e457faa..b37232090 100644 --- a/kitty/prewarm.py +++ b/kitty/prewarm.py @@ -351,7 +351,7 @@ def fork(shm_address: str, free_non_child_resources: Callable[[], None]) -> Tupl if tty_name: sys.__stdout__.flush() sys.__stderr__.flush() - establish_controlling_tty(tty_name, -1, sys.__stdin__.fileno(), sys.__stdout__.fileno(), sys.__stderr__.fileno()) + 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) @@ -389,10 +389,10 @@ class SocketChild: self.input_buf = self.output_buf = b'' self.fds: List[int] = [] self.child_id = -1 - self.cwd = '' + self.cwd = self.tty_name = '' self.env: Dict[str, str] = {} self.argv: List[str] = [] - self.stdin = self.stdout = self.stderr = self.tty_fd = -1 + self.stdin = self.stdout = self.stderr = -1 self.pid = -1 self.closed = False @@ -431,7 +431,6 @@ class SocketChild: for x in self.fds: os.set_inheritable(x, x is not self.fds[0]) os.set_blocking(x, True) - self.tty_fd = self.fds[0] if self.stdin > -1: self.stdin = self.fds[self.stdin] if self.stdout > -1: @@ -453,6 +452,8 @@ class SocketChild: self.stdout = int(payload) elif cmd == 'stderr': self.stderr = int(payload) + elif cmd == 'tty_name': + self.tty_name = payload return False @@ -463,9 +464,6 @@ class SocketChild: if self.pid > 0: # master process os.close(w) - if self.tty_fd > -1: - os.close(self.tty_fd) - self.tty_fd = -1 if self.stdin > -1: os.close(self.stdin) self.stdin = -1 @@ -486,15 +484,14 @@ class SocketChild: os.close(r) os.setsid() restore_python_signal_handlers() - if self.tty_fd > -1: + if self.tty_name: sys.__stdout__.flush() sys.__stderr__.flush() establish_controlling_tty( - os.ttyname(self.tty_fd), self.tty_fd, + self.tty_name, sys.__stdin__.fileno() if self.stdin < 0 else -1, sys.__stdout__.fileno() if self.stdout < 0 else -1, sys.__stderr__.fileno() if self.stderr < 0 else -1) - self.tty_fd = -1 # the std streams fds are closed in free_non_child_resources(), see # SocketChild.close() if self.stdin > -1: @@ -542,9 +539,6 @@ class SocketChild: for x in self.fds: os.close(x) del self.fds[:] - if self.tty_fd > -1: - os.close(self.tty_fd) - self.tty_fd = -1 if self.stdin > -1: os.close(self.stdin) self.stdin = -1 diff --git a/prewarm-launcher.c b/prewarm-launcher.c index d122efceb..e515bc1f4 100644 --- a/prewarm-launcher.c +++ b/prewarm-launcher.c @@ -60,6 +60,7 @@ typedef struct transfer_buf { } transfer_buf; static transfer_buf from_child_tty = {0}; static transfer_buf to_child_tty = {0}; +static char child_tty_name[256]; #define err_prefix "prewarm wrapper process error: " static inline void @@ -218,7 +219,7 @@ get_termios_state(void) { static bool open_pty(void) { - while (openpty(&child_master_fd, &child_slave_fd, NULL, &self_termios, &self_winsize) == -1) { + while (openpty(&child_master_fd, &child_slave_fd, child_tty_name, &self_termios, &self_winsize) == -1) { if (errno != EINTR) return false; } return true; @@ -256,7 +257,7 @@ setup_signal_handler(void) { static void setup_stdio_handles(void) { - int pos = 1; + int pos = 0; if (!isatty(STDIN_FILENO)) stdin_pos = pos++; if (!isatty(STDOUT_FILENO)) stdout_pos = pos++; if (!isatty(STDERR_FILENO)) stderr_pos = pos++; @@ -291,12 +292,12 @@ static bool create_launch_msg(int argc, char *argv[]) { #define w(prefix, data) { if (!write_item_to_launch_msg(prefix, data)) return false; } static char buf[4*PATH_MAX]; + w("tty_name", child_tty_name); if (getcwd(buf, sizeof(buf))) { w("cwd", buf); } for (int i = 0; i < argc; i++) w("argv", argv[i]); char **s = environ; for (; *s; s++) w("env", *s); int num_fds = 0, fds[4]; - fds[num_fds++] = child_slave_fd; #define sio(which, x) if (which##_pos > -1) { snprintf(buf, sizeof(buf), "%d", which##_pos); w(#which, buf); fds[num_fds++] = x; } sio(stdin, STDIN_FILENO); sio(stdout, STDOUT_FILENO); sio(stderr, STDERR_FILENO); #undef sio @@ -352,7 +353,6 @@ read_child_data(void) { static void close_sent_fds(void) { - if (child_slave_fd > -1) { safe_close(child_slave_fd); child_slave_fd = -1; } #define redirect(which, mode) { int fd = safe_open("/dev/null", mode | O_CLOEXEC, 0); if (fd > -1) { safe_dup2(fd, which); safe_close(fd); } } if (stdin_pos > -1) redirect(STDIN_FILENO, O_RDONLY); if (stdout_pos > -1) redirect(STDOUT_FILENO, O_WRONLY);