From 9f639210ca71c548b76d311d826899ed36f98372 Mon Sep 17 00:00:00 2001 From: David Dykstra Date: Mon, 27 Jan 2003 03:35:08 +0000 Subject: Prevent the "Connection reset by peer" messages often seen from Cygwin. Result of a lot of discussion over the last year and a half. Based on a patch from Randy O'Meara, cleaned up a bit by Max Bowsher. --- NEWS | 2 ++ cleanup.c | 27 +++++++++++++++++++++++++++ configure.in | 8 ++++++++ socket.c | 5 ++++- 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 578860be..47433c67 100644 --- a/NEWS +++ b/NEWS @@ -73,6 +73,8 @@ rsync changes since last release * Fixed a bug that prevented rsync from creating intervening directories when --relative-paths/-R is set. (Craig Barratt) + * Prevent "Connection reset by peer" messages from Cygwin. (Randy O'Meara) + INTERNAL: * Many code cleanups and improved internal documentation. (Martin diff --git a/cleanup.c b/cleanup.c index 8543217d..2a850832 100644 --- a/cleanup.c +++ b/cleanup.c @@ -21,6 +21,32 @@ #include "rsync.h" +/** + * Close all open sockets and files, allowing a (somewhat) graceful + * shutdown() of socket connections. This eliminates the abortive + * TCP RST sent by a Winsock-based system when the close() occurs. + **/ +void close_all() +{ +#ifdef SHUTDOWN_ALL_SOCKETS + int max_fd; + int fd; + int ret; + struct stat st; + + max_fd = sysconf(_SC_OPEN_MAX) - 1; + for (fd = max_fd; fd >= 0; fd--) { + ret = fstat(fd,&st); + if (fstat(fd,&st) == 0) { + if (is_a_socket(fd)) { + ret = shutdown(fd, 2); + } + ret = close(fd); + } + } +#endif +} + /** * @file cleanup.c * @@ -115,6 +141,7 @@ void _exit_cleanup(int code, const char *file, int line) rprintf(FINFO,"_exit_cleanup(code=%d, file=%s, line=%d): about to call exit(%d)\n", ocode, file, line, code); + close_all(); exit(code); } diff --git a/configure.in b/configure.in index 31fd57d2..843fe60b 100644 --- a/configure.in +++ b/configure.in @@ -256,6 +256,14 @@ AC_MSG_RESULT($DEFAULT_MODIFY_WINDOW) AC_DEFINE_UNQUOTED(DEFAULT_MODIFY_WINDOW, $DEFAULT_MODIFY_WINDOW, [Set to the default value for the --modify-window option]) +AC_MSG_CHECKING([whether to call shutdown on all sockets]) +case $host_os in + *cygwin* ) AC_MSG_RESULT(yes) + AC_DEFINE(SHUTDOWN_ALL_SOCKETS, 1, [Define if sockets need to be shutdown]) + ;; + * ) AC_MSG_RESULT(no);; +esac + AC_C_BIGENDIAN AC_HEADER_DIRENT AC_HEADER_TIME diff --git a/socket.c b/socket.c index fa8e4572..eb0660bb 100644 --- a/socket.c +++ b/socket.c @@ -429,11 +429,14 @@ void start_accept_loop(int port, int (*fn)(int, int)) #endif if ((pid = fork()) == 0) { + int ret; close(s); /* open log file in child before possibly giving up privileges */ log_open(); - _exit(fn(fd, fd)); + ret = fn(fd, fd); + close_all(); + _exit(ret); } else if (pid < 0) { rprintf(FERROR, RSYNC_NAME -- cgit v1.2.1