Commit 894eaf53 authored by Dominik Charousset's avatar Dominik Charousset

Move sigpipe flag setup to header

parent 35742367
...@@ -116,6 +116,21 @@ namespace network { ...@@ -116,6 +116,21 @@ namespace network {
constexpr int ec_interrupted_syscall = EINTR; constexpr int ec_interrupted_syscall = EINTR;
#endif #endif
// platform-dependent SIGPIPE setup
#if defined(CAF_MACOS) || defined(CAF_IOS) || defined(CAF_BSD)
// Use the socket option but no flags to recv/send on macOS/iOS/BSD.
constexpr int no_sigpipe_socket_flag = SO_NOSIGPIPE;
constexpr int no_sigpipe_io_flag = 0;
#elif defined(CAF_WINDOWS)
// Do nothing on Windows (SIGPIPE does not exist).
constexpr int no_sigpipe_socket_flag = 0;
constexpr int no_sigpipe_io_flag = 0;
#else
// Use flags to recv/send on Linux/Android but no socket option.
constexpr int no_sigpipe_socket_flag = 0;
constexpr int no_sigpipe_io_flag = MSG_NOSIGNAL;
#endif
// poll vs epoll backend // poll vs epoll backend
#if !defined(CAF_LINUX) || defined(CAF_POLL_IMPL) // poll() multiplexer #if !defined(CAF_LINUX) || defined(CAF_POLL_IMPL) // poll() multiplexer
# ifdef CAF_WINDOWS # ifdef CAF_WINDOWS
...@@ -171,6 +186,9 @@ enum class rw_state { ...@@ -171,6 +186,9 @@ enum class rw_state {
indeterminate indeterminate
}; };
/// Convenience functions for checking the result of `recv` or `send`.
bool is_error(ssize_t res, bool is_nonblock);
/// Reads up to `len` bytes from `fd,` writing the received data /// Reads up to `len` bytes from `fd,` writing the received data
/// to `buf`. Returns `true` as long as `fd` is readable and `false` /// to `buf`. Returns `true` as long as `fd` is readable and `false`
/// if the socket has been closed or an IO error occured. The number /// if the socket has been closed or an IO error occured. The number
......
...@@ -56,14 +56,6 @@ using std::string; ...@@ -56,14 +56,6 @@ using std::string;
namespace { namespace {
#if defined(CAF_MACOS) || defined(CAF_IOS)
constexpr int no_sigpipe_flag = SO_NOSIGPIPE;
#elif defined(CAF_WINDOWS)
constexpr int no_sigpipe_flag = 0; // does not exist on Windows
#else // BSD, Linux or Android
constexpr int no_sigpipe_flag = MSG_NOSIGNAL;
#endif
// safe ourselves some typing // safe ourselves some typing
constexpr auto ipv4 = caf::io::network::protocol::ipv4; constexpr auto ipv4 = caf::io::network::protocol::ipv4;
constexpr auto ipv6 = caf::io::network::protocol::ipv6; constexpr auto ipv6 = caf::io::network::protocol::ipv6;
...@@ -131,16 +123,12 @@ namespace network { ...@@ -131,16 +123,12 @@ namespace network {
} }
expected<void> allow_sigpipe(native_socket fd, bool new_value) { expected<void> allow_sigpipe(native_socket fd, bool new_value) {
# if !defined(CAF_LINUX) && !defined(CAF_CYGWIN) if (no_sigpipe_socket_flag != 0) {
int value = new_value ? 0 : 1; int value = new_value ? 0 : 1;
CALL_CFUN(res, cc_zero, "setsockopt", CALL_CFUN(res, cc_zero, "setsockopt",
setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &value, setsockopt(fd, SOL_SOCKET, no_sigpipe_socket_flag, &value,
static_cast<unsigned>(sizeof(value)))); static_cast<unsigned>(sizeof(value))));
# else }
// SO_NOSIGPIPE does not exist on Linux, suppress unused warnings
static_cast<void>(fd);
static_cast<void>(new_value);
# endif
return unit; return unit;
} }
...@@ -647,7 +635,8 @@ bool is_error(ssize_t res, bool is_nonblock) { ...@@ -647,7 +635,8 @@ bool is_error(ssize_t res, bool is_nonblock) {
rw_state read_some(size_t& result, native_socket fd, void* buf, size_t len) { rw_state read_some(size_t& result, native_socket fd, void* buf, size_t len) {
CAF_LOG_TRACE(CAF_ARG(fd) << CAF_ARG(len)); CAF_LOG_TRACE(CAF_ARG(fd) << CAF_ARG(len));
auto sres = ::recv(fd, reinterpret_cast<socket_recv_ptr>(buf), len, 0); auto sres = ::recv(fd, reinterpret_cast<socket_recv_ptr>(buf),
len, no_sigpipe_io_flag);
CAF_LOG_DEBUG(CAF_ARG(len) << CAF_ARG(fd) << CAF_ARG(sres)); CAF_LOG_DEBUG(CAF_ARG(len) << CAF_ARG(fd) << CAF_ARG(sres));
if (is_error(sres, true) || sres == 0) { if (is_error(sres, true) || sres == 0) {
// recv returns 0 when the peer has performed an orderly shutdown // recv returns 0 when the peer has performed an orderly shutdown
...@@ -661,7 +650,7 @@ rw_state write_some(size_t& result, native_socket fd, const void* buf, ...@@ -661,7 +650,7 @@ rw_state write_some(size_t& result, native_socket fd, const void* buf,
size_t len) { size_t len) {
CAF_LOG_TRACE(CAF_ARG(fd) << CAF_ARG(len)); CAF_LOG_TRACE(CAF_ARG(fd) << CAF_ARG(len));
auto sres = ::send(fd, reinterpret_cast<socket_send_ptr>(buf), auto sres = ::send(fd, reinterpret_cast<socket_send_ptr>(buf),
len, no_sigpipe_flag); len, no_sigpipe_io_flag);
CAF_LOG_DEBUG(CAF_ARG(len) << CAF_ARG(fd) << CAF_ARG(sres)); CAF_LOG_DEBUG(CAF_ARG(len) << CAF_ARG(fd) << CAF_ARG(sres));
if (is_error(sres, true)) if (is_error(sres, true))
return rw_state::failure; return rw_state::failure;
...@@ -727,7 +716,7 @@ void default_multiplexer::wr_dispatch_request(resumable* ptr) { ...@@ -727,7 +716,7 @@ void default_multiplexer::wr_dispatch_request(resumable* ptr) {
// on windows, we actually have sockets, otherwise we have file handles // on windows, we actually have sockets, otherwise we have file handles
# ifdef CAF_WINDOWS # ifdef CAF_WINDOWS
auto res = ::send(pipe_.second, reinterpret_cast<socket_send_ptr>(&ptrval), auto res = ::send(pipe_.second, reinterpret_cast<socket_send_ptr>(&ptrval),
sizeof(ptrval), no_sigpipe_flag); sizeof(ptrval), no_sigpipe_io_flag);
# else # else
auto res = ::write(pipe_.second, &ptrval, sizeof(ptrval)); auto res = ::write(pipe_.second, &ptrval, sizeof(ptrval));
# endif # endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment