xterm-class programs should exit when their primary child process
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Mon, 14 Oct 2002 09:18:34 +0000 (09:18 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Mon, 14 Oct 2002 09:18:34 +0000 (09:18 +0000)
dies, rather than waiting around until the last open handle on the
pty closes.

git-svn-id: svn://svn.tartarus.org/sgt/putty@2044 cda61777-01e9-0310-a592-d414129be87e

unix/pterm.c
unix/pty.c

index d258f9e..e6ffee3 100644 (file)
@@ -710,6 +710,19 @@ gint motion_event(GtkWidget *widget, GdkEventMotion *event, gpointer data)
 gint timer_func(gpointer data)
 {
     /* struct gui_data *inst = (struct gui_data *)data; */
+    extern int pty_child_is_dead();  /* declared in pty.c */
+
+    if (pty_child_is_dead()) {
+       /*
+        * The primary child process died. We could keep the
+        * terminal open for remaining subprocesses to output to,
+        * but conventional wisdom seems to feel that that's the
+        * Wrong Thing for an xterm-alike, so we bail out now. This
+        * would be easy enough to change or make configurable if
+        * necessary.
+        */
+       exit(0);
+    }
 
     term_update();
     return TRUE;
index 8a3d06b..9347bb9 100644 (file)
@@ -6,8 +6,11 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <signal.h>
 #include <fcntl.h>
 #include <termios.h>
+#include <sys/types.h>
+#include <sys/wait.h>
 #include <sys/ioctl.h>
 
 #include "putty.h"
 #endif
 
 int pty_master_fd;
+static int pty_child_pid;
+static sig_atomic_t pty_child_dead;
 char **pty_argv;
 
+int pty_child_is_dead(void)
+{
+    return pty_child_dead;
+}
+
 static void pty_size(void);
 
+static void sigchld_handler(int signum)
+{
+    pid_t pid;
+    int status;
+    pid = waitpid(-1, &status, WNOHANG);
+    if (pid == pty_child_pid && (WIFEXITED(status) || WIFSIGNALED(status)))
+       pty_child_dead = TRUE;  
+}
+
 /*
  * Called to set up the pty.
  * 
@@ -113,6 +132,9 @@ static char *pty_init(char *host, int port, char **realhost, int nodelay)
        exit(127);
     } else {
        close(slavefd);
+       pty_child_pid = pid;
+       pty_child_dead = FALSE;
+       signal(SIGCHLD, sigchld_handler);
     }
 
     return NULL;