Commit cc825f70 authored by Dominik Charousset's avatar Dominik Charousset

Suppress SIGPIPE events on all sockets

parent 3e51f9b8
......@@ -140,19 +140,22 @@ using native_socket_acceptor = native_socket;
/// Returns the last socket error as human-readable string.
std::string last_socket_error_as_string();
/// Creates two connected sockets. The former is the read handle
/// and the latter is the write handle.
std::pair<native_socket, native_socket> create_pipe();
/// Sets fd to nonblocking if `set_nonblocking == true`
/// or to blocking if `set_nonblocking == false`
/// throws `network_error` on error
void nonblocking(native_socket fd, bool new_value);
/// Creates two connected sockets. The former is the read handle
/// and the latter is the write handle.
std::pair<native_socket, native_socket> create_pipe();
/// Returns true if `fd` is configured as nodelay socket.
/// Enables or disables Nagle's algorithm on `fd`.
/// @throws network_error
void tcp_nodelay(native_socket fd, bool new_value);
/// Enables or disables `SIGPIPE` events from `fd`.
void allow_sigpipe(native_socket fs, bool new_value);
/// Throws `network_error` if `result` is invalid.
void handle_write_result(ssize_t result);
......
......@@ -50,14 +50,6 @@ using std::string;
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
constexpr auto ipv4 = caf::io::network::protocol::ipv4;
constexpr auto ipv6 = caf::io::network::protocol::ipv6;
......@@ -125,6 +117,11 @@ uint16_t port_of_fd(native_socket fd);
ccall(cc_not_minus1, "cannot set flags", fcntl, fd, F_SETFL, wf);
}
void allow_sigpipe(native_socket fd, bool new_value) {
int value = new_value ? 0 : 1;
setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &value, sizeof(value));
}
std::pair<native_socket, native_socket> create_pipe() {
int pipefds[2];
if (pipe(pipefds) != 0) {
......@@ -165,6 +162,10 @@ uint16_t port_of_fd(native_socket fd);
ccall(cc_zero, "unable to set FIONBIO", ioctlsocket, fd, FIONBIO, &mode);
}
void allow_sigpipe(native_socket, bool) {
// nop; SIGPIPE does not exist on Windows
}
/**************************************************************************\
* Based on work of others; *
* original header: *
......@@ -590,7 +591,7 @@ void default_multiplexer::wr_dispatch_request(runnable* ptr) {
// on windows, we actually have sockets, otherwise we have file handles
# ifdef CAF_WINDOWS
auto res = ::send(pipe_.second, reinterpret_cast<socket_send_ptr>(&ptrval),
sizeof(ptrval), no_sigpipe_flag);
sizeof(ptrval), 0);
# else
auto res = ::write(pipe_.second, &ptrval, sizeof(ptrval));
# endif
......@@ -847,7 +848,8 @@ default_multiplexer::new_tcp_doorman(uint16_t port, const char* in,
res.second};
}
void default_multiplexer::assign_tcp_doorman(abstract_broker* ptr, accept_handle hdl) {
void default_multiplexer::assign_tcp_doorman(abstract_broker* ptr,
accept_handle hdl) {
add_tcp_doorman(ptr, static_cast<native_socket>(hdl.id()));
}
......@@ -903,8 +905,7 @@ bool read_some(size_t& result, native_socket fd, void* buf, size_t len) {
bool write_some(size_t& result, native_socket fd, const void* buf, size_t len) {
CAF_LOGF_TRACE(CAF_ARG(fd) << ", " << CAF_ARG(len));
auto sres = ::send(fd, reinterpret_cast<socket_send_ptr>(buf),
len, no_sigpipe_flag);
auto sres = ::send(fd, reinterpret_cast<socket_send_ptr>(buf), len, 0);
CAF_LOGF_DEBUG("tried to write " << len << " bytes to socket " << fd
<< ", send returned " << sres);
if (is_error(sres, true))
......@@ -945,9 +946,10 @@ default_socket::default_socket(default_multiplexer& ref, native_socket sockfd)
fd_(sockfd) {
CAF_LOG_TRACE(CAF_ARG(sockfd));
if (sockfd != invalid_native_socket) {
// enable nonblocking IO & disable Nagle's algorithm
// enable nonblocking IO, disable Nagle's algorithm, and suppress SIGPIPE
nonblocking(fd_, true);
tcp_nodelay(fd_, true);
allow_sigpipe(fd_, false);
}
}
......
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