Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT sources DOT redhat DOT com Delivered-To: mailing list cygwin AT sources DOT redhat DOT com Date: Fri, 13 Jul 2001 20:21:46 -0400 From: Christopher Faylor To: cygwin AT cygwin DOT com Subject: Re: data in socketpair() channel lost if writer closes or exits without shutting down Message-ID: <20010713202146.B11377@redhat.com> Reply-To: cygwin AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com References: <20010713181435 DOT 3695 DOT qmail AT lizard DOT curl DOT com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.3.11i In-Reply-To: <20010713181435.3695.qmail@lizard.curl.com>; from jik@curl.com on Fri, Jul 13, 2001 at 02:14:35PM -0400 Thanks for the diagnosis. Would you be willing to look at the Cygwin socket code and suggest a fix? cgf On Fri, Jul 13, 2001 at 02:14:35PM -0400, Jonathan Kamens wrote: >The test program below creates a socketpair and then forks. The child >writes some data to the socketpair and then exits, and the parent >tries to read that data. > >Instead of printing "PARENT: foo (exiting)" as it should, the parent >prints "PARENT: read: Connection reset by peer". This is also true if >you compile the program with "-DUSE_CLOSE" to tell the child to close >the write end of the socketpair before exiting. However, it works >properly if you compile the program with "-DUSE_SHUTDOWN" to tell the >child to shutdown its end of the socketpair before exiting. > >There are two different bugs here: > >1) close() on an end of a socketpair should behave the same as > shutdown(..., 2), in terms of flushing data to the other end of the > socketpair. > >2) Data sent by the writer should be flushed to the reader, not lost, > when the writer exits. > >This problem causes recent versions of rsync, when they are compiled >to use socketpairs (which is the default), to report a bogus "read >error: connection reset by peer" at the end of every rsync, even when >it in fact copied everything successfully. I'm going to submit a >patch to the rsync maintainers suggesting that they work around this >problem by calling shutdown() before exiting. > > jik > > ************************* > >#include >#include >#include >#include >#include > >main() >{ > int pipefds[2]; > int readfd, writefd; > char inbuf[4]; > char outbuf[4] = "foo"; > int pid; > fd_set readfds, exceptfds; > > socketpair(AF_UNIX, SOCK_STREAM, 0, pipefds); > /* pipe(pipefds); */ > > readfd = pipefds[0]; > writefd = pipefds[1]; > > if (pid = fork()) { > fprintf(stderr, "PARENT: close(writefd)\n"); > close(writefd); > > FD_ZERO(&readfds); > FD_SET(readfd, &readfds); > exceptfds = readfds; > > fprintf(stderr, "PARENT: selecting\n"); > if (select(readfd + 1, &readfds, NULL, &exceptfds, NULL) <= 0) { > perror("PARENT: select"); > exit(1); > } > > if (FD_ISSET(readfd, &exceptfds)) { > fprintf(stderr, "PARENT: exception is set\n"); > } > > if (FD_ISSET(readfd, &readfds)) { > fprintf(stderr, "PARENT: read is set\n"); > } > > fprintf(stderr, "PARENT: reading\n"); > if (read(readfd, inbuf, sizeof(inbuf)) != sizeof(inbuf)) { > perror("PARENT: read"); > exit(1); > } > > printf("PARENT: %s (exiting)\n", inbuf); > exit(0); > } > else { > fprintf(stderr, "CHILD: close(readfd)\n"); > close(readfd); > > fprintf(stderr, "CHILD: writing\n"); > if (write(writefd, outbuf, sizeof(outbuf)) != sizeof(outbuf)) { > perror("CHILD: write"); > exit(1); > } >#ifdef USE_SHUTDOWN > shutdown(writefd, 2); >#endif >#ifdef USE_CLOSE > close(writefd); >#endif > > fprintf(stderr, "CHILD: exiting\n"); > exit(0); > } >} > >-- >Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple >Bug reporting: http://cygwin.com/bugs.html >Documentation: http://cygwin.com/docs.html >FAQ: http://cygwin.com/faq/ -- cgf AT cygnus DOT com Red Hat, Inc. http://sources.redhat.com/ http://www.redhat.com/ -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Bug reporting: http://cygwin.com/bugs.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/