diff options
Diffstat (limited to 'pkgs/applications/terminal-emulators/foot/Add-support-for-opening-an-existing-PTY.patch')
-rw-r--r-- | pkgs/applications/terminal-emulators/foot/Add-support-for-opening-an-existing-PTY.patch | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/pkgs/applications/terminal-emulators/foot/Add-support-for-opening-an-existing-PTY.patch b/pkgs/applications/terminal-emulators/foot/Add-support-for-opening-an-existing-PTY.patch new file mode 100644 index 00000000000..f07a26bad6f --- /dev/null +++ b/pkgs/applications/terminal-emulators/foot/Add-support-for-opening-an-existing-PTY.patch @@ -0,0 +1,211 @@ +From 6cb6fe265eb8c066fce8ce12473d6b8135f3b3cb Mon Sep 17 00:00:00 2001 +From: Alyssa Ross <hi@alyssa.is> +Date: Fri, 10 Dec 2021 17:40:59 +0000 +Subject: [PATCH] Add support for opening an existing PTY + +--- + main.c | 12 +++++++++- + server.c | 2 +- + terminal.c | 65 +++++++++++++++++++++++++++++++----------------------- + terminal.h | 2 +- + 4 files changed, 51 insertions(+), 30 deletions(-) + +diff --git a/main.c b/main.c +index 4f2dc7b6..d1307a84 100644 +--- a/main.c ++++ b/main.c +@@ -152,6 +152,10 @@ print_pid(const char *pid_file, bool *unlink_at_exit) + return false; + } + ++enum { ++ PTY_OPTION = CHAR_MAX + 1, ++}; ++ + int + main(int argc, char *const *argv) + { +@@ -187,6 +191,7 @@ main(int argc, char *const *argv) + {"maximized", no_argument, NULL, 'm'}, + {"fullscreen", no_argument, NULL, 'F'}, + {"presentation-timings", no_argument, NULL, 'P'}, /* Undocumented */ ++ {"pty", required_argument, NULL, PTY_OPTION}, + {"print-pid", required_argument, NULL, 'p'}, + {"log-level", required_argument, NULL, 'd'}, + {"log-colorize", optional_argument, NULL, 'l'}, +@@ -202,6 +207,7 @@ main(int argc, char *const *argv) + const char *conf_title = NULL; + const char *conf_app_id = NULL; + const char *custom_cwd = NULL; ++ const char *pty_path = NULL; + bool login_shell = false; + tll(char *) conf_fonts = tll_init(); + enum conf_size_type conf_size_type = CONF_SIZE_PX; +@@ -320,6 +326,10 @@ main(int argc, char *const *argv) + conf_server_socket_path = optarg; + break; + ++ case PTY_OPTION: ++ pty_path = optarg; ++ break; ++ + case 'P': + presentation_timings = true; + break; +@@ -538,7 +548,7 @@ main(int argc, char *const *argv) + goto out; + + if (!as_server && (term = term_init( +- &conf, fdm, reaper, wayl, "foot", cwd, token, ++ &conf, fdm, reaper, wayl, "foot", cwd, token, pty_path, + argc, argv, + &term_shutdown_cb, &shutdown_ctx)) == NULL) { + goto out; +diff --git a/server.c b/server.c +index 1d31abc6..190d224d 100644 +--- a/server.c ++++ b/server.c +@@ -315,7 +315,7 @@ fdm_client(struct fdm *fdm, int fd, int events, void *data) + instance->terminal = term_init( + conf != NULL ? conf : server->conf, + server->fdm, server->reaper, server->wayl, "footclient", cwd, token, +- cdata.argc, argv, &term_shutdown_handler, instance); ++ NULL, cdata.argc, argv, &term_shutdown_handler, instance); + + if (instance->terminal == NULL) { + LOG_ERR("failed to instantiate new terminal"); +diff --git a/terminal.c b/terminal.c +index ac887412..e11ef0d6 100644 +--- a/terminal.c ++++ b/terminal.c +@@ -327,6 +327,7 @@ fdm_ptmx(struct fdm *fdm, int fd, int events, void *data) + if (hup) { + fdm_del(fdm, fd); + term->ptmx = -1; ++ term_shutdown(term); + } + + return true; +@@ -1035,10 +1036,12 @@ load_fonts_from_conf(struct terminal *term) + static void fdm_client_terminated( + struct reaper *reaper, pid_t pid, int status, void *data); + ++static const int PTY_OPEN_FLAGS = O_RDWR | O_NOCTTY; ++ + struct terminal * + term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper, + struct wayland *wayl, const char *foot_exe, const char *cwd, +- const char *token, int argc, char *const *argv, ++ const char *token, const char *pty_path, int argc, char *const *argv, + void (*shutdown_cb)(void *data, int exit_code), void *shutdown_data) + { + int ptmx = -1; +@@ -1054,7 +1057,8 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper, + return NULL; + } + +- if ((ptmx = posix_openpt(O_RDWR | O_NOCTTY)) < 0) { ++ ptmx = pty_path ? open(pty_path, PTY_OPEN_FLAGS) : posix_openpt(PTY_OPEN_FLAGS); ++ if (ptmx < 0) { + LOG_ERRNO("failed to open PTY"); + goto close_fds; + } +@@ -1116,6 +1120,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper, + .fdm = fdm, + .reaper = reaper, + .conf = conf, ++ .slave = -1, + .ptmx = ptmx, + .ptmx_buffers = tll_init(), + .ptmx_paste_buffers = tll_init(), +@@ -1237,16 +1242,18 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper, + } + term->font_line_height = conf->line_height; + +- /* Start the slave/client */ +- if ((term->slave = slave_spawn( +- term->ptmx, argc, term->cwd, argv, +- conf->term, conf->shell, conf->login_shell, +- &conf->notifications)) == -1) +- { +- goto err; +- } ++ if (!pty_path) { ++ /* Start the slave/client */ ++ if ((term->slave = slave_spawn( ++ term->ptmx, argc, term->cwd, argv, ++ conf->term, conf->shell, conf->login_shell, ++ &conf->notifications)) == -1) ++ { ++ goto err; ++ } + +- reaper_add(term->reaper, term->slave, &fdm_client_terminated, term); ++ reaper_add(term->reaper, term->slave, &fdm_client_terminated, term); ++ } + + /* Guess scale; we're not mapped yet, so we don't know on which + * output we'll be. Pick highest scale we find for now */ +@@ -1506,26 +1513,30 @@ term_shutdown(struct terminal *term) + close(term->ptmx); + + if (!term->shutdown.client_has_terminated) { +- LOG_DBG("initiating asynchronous terminate of slave; " +- "sending SIGTERM to PID=%u", term->slave); ++ if (term->slave <= 0) { ++ term->shutdown.client_has_terminated = true; ++ } else { ++ LOG_DBG("initiating asynchronous terminate of slave; " ++ "sending SIGTERM to PID=%u", term->slave); + +- kill(-term->slave, SIGTERM); ++ kill(-term->slave, SIGTERM); + +- const struct itimerspec timeout = {.it_value = {.tv_sec = 60}}; ++ const struct itimerspec timeout = {.it_value = {.tv_sec = 60}}; + +- int timeout_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); +- if (timeout_fd < 0 || +- timerfd_settime(timeout_fd, 0, &timeout, NULL) < 0 || +- !fdm_add(term->fdm, timeout_fd, EPOLLIN, &fdm_terminate_timeout, term)) +- { +- if (timeout_fd >= 0) +- close(timeout_fd); +- LOG_ERRNO("failed to create slave terminate timeout FD"); +- return false; ++ int timeout_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); ++ if (timeout_fd < 0 || ++ timerfd_settime(timeout_fd, 0, &timeout, NULL) < 0 || ++ !fdm_add(term->fdm, timeout_fd, EPOLLIN, &fdm_terminate_timeout, term)) ++ { ++ if (timeout_fd >= 0) ++ close(timeout_fd); ++ LOG_ERRNO("failed to create slave terminate timeout FD"); ++ return false; ++ } ++ ++ xassert(term->shutdown.terminate_timeout_fd < 0); ++ term->shutdown.terminate_timeout_fd = timeout_fd; + } +- +- xassert(term->shutdown.terminate_timeout_fd < 0); +- term->shutdown.terminate_timeout_fd = timeout_fd; + } + + term->selection.auto_scroll.fd = -1; +diff --git a/terminal.h b/terminal.h +index 09b04614..3beb3e80 100644 +--- a/terminal.h ++++ b/terminal.h +@@ -671,7 +671,7 @@ struct config; + struct terminal *term_init( + const struct config *conf, struct fdm *fdm, struct reaper *reaper, + struct wayland *wayl, const char *foot_exe, const char *cwd, +- const char *token, int argc, char *const *argv, ++ const char *token, const char *pty_path, int argc, char *const *argv, + void (*shutdown_cb)(void *data, int exit_code), void *shutdown_data); + + bool term_shutdown(struct terminal *term); +-- +2.33.0 + |