Occasionally (especially when the parent process has alarm signals running, which get inherited to the child rsync process, but even when no signal activity is happening) Mac OS X will return that a read socket is ready to be read from, but 0 bytes are returned from a read() call. Rsync assumes this means the connection is closed, which tears the session down. On OS X this seems not to be true. This only seems to occur on very busy systems, it's difficult to reproduce on a development machine, but nearly impossible to work around on a busy server. This bug also appears only to be present in OS X 10.4, reverting to 10.3 is fine. This patch has worked fine for me for a few weeks now, which changed things from "unusable on OS X" to "works flawlessly". I think it's safe to commit, I don't know of any OS that returns 0 on a read without setting errno when something really is wrong. --- io.c.orig 2005-08-20 18:44:34.000000000 +0000 +++ io.c 2005-08-20 19:02:37.000000000 +0000 @@ -570,7 +570,7 @@ n = read(fd, buf, len); - if (n <= 0) { + if ((n <= 0) && errno) { if (n == 0) whine_about_eof(fd); /* Doesn't return. */ if (errno == EINTR || errno == EWOULDBLOCK
This is a bug in MacOS, then. A return of 0 from read() indicates end-of-file, and errno is not guaranteed to be any particular value in that case (I've tested that it is often 0). If MacOS has a no-data situation such as that, they should probably be returning -1 with errno set to EAGAIN.