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: Wed, 8 Aug 2001 09:03:06 +0200 From: Corinna Vinschen To: cygwin AT cygwin DOT com Subject: Re: data in socketpair() channel lost if writer closes or exits without shutting down Message-ID: <20010808090306.G28586@cygbert.vinschen.de> Mail-Followup-To: cygwin AT cygwin DOT com References: <20010713181435 DOT 3695 DOT qmail AT lizard DOT curl DOT com> <20010713202146 DOT B11377 AT redhat DOT com> <20010807150603 DOT B30140 AT redhat DOT com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <20010807150603.B30140@redhat.com>; from cgf@redhat.com on Tue, Aug 07, 2001 at 03:06:03PM -0400 On Tue, Aug 07, 2001 at 03:06:03PM -0400, Christopher Faylor wrote: > I'm getting ready to make a new release. Was there ever any movement > on a fix for this? No, I'm afraid. Corinna > > cgf > > On Fri, Jul 13, 2001 at 08:21:46PM -0400, Christopher Faylor wrote: > >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/ -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Developer mailto:cygwin AT cygwin DOT com Red Hat, Inc. -- 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/