- (dtucker) [channels.c configure.ac serverloop.c] Bug #1102: Around AIX
   4.3.3 ML3 or so, the AIX pty layer starting passing zero-length writes
   on the pty slave as zero-length reads on the pty master, which sshd
   interprets as the descriptor closing.  Since most things don't do zero
   length writes this rarely matters, but occasionally it happens, and when
   it does the SSH pty session appears to hang, so we add a special case for
   this condition.  ok djm@
diff --git a/ChangeLog b/ChangeLog
index 327fec1..dfaa467 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,13 @@
  - (dtucker) [README.platform configure.ac openbsd-compat/port-tun.c] Add
    tunnel support for Mac OS X/Darwin via a third-party tun driver.  Patch
    from reyk@, tested by anil@
+ - (dtucker) [channels.c configure.ac serverloop.c] Bug #1102: Around AIX
+   4.3.3 ML3 or so, the AIX pty layer starting passing zero-length writes
+   on the pty slave as zero-length reads on the pty master, which sshd
+   interprets as the descriptor closing.  Since most things don't do zero
+   length writes this rarely matters, but occasionally it happens, and when
+   it does the SSH pty session appears to hang, so we add a special case for
+   this condition.  ok djm@
 
 20060613
  - (djm) [getput.h] This file has been replaced by functions in misc.c
@@ -4690,4 +4697,4 @@
    - (djm) Trim deprecated options from INSTALL. Mention UsePAM
    - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu
 
-$Id: ChangeLog,v 1.4345 2006/06/23 11:05:12 dtucker Exp $
+$Id: ChangeLog,v 1.4346 2006/06/23 11:24:12 dtucker Exp $
diff --git a/channels.c b/channels.c
index 2fa997e..239e9dd 100644
--- a/channels.c
+++ b/channels.c
@@ -1415,10 +1415,15 @@
 
 	if (c->rfd != -1 &&
 	    FD_ISSET(c->rfd, readset)) {
+		errno = 0;
 		len = read(c->rfd, buf, sizeof(buf));
 		if (len < 0 && (errno == EINTR || errno == EAGAIN))
 			return 1;
+#ifndef PTY_ZEROREAD
 		if (len <= 0) {
+#else
+		if (len < 0 || (len == 0 && errno != 0)) {
+#endif
 			debug2("channel %d: read<=0 rfd %d len %d",
 			    c->self, c->rfd, len);
 			if (c->type != SSH_CHANNEL_OPEN) {
diff --git a/configure.ac b/configure.ac
index c3cb68f..259b5c2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-# $Id: configure.ac,v 1.340 2006/06/23 11:05:13 dtucker Exp $
+# $Id: configure.ac,v 1.341 2006/06/23 11:24:13 dtucker Exp $
 #
 # Copyright (c) 1999-2004 Damien Miller
 #
@@ -15,7 +15,7 @@
 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org)
-AC_REVISION($Revision: 1.340 $)
+AC_REVISION($Revision: 1.341 $)
 AC_CONFIG_SRCDIR([ssh.c])
 
 AC_CONFIG_HEADER(config.h)
@@ -190,6 +190,7 @@
 		supported by bsd-setproctitle.c])
 	AC_DEFINE(SSHPAM_CHAUTHTOK_NEEDS_RUID, 1,
 	    [AIX 5.2 and 5.3 (and presumably newer) require this])
+	AC_DEFINE(PTY_ZEROREAD, 1, [read(1) can return 0 for a non-closed fd])
 	;;
 *-*-cygwin*)
 	check_for_libcrypt_later=1
diff --git a/serverloop.c b/serverloop.c
index 021ba68..c1eb288 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -387,10 +387,15 @@
 
 	/* Read and buffer any available stdout data from the program. */
 	if (!fdout_eof && FD_ISSET(fdout, readset)) {
+		errno = 0;
 		len = read(fdout, buf, sizeof(buf));
 		if (len < 0 && (errno == EINTR || errno == EAGAIN)) {
 			/* do nothing */
+#ifdef PTY_ZEROREAD
 		} else if (len <= 0) {
+#else
+		} else if (len < 0 || (len == 0 && errno != 0)) {
+#endif
 			fdout_eof = 1;
 		} else {
 			buffer_append(&stdout_buffer, buf, len);
@@ -399,10 +404,15 @@
 	}
 	/* Read and buffer any available stderr data from the program. */
 	if (!fderr_eof && FD_ISSET(fderr, readset)) {
+		errno = 0;
 		len = read(fderr, buf, sizeof(buf));
 		if (len < 0 && (errno == EINTR || errno == EAGAIN)) {
 			/* do nothing */
+#ifdef PTY_ZEROREAD
 		} else if (len <= 0) {
+#else
+		} else if (len < 0 || (len == 0 && errno != 0)) {
+#endif
 			fderr_eof = 1;
 		} else {
 			buffer_append(&stderr_buffer, buf, len);