summary refs log tree commit diff
path: root/pkgs/applications/terminal-emulators/foot/Add-support-for-opening-an-existing-PTY.patch
diff options
context:
space:
mode:
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.patch211
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
+