]> git.ipfire.org Git - pakfire.git/commitdiff
pty: Handle resizing the terminal window
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 6 Oct 2024 12:57:10 +0000 (12:57 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 6 Oct 2024 12:57:10 +0000 (12:57 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/pty.c

index 7c503b9fa1d0f5053f1de4d9fd38161a3aaff745..c1e963508adfaf257d89df13d4bf1ee0262b1cb1 100644 (file)
@@ -77,6 +77,9 @@ struct pakfire_pty {
        // Standard Input
        struct pakfire_pty_stdio stdin;
        struct pakfire_pty_stdio stdout;
+
+       // SIGWINCH Event
+       sd_event_source* sigwinch_event;
 };
 
 /*
@@ -249,6 +252,31 @@ static int pakfire_pty_restore_attrs(struct pakfire_pty* pty,
        return 0;
 }
 
+/*
+       Forwards any window size changes.
+*/
+static int pakfire_pty_SIGWINCH(sd_event_source* source, const struct signalfd_siginfo* si, void* data) {
+       struct pakfire_pty* pty = data;
+       struct winsize size;
+       int r;
+
+       // Don't do anything if we have not been set up, yet
+       if (pty->stdout.fd < 0 || pty->master.fd < 0)
+               return 0;
+
+       // Fetch the new window size
+       r = ioctl(pty->stdout.fd, TIOCGWINSZ, &size);
+       if (r < 0)
+               return 0;
+
+       // Set the new window size
+       r = ioctl(pty->master.fd, TIOCSWINSZ, &size);
+       if (r < 0)
+               return 0;
+
+       return 0;
+}
+
 static int pakfire_pty_activity(struct pakfire_pty* pty, struct pakfire_pty_stdio* stdio, uint32_t events) {
        // Do we have data to read?
        if (events & (EPOLLIN|EPOLLHUP))
@@ -519,6 +547,8 @@ static void pakfire_pty_free(struct pakfire_pty* pty) {
                sd_event_source_unref(pty->stdin.event);
        if (pty->stdout.event)
                sd_event_source_unref(pty->stdout.event);
+       if (pty->sigwinch_event)
+               sd_event_source_unref(pty->sigwinch_event);
        if (pty->socket[0] >= 0)
                close(pty->socket[0]);
        if (pty->socket[1] >= 0)
@@ -688,5 +718,13 @@ int pakfire_pty_open(struct pakfire_pty* pty) {
        close(pty->master.fd);
        pty->master.fd = -1;
 
+       // Listen to SIGWINCH
+       r = sd_event_add_signal(pty->loop, &pty->sigwinch_event,
+                       SIGWINCH|SD_EVENT_SIGNAL_PROCMASK, pakfire_pty_SIGWINCH, pty);
+       if (r < 0) {
+               CTX_ERROR(pty->ctx, "Could not register SIGWINCH: %s\n", strerror(-r));
+               return r;
+       }
+
        return 0;
 }