summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Dykstra <dwd@samba.org>2003-01-27 03:35:08 +0000
committerDavid Dykstra <dwd@samba.org>2003-01-27 03:35:08 +0000
commit9f639210ca71c548b76d311d826899ed36f98372 (patch)
tree93d3d0d66c28388a51d69c7eae39303adfb55236
parentdeec574421aea793cc2093e676adc798989181fa (diff)
downloadrsync-9f639210ca71c548b76d311d826899ed36f98372.tar.gz
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.
-rw-r--r--NEWS2
-rw-r--r--cleanup.c27
-rw-r--r--configure.in8
-rw-r--r--socket.c5
4 files changed, 41 insertions, 1 deletions
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
@@ -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
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