diff options
Diffstat (limited to 'pkgs')
-rw-r--r-- | pkgs/default.nix | 2 | ||||
-rw-r--r-- | pkgs/foot/Add-support-for-opening-an-existing-PTY.patch | 228 | ||||
-rw-r--r-- | pkgs/foot/default.nix | 10 | ||||
-rw-r--r-- | pkgs/overlay.nix | 2 |
4 files changed, 241 insertions, 1 deletions
diff --git a/pkgs/default.nix b/pkgs/default.nix index eb746a8..13ac843 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -22,7 +22,7 @@ let # Packages from the overlay, so it's possible to build them from # the CLI easily. - inherit (pkgs) cloud-hypervisor; + inherit (pkgs) cloud-hypervisor foot; pkgsStatic = makeScope pkgs.pkgsStatic.newScope scope; diff --git a/pkgs/foot/Add-support-for-opening-an-existing-PTY.patch b/pkgs/foot/Add-support-for-opening-an-existing-PTY.patch new file mode 100644 index 0000000..56f9cf2 --- /dev/null +++ b/pkgs/foot/Add-support-for-opening-an-existing-PTY.patch @@ -0,0 +1,228 @@ +From 85cb6c3c705424ff3352d4771efa4c4d0dd09590 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 +SPDX-FileCopyrightText: 2019 Daniel Eklöf +SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> +SPDX-License-Identifier: MIT + +--- + main.c | 13 ++++++++++- + server.c | 2 +- + terminal.c | 68 ++++++++++++++++++++++++++++++++---------------------- + terminal.h | 5 ++-- + 4 files changed, 56 insertions(+), 32 deletions(-) + +diff --git a/main.c b/main.c +index dffd2b2b..aa060747 100644 +--- a/main.c ++++ b/main.c +@@ -3,6 +3,7 @@ + #include <string.h> + #include <ctype.h> + #include <stdbool.h> ++#include <limits.h> + #include <locale.h> + #include <getopt.h> + #include <signal.h> +@@ -174,6 +175,10 @@ sanitize_signals(void) + sigaction(i, &dfl, NULL); + } + ++enum { ++ PTY_OPTION = CHAR_MAX + 1, ++}; ++ + int + main(int argc, char *const *argv) + { +@@ -211,6 +216,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'}, +@@ -223,6 +229,7 @@ main(int argc, char *const *argv) + bool check_config = false; + const char *conf_path = NULL; + const char *custom_cwd = NULL; ++ const char *pty_path = NULL; + bool as_server = false; + const char *conf_server_socket_path = NULL; + bool presentation_timings = false; +@@ -318,6 +325,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; +@@ -576,7 +587,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, NULL, + &term_shutdown_cb, &shutdown_ctx)) == NULL) { + goto out; +diff --git a/server.c b/server.c +index ca55b8f3..b1268574 100644 +--- a/server.c ++++ b/server.c +@@ -332,7 +332,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, envp, &term_shutdown_handler, instance); ++ NULL, cdata.argc, argv, envp, &term_shutdown_handler, instance); + + if (instance->terminal == NULL) { + LOG_ERR("failed to instantiate new terminal"); +diff --git a/terminal.c b/terminal.c +index d4132c24..ad10bb7d 100644 +--- a/terminal.c ++++ b/terminal.c +@@ -367,6 +367,7 @@ fdm_ptmx(struct fdm *fdm, int fd, int events, void *data) + del_utmp_record(term->conf, term->reaper, term->ptmx); + fdm_del(fdm, fd); + term->ptmx = -1; ++ term_shutdown(term); + } + + return true; +@@ -1056,11 +1057,14 @@ 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, char *const *envp, +- void (*shutdown_cb)(void *data, int exit_code), void *shutdown_data) ++ const char *token, const char *pty_path, int argc, char *const *argv, ++ char *const *envp, void (*shutdown_cb)(void *data, int exit_code), ++ void *shutdown_data) + { + int ptmx = -1; + int flash_fd = -1; +@@ -1075,7 +1079,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; + } +@@ -1142,6 +1147,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(), +@@ -1272,16 +1278,18 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper, + + add_utmp_record(conf, reaper, ptmx); + +- /* Start the slave/client */ +- if ((term->slave = slave_spawn( +- term->ptmx, argc, term->cwd, argv, envp, &conf->env_vars, +- 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, envp, &conf->env_vars, ++ 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. Use scaling factor from first monitor */ +@@ -1541,26 +1549,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 25019ecd..569fe8f4 100644 +--- a/terminal.h ++++ b/terminal.h +@@ -722,8 +722,9 @@ 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, char *const *envp, +- void (*shutdown_cb)(void *data, int exit_code), void *shutdown_data); ++ const char *token, const char *pty_path, int argc, char *const *argv, ++ char *const *envp, void (*shutdown_cb)(void *data, int exit_code), ++ void *shutdown_data); + + bool term_shutdown(struct terminal *term); + int term_destroy(struct terminal *term); +-- +2.41.0 + diff --git a/pkgs/foot/default.nix b/pkgs/foot/default.nix new file mode 100644 index 0000000..a44c61d --- /dev/null +++ b/pkgs/foot/default.nix @@ -0,0 +1,10 @@ +# SPDX-FileCopyrightText: 2023 Alyssa Ross <hi@alyssa.is> +# SPDX-License-Identifier: MIT + +import ../../lib/overlay-package.nix "foot" ({ final, super }: + +super.foot.overrideAttrs ({ patches ? [], ... }: { + patches = patches ++ [ + ./Add-support-for-opening-an-existing-PTY.patch + ]; +})) diff --git a/pkgs/overlay.nix b/pkgs/overlay.nix index 32949d5..e9b3a53 100644 --- a/pkgs/overlay.nix +++ b/pkgs/overlay.nix @@ -3,4 +3,6 @@ (final: super: { cloud-hypervisor = import ../pkgs/cloud-hypervisor { inherit final super; }; + + foot = import ../pkgs/foot { inherit final super; }; }) |