delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2009/08/13/13:18:18

X-Recipient: archive-cygwin AT delorie DOT com
X-SWARE-Spam-Status: No, hits=-1.6 required=5.0 tests=AWL,BAYES_00
X-Spam-Check-By: sourceware.org
Message-ID: <4A844A97.1050809@sipxx.com>
Date: Thu, 13 Aug 2009 13:17:11 -0400
From: cygwin <karl AT sipxx DOT com>
Reply-To: cygwin AT sipxx DOT com
User-Agent: Thunderbird 2.0.0.22 (Windows/20090605)
MIME-Version: 1.0
To: cygwin AT cygwin DOT com
Subject: Cygwin1.dll 1.7.0-5x: RSYNC failures in close() system call on pipe file descriptors
Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Id: <cygwin.cygwin.com>
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com

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

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019