]> ruderich.org/simon Gitweb - ptyas/ptyas.git/blobdiff - ptyas.c
Add SIGWINCH handler to support resizes of the outer terminal
[ptyas/ptyas.git] / ptyas.c
diff --git a/ptyas.c b/ptyas.c
index 4b7b208856e88f53a43abc833ea4dde6a7c5bcdb..ee5facf081bd2eec5dc0bc8859626fd992b682e5 100644 (file)
--- a/ptyas.c
+++ b/ptyas.c
@@ -270,10 +270,12 @@ static void proxy_input_between_ttys(int pty_master, int ctty, volatile pid_t *p
 static volatile pid_t pid_to_wait_for;
 static int pid_to_wait_for_status;
 
-static void sigchld_handler() {
+static void sigchld_handler(int signal) {
     int status;
     pid_t pid;
 
+    (void)signal;
+
     while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
         if (pid == pid_to_wait_for) {
             /* Mark that our child has died and we should exit as well. */
@@ -284,6 +286,28 @@ static void sigchld_handler() {
     }
 }
 
+/*
+ * SIGWINCH handler to handle resizes of the outer terminal.
+ *
+ * Errors are ignored without message because printing in signal handlers is
+ * problematic (no FILE * usable due to locks) and there's not much we can do
+ * at this point.
+ */
+static int sigwinch_ctty = -1;
+static int sigwinch_slave = -1;
+
+static void sigwinch_handler(int signal) {
+    (void)signal;
+
+    struct winsize size;
+    if (ioctl(sigwinch_ctty, TIOCGWINSZ, &size) == -1) {
+        return;
+    }
+    if (ioctl(sigwinch_slave, TIOCSWINSZ, &size) == -1) {
+        return;
+    }
+}
+
 
 int main(int argc, char **argv) {
     char *exec_argv_shell[] = { NULL, NULL }; /* filled below */
@@ -420,14 +444,26 @@ int main(int argc, char **argv) {
         }
         quit_with_matching_code(status);
     }
-    close_or_die(pty_slave);
+    /* Don't close pty_slave here as it's used in sigwinch_handler(). */
+
+    sigwinch_ctty = ctty;
+    sigwinch_slave = pty_slave;
+
+    struct sigaction action_sigwinch = {
+        .sa_handler = sigwinch_handler,
+    };
+    sigemptyset(&action_sigwinch.sa_mask);
+    if (sigaction(SIGWINCH, &action_sigwinch, NULL) != 0) {
+        die("sigaction SIGWINCH");
+    }
 
     pid_to_wait_for = pid;
-    struct sigaction action = {
+    struct sigaction action_sigchld = {
         .sa_handler = sigchld_handler,
     };
-    if (sigaction(SIGCHLD, &action, NULL) != 0) {
-        die("sigaction");
+    sigemptyset(&action_sigchld.sa_mask);
+    if (sigaction(SIGCHLD, &action_sigchld, NULL) != 0) {
+        die("sigaction SIGCHLD");
     }
 
     if (sigprocmask(SIG_SETMASK, &sigset_old, NULL) != 0) {