sshd problem on Solaris 7: Control-C hangs shell

Tor Lillqvist Tor.Lillqvist at tellabs.com
Mon Jul 9 20:18:28 EST 2001


I have a strange problem with sshd (from openssh-2.9p2) on Solaris 7. My shell is bash. When I open an ssh session , and type a Control-C to bash's prompt, the shell hangs. (But, if I for instance run "sleep 10" (during which time the pty is in cooked mode) and press Control-C, the sleep command is interrupted quite normally, and the bash prompt returns.) 

Adding some debugging printfs tell me that the read(fdout,...) in serverloop.c:process_input() returns zero when I type the Control-C?! Some Solaris quirk in pty behaviour related to interrupts in raw mode? Following this read returning 0, sshd thinks it got an EOF, closes its side of the pty, but the shell still thinks everything is OK, but of course can't get any input.

So, my next try is to comment out the fdout_eof assignment. But then again, exiting from the ssh session causes the sshd to loop (printing tvp!=NULL kid 1 milli 100), and if I then press Control-C to the ssh client (where I already have exited the shell in the ssh session), sshd loops tighter, getting 0 all the time from the read(fdout). Hmm, more hacking...

A horrible hack that seems to "fix" my problem is:

--- /tmp/openssh-2.9p2/serverloop.c	Sat Apr 14 02:28:03 2001
+++ serverloop.c	Mon Jul  9 13:02:27 2001
@@ -74,4 +74,5 @@
 static int stdin_eof = 0;	/* EOF message received from client. */
 static int fdout_eof = 0;	/* EOF encountered reading from fdout. */
+static int fdout_maybe_eof = 0;
 static int fderr_eof = 0;	/* EOF encountered readung from fderr. */
 static int fdin_is_tty = 0;	/* fdin points to a tty. */
@@ -107,6 +108,9 @@
 			      wait_pid, child_pid);
 		if (WIFEXITED(child_wait_status) ||
-		    WIFSIGNALED(child_wait_status))
+		    WIFSIGNALED(child_wait_status)) {
 			child_terminated = 1;
+			if (fdout_maybe_eof)
+				fdout_eof = 1;
+		}
 	}
 	signal(SIGCHLD, sigchld_handler);
@@ -338,10 +342,14 @@
 
 	/* Read and buffer any available stdout data from the program. */
-	if (!fdout_eof && FD_ISSET(fdout, readset)) {
+	if (!fdout_eof && (child_terminated || FD_ISSET(fdout, readset))) {
 		len = read(fdout, buf, sizeof(buf));
 		if (len < 0 && (errno == EINTR || errno == EAGAIN)) {
 			/* do nothing */
 		} else if (len <= 0) {
-			fdout_eof = 1;
+			verbose ("read from fdout returns zero?");
+			if (child_terminated)
+				fdout_eof = 1;
+			else
+				fdout_maybe_eof = 1;
 		} else {
 			buffer_append(&stdout_buffer, buf, len);

But no doubt it would be much better if somebody who understands how ptys work in Solaris 7 could figure out the *right* way to fix this. I don't recommend adding that hack to the code.

With the old Ylönen ssh 1.2.26, the behaviour is a bit different: A Control-C to bash's prompt kills the shell completely, with SIGHUP eventually. BTW, with Solaris 2.5.1, I didn't notice any of these problems.

--tml



More information about the openssh-unix-dev mailing list