]> ruderich.org/simon Gitweb - ptyas/ptyas.git/blobdiff - ptyas.c
Update copyright years
[ptyas/ptyas.git] / ptyas.c
diff --git a/ptyas.c b/ptyas.c
index 9fc7997269a23b756f8a173f399f8bbad771df26..d650f1858f0843ac56747354cd8c4bef3291113b 100644 (file)
--- a/ptyas.c
+++ b/ptyas.c
@@ -2,7 +2,7 @@
  * Run the login shell or command as the given user in a new pty to prevent
  * terminal injection attacks.
  *
- * Copyright (C) 2016-2018  Simon Ruderich
+ * Copyright (C) 2016-2019  Simon Ruderich
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -286,6 +286,28 @@ static void sigchld_handler(int signal) {
     }
 }
 
+/*
+ * 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 */
@@ -422,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) {