text: This is the mail archive of the cygwin@cygwin.com mailing list for the Cygwin project.
  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 <unistd.h> > >>#include <stdio.h> > >>#include <sys/types.h> > >>#include <signal.h> > >>#include <sys/socket.h> > >> > >>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: > Bug reporting: > Documentation: > FAQ: -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Developer mailto:cygwin@cygwin.com Red Hat, Inc. -- Unsubscribe info: Bug reporting: Documentation: FAQ: