Cygwin1.dll 1.7.0-5x: RSYNC failures in close() system call on pipe file descriptors

cygwin karl@sipxx.com
Thu Aug 13 17:18:00 GMT 2009


The RSYNC application fails in close() on the pipe streams to and from 
child processes created when rsync starts.
When running rsync.exe and cygwin1.dll from cygwin 1.5 within the 1.7 
installation on the same system (WinXP pro),
the identical invocation completes without errors.

The problems appears to be a bug in the cygwin.dll

For example,

$ rsync -a /etc /test

produces the following messages:

rsync: Failed to dup/close: Socket operation on non-socket (108)
rsync error: error in IPC code (code 14) at pipe.c(147) [receiver=3.0.5]
rsync: read error: Connection reset by peer (104)
rsync error: error in IPC code (code 14) at io.c(759) [sender=3.0.5]



Since there are several close() calls and a dup2() ORed in one statement 
in pipe.c, so that the error message is not conclusively linked to a 
single call, I separated them with this patch. The patch first prints 
out the file descriptors for the streams to/from the child, to make sure 
they are valid before we try to close() them, and then it tests the 
result from close() after each call.


$ diff -u /usr/src/rsync*/origsrc/*/pipe.c ./pipe.c
--- /usr/src/rsync-3.0.5-1/origsrc/rsync-3.0.5/pipe.c   2008-03-01 
15:01:41.000000000 -0500
+++ ./pipe.c    2009-08-13 01:17:16.250000000 -0400
@@ -139,17 +139,39 @@
                        logfile_close();
                }
 
-               if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
-                   close(to_child_pipe[1]) < 0 ||
-                   close(from_child_pipe[0]) < 0 ||
-                   dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
-                       rsyserr(FERROR, errno, "Failed to dup/close");
+               if (dup2(to_child_pipe[0], STDIN_FILENO) < 0) {
+                       rsyserr(FERROR, errno, "Failed to dup2(to-0)");
                        exit_cleanup(RERR_IPC);
                }
-               if (to_child_pipe[0] != STDIN_FILENO)
-                       close(to_child_pipe[0]);
-               if (from_child_pipe[1] != STDOUT_FILENO)
-                       close(from_child_pipe[1]);
+
+               printf("  to_child_pipe[0] = %d\n", to_child_pipe[0]);
+               printf("  to_child_pipe[1] = %d\n", to_child_pipe[1]);
+               printf("from_child_pipe[0] = %d\n", from_child_pipe[0]);
+               printf("from_child_pipe[1] = %d\n", from_child_pipe[1]);
+
+               if (close(to_child_pipe[1]) < 0 ) {
+                       rsyserr(FERROR, errno, "Failed to close(to-1)");
+                       //exit_cleanup(RERR_IPC);
+               }
+               if (close(from_child_pipe[0]) < 0 ) {
+                       rsyserr(FERROR, errno, "Failed to close(from-0)");
+                       //exit_cleanup(RERR_IPC);
+               }
+               if (dup2(from_child_pipe[1], STDOUT_FILENO) < 0 ) {
+                       rsyserr(FERROR, errno, "Failed to dup(from-1)");
+                       exit_cleanup(RERR_IPC);
+               }
+               if (to_child_pipe[0] != STDIN_FILENO) {
+                       fprintf(stderr, "closing to-0\n");
+                       int res=close(to_child_pipe[0]);
+                       if (res < 0) rsyserr(FERROR, errno, "Failed to 
close(to-0)");
+                       }
+               if (from_child_pipe[1] != STDOUT_FILENO) {
+                       fprintf(stderr, "closing from-1\n");
+                       int res=close(from_child_pipe[1]);
+                       if (res < 0) rsyserr(FERROR, errno, "Failed to 
close(from-1)");
+                       }
+               fprintf(stderr, "End of pipe.c, entering child_main()\n");
 #ifdef ICONV_CONST
                setup_iconv();
 #endif




This patched version prints the following resulting messages and then 
just hangs indefinitely:

$ ./rsync -a /etc /test
  to_child_pipe[0] = 3
  to_child_pipe[1] = 4
from_child_pipe[0] = 5
from_child_pipe[1] = 6
rsync: Failed to close(to-1): Socket operation on non-socket (108)
rsync: Failed to close(from-0): Socket operation on non-socket (108)
closing to-0
rsync: Failed to close(to-0): Socket operation on non-socket (108)
closing from-1
rsync: Failed to close(from-1): Socket operation on non-socket (108)
End of pipe.c, entering child_main()


Rsync is used in cygport to copy directories, so I can't  actually build 
any source code with stock cygport (I replaced the rsync with cp).
As I haven't found a prior trouble report, I am wondering whether this 
happens only on my system, seems strange that no one has built source 
code on Cygwin 1.7 without having the same trouble.




--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple



More information about the Cygwin mailing list