diff options
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | cleanup.c | 27 | ||||
-rw-r--r-- | configure.in | 8 | ||||
-rw-r--r-- | socket.c | 5 |
4 files changed, 41 insertions, 1 deletions
@@ -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 @@ -22,6 +22,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 * * Code for handling interrupted transfers. Depending on the @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 @@ -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 |