]> andersk Git - openssh.git/commitdiff
- Fix hang on logout if processes are still using the pty. Needs
authordamien <damien>
Mon, 17 Jan 2000 09:55:18 +0000 (09:55 +0000)
committerdamien <damien>
Mon, 17 Jan 2000 09:55:18 +0000 (09:55 +0000)
   further testing.

ChangeLog
TODO
serverloop.c

index 8c182d6cb45c73b8f8813dd305a0e22fa2a074b8..0366d260b1a020c1e6ed17e136be6ac6f60698b8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -12,6 +12,8 @@
  - Fix rresvport_af failure errors (logic error in bsd-bindresvport.c)
  - Fix --with-ipaddr-display option test. Fix from Jarno Huuskonen 
    <jhuuskon@hytti.uku.fi>
+ - Fix hang on logout if processes are still using the pty. Needs 
+   further testing.
 
 20000116
  - Renamed --with-xauth-path to --with-xauth
diff --git a/TODO b/TODO
index 0eccc9be40c16721c6ac2d04f0aa278cb8569fa1..785b49066d3a576f60cbdd217d290dceed4610b7 100644 (file)
--- a/TODO
+++ b/TODO
@@ -8,19 +8,3 @@
   lack of u_intXX_t types. There must be a better way.
 
 - Move all compatability cruft (bsd-*, fake-*) into subordinate library
-
-- Hanging on logout:
-
-localhost$ ssh remotehost
-remotehost$ sleep 20 &
-remotehost$ logout
-(ssh hangs at logout for 20 seconds)
-
-Worse:
-
-localhost$ ssh root@remotehost
-remotehost# httpd
-remotehost# logout
-(ssh hangs at logout forever)
-
-This appears to be a problem in the server.
index a5ecfe97d5d7cde64aa147a7bdfb80918f0f8320..2afca7637039345b82d766314378004442be0575 100644 (file)
@@ -36,10 +36,15 @@ static int max_fd;          /* Max file descriptor number for select(). */
 /*
  * This SIGCHLD kludge is used to detect when the child exits.  The server
  * will exit after that, as soon as forwarded connections have terminated.
+ *
+ * After SIGCHLD child_has_selected is set to 1 after the first pass
+ * through the wait_until_can_do_something() select(). This ensures
+ * that the child's output gets a chance to drain before it is yanked.
  */
 
 static int child_pid;                  /* Pid of the child. */
 static volatile int child_terminated;  /* The child has terminated. */
+static volatile int child_has_selected; /* Child has had chance to drain. */
 static volatile int child_wait_status; /* Status from wait(). */
 
 void 
@@ -56,6 +61,7 @@ sigchld_handler(int sig)
                if (WIFEXITED(child_wait_status) ||
                    WIFSIGNALED(child_wait_status))
                        child_terminated = 1;
+                       child_has_selected = 0;
        }
        signal(SIGCHLD, sigchld_handler);
        errno = save_errno;
@@ -300,6 +306,9 @@ retry_select:
                else
                        goto retry_select;
        }
+       
+       if (child_terminated)
+               child_has_selected = 1;
 }
 
 /*
@@ -438,6 +447,7 @@ server_loop(int pid, int fdin_arg, int fdout_arg, int fderr_arg)
        /* Initialize the SIGCHLD kludge. */
        child_pid = pid;
        child_terminated = 0;
+       child_has_selected = 0;
        signal(SIGCHLD, sigchld_handler);
 
        /* Initialize our global variables. */
@@ -533,8 +543,11 @@ server_loop(int pid, int fdin_arg, int fdout_arg, int fderr_arg)
                 * descriptors, and we have no more data to send to the
                 * client, and there is no pending buffered data.
                 */
-               if (fdout_eof && fderr_eof && !packet_have_data_to_write() &&
-                   buffer_len(&stdout_buffer) == 0 && buffer_len(&stderr_buffer) == 0) {
+               if (((fdout_eof && fderr_eof) || 
+                   (child_terminated && child_has_selected)) && 
+                   !packet_have_data_to_write() &&
+                   (buffer_len(&stdout_buffer) == 0) && 
+                        (buffer_len(&stderr_buffer) == 0)) {
                        if (!channel_still_open())
                                goto quit;
                        if (!waiting_termination) {
This page took 0.045504 seconds and 5 git commands to generate.