summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2022-06-28 17:45:02 +0000
committerAlyssa Ross <hi@alyssa.is>2023-11-21 16:10:47 +0100
commitc20cc4f1f089f4a93651a1b667299ddac73f59ba (patch)
tree3c1225fe9ccdeb4bb0e05f828482839095672de0
parent42cc5e5a3333fac99dea003249f1439800aba05d (diff)
downloadnixpkgs-c20cc4f1f089f4a93651a1b667299ddac73f59ba.tar
nixpkgs-c20cc4f1f089f4a93651a1b667299ddac73f59ba.tar.gz
nixpkgs-c20cc4f1f089f4a93651a1b667299ddac73f59ba.tar.bz2
nixpkgs-c20cc4f1f089f4a93651a1b667299ddac73f59ba.tar.lz
nixpkgs-c20cc4f1f089f4a93651a1b667299ddac73f59ba.tar.xz
nixpkgs-c20cc4f1f089f4a93651a1b667299ddac73f59ba.tar.zst
nixpkgs-c20cc4f1f089f4a93651a1b667299ddac73f59ba.zip
foot: add support for opening an existing PTY
-rw-r--r--pkgs/applications/terminal-emulators/foot/Add-support-for-opening-an-existing-PTY.patch225
-rw-r--r--pkgs/applications/terminal-emulators/foot/default.nix4
2 files changed, 229 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..5dc3b2e8460
--- /dev/null
+++ b/pkgs/applications/terminal-emulators/foot/Add-support-for-opening-an-existing-PTY.patch
@@ -0,0 +1,225 @@
+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
+
+---
+ 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/applications/terminal-emulators/foot/default.nix b/pkgs/applications/terminal-emulators/foot/default.nix
index ad9487b082c..1792b587c1b 100644
--- a/pkgs/applications/terminal-emulators/foot/default.nix
+++ b/pkgs/applications/terminal-emulators/foot/default.nix
@@ -104,6 +104,10 @@ stdenv.mkDerivation {
 
   separateDebugInfo = true;
 
+  patches = [
+    ./Add-support-for-opening-an-existing-PTY.patch
+  ];
+
   depsBuildBuild = [
     pkg-config
   ];