ECONNRESET,EPIPE on read() and shutdown() are now errors
diff --git a/CHANGES b/CHANGES
index b74f66b..6cbac90 100644
--- a/CHANGES
+++ b/CHANGES
@@ -67,6 +67,18 @@
Better formatted help output; address keywords in help output are now
printed in uppercase.
+ In previous Socat versions errors EPIPE and ECONNRESET on read() were
+ handled at warning level, thus not automatically leading to termination
+ with exit code 1. Beginning with this release these conditions are
+ handled as errors with termination and exit code 1 to not pretend
+ success on possible data loss.
+ Problem reported by Scott Burkett.
+
+ In previous Socat versions errors on shutdown() were ignored (info
+ level).
+ Now Socat handles EPIPE and ECONNRESET as error to indicate possible
+ failure of data transfer.
+
Coding:
Introduced groups_t instead of uint32_t, for more flexibility.
diff --git a/doc/socat.yo b/doc/socat.yo
index c55d170..d206051 100644
--- a/doc/socat.yo
+++ b/doc/socat.yo
@@ -789,8 +789,7 @@
link(sctp-nodelay)(OPTION_SCTP_NODELAY),
link(su)(OPTION_SUBSTUSER),
link(reuseaddr)(OPTION_REUSEADDR),
- link(retry)(OPTION_RETRY),
- link(cool-write)(OPTION_COOL_WRITE)nl()
+ link(retry)(OPTION_RETRY)nl()
See also:
link(SCTP4-LISTEN)(ADDRESS_SCTP4_LISTEN),
link(SCTP6-LISTEN)(ADDRESS_SCTP6_LISTEN),
@@ -1415,8 +1414,7 @@
link(backlog)(OPTION_BACKLOG),
link(su)(OPTION_SUBSTUSER),
link(reuseaddr)(OPTION_REUSEADDR),
- link(retry)(OPTION_RETRY),
- link(cool-write)(OPTION_COOL_WRITE)nl()
+ link(retry)(OPTION_RETRY)nl()
See also:
link(VSOCK-CONNECT)(ADDRESS_VSOCK_CONNECT)
@@ -1626,9 +1624,10 @@
Takes it easy when write fails with EPIPE or ECONNRESET and logs the message
with em(notice) level instead of em(error).
This prevents the log file from being filled with useless error messages
- when socat is used as a high volume server or proxy where clients often
- abort the connection.nl()
- This option is experimental.
+ when socat() is used as a high volume server or proxy where clients often
+ abort the connection. Use this option only with option
+ link(fork)(OPTION_FORK) because otherwise it might cause socat() to exit
+ with code 0 even on failure.nl()
label(OPTION_END_CLOSE)dit(bf(tt(end-close[=<bool>])))
Changes the (address dependent) method of ending a connection to just close
the file descriptors. This is useful when the connection is to be reused by
diff --git a/xioread.c b/xioread.c
index 857d679..b5ec837 100644
--- a/xioread.c
+++ b/xioread.c
@@ -59,12 +59,9 @@
if (bytes < 0) {
_errno = errno;
switch (_errno) {
-#if 1
- case EPIPE: case ECONNRESET:
- Warn4("read(%d, %p, "F_Zu"): %s",
- pipe->fd, buff, bufsiz, strerror(_errno));
- break;
-#endif
+ case EPIPE:
+ case ECONNRESET:
+ /*PASSTHROUGH*/
default:
Error4("read(%d, %p, "F_Zu"): %s",
pipe->fd, buff, bufsiz, strerror(_errno));
diff --git a/xioshutdown.c b/xioshutdown.c
index 4fe51a0..2175916 100644
--- a/xioshutdown.c
+++ b/xioshutdown.c
@@ -52,9 +52,22 @@
}
return 0;
case XIOSHUT_DOWN:
- if ((result = Shutdown(sock->stream.fd, how)) < 0) {
- Info3("shutdown(%d, %d): %s",
- sock->stream.fd, how, strerror(errno));
+ result = Shutdown(sock->stream.fd, how);
+ if (result < 0) {
+ int level, _errno = errno;
+ switch (_errno) {
+ case EPIPE:
+ case ECONNRESET:
+ level = E_ERROR;
+ break;
+ default:
+ level = E_INFO; /* old behaviour */
+ break;
+ }
+ Msg3(level, "shutdown(%d, %d): %s",
+ sock->stream.fd, how, strerror(_errno));
+ errno = _errno;
+ return -1;
}
return 0;
#if _WITH_SOCKET