diff options
-rw-r--r-- | configure.ac | 19 | ||||
-rw-r--r-- | src/Socket.h | 22 |
2 files changed, 38 insertions, 3 deletions
diff --git a/configure.ac b/configure.ac index 261d444..9adb831 100644 --- a/configure.ac +++ b/configure.ac @@ -185,6 +185,25 @@ AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([[ AC_DEFINE(HAVE_PRCTL, 1, [Define this symbol if you have prctl and PR_SET_NAME]) ], [ AC_MSG_RESULT(no) ]) +# Linux defines MSG_NOSIGNAL, some other systems have SO_NOSIGPIPE instead +AC_MSG_CHECKING(for MSG_NOSIGNAL) +AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([[ + #include <sys/socket.h> + int f = MSG_NOSIGNAL; + ]])], + [ AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_MSG_NOSIGNAL, 1, [Define this symbol if you have MSG_NOSIGNAL]) ], + [ AC_MSG_RESULT(no) ]) + +AC_MSG_CHECKING(for SO_NOSIGPIPE) +AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([[ + #include <sys/socket.h> + int f = SO_NOSIGPIPE; + ]])], + [ AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SO_NOSIGPIPE, 1, [Define this symbol if you have SO_NOSIGPIPE]) ], + [ AC_MSG_RESULT(no) ]) + # Check for march AS_IF([test "x$enable_native" = "xyes"], [AC_MSG_CHECKING(if we can add -march=native to CFLAGS) diff --git a/src/Socket.h b/src/Socket.h index 39554ca..5145103 100644 --- a/src/Socket.h +++ b/src/Socket.h @@ -49,6 +49,14 @@ class TCPSocket { if ((m_sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { throw std::runtime_error("Can't create TCP socket"); } + +#if defined(HAVE_SO_NOSIGPIPE) + int val = 1; + if (setsockopt(m_sock, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof(val)) + == SOCKET_ERROR) { + throw std::runtime_error("Can't set SO_NOSIGPIPE"); + } +#endif } ~TCPSocket() { @@ -93,7 +101,7 @@ class TCPSocket { throw std::runtime_error("Can't reuse address for TCP socket"); } - if (bind(m_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) { + if (::bind(m_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) { close(); throw std::runtime_error("Can't bind TCP socket"); } @@ -138,8 +146,16 @@ class TCPSocket { { uint8_t *buf = (uint8_t*)buffer; while (buflen > 0) { - // Set MSG_NOSIGNAL to avoid that this thread gets a SIGPIPE - ssize_t sent = send(m_sock, buf, buflen, MSG_NOSIGNAL); + /* On Linux, the MSG_NOSIGNAL flag ensures that the process + * would not receive a SIGPIPE and die. + * Other systems have SO_NOSIGPIPE set on the socket for the + * same effect. */ +#if defined(HAVE_MSG_NOSIGNAL) + const int flags = MSG_NOSIGNAL; +#else + const int flags = 0; +#endif + ssize_t sent = ::send(m_sock, buf, buflen, flags); if (sent < 0) { return -1; } |