Suppress SIGPIPE signals on write.

GitOrigin-RevId: 19ff2a079a4dc69535e34282bfb2c2f381856def
This commit is contained in:
levlam 2020-10-18 18:12:32 +03:00
parent 5fc7a7727e
commit fc5bf9ef06
2 changed files with 35 additions and 4 deletions

View File

@ -384,17 +384,37 @@ class SocketFdImpl {
const NativeFd &get_native_fd() const {
return info.native_fd();
}
Result<size_t> writev(Span<IoSlice> slices) {
int native_fd = get_native_fd().socket();
auto write_res =
detail::skip_eintr([&] { return ::writev(native_fd, slices.begin(), narrow_cast<int>(slices.size())); });
TRY_RESULT(slices_size, narrow_cast_safe<int>(slices.size()));
auto write_res = detail::skip_eintr([&] {
#ifdef MSG_NOSIGNAL
msghdr msg;
memset(&msg, 0, sizeof(msg));
msg.msg_iov = const_cast<iovec *>(slices.begin());
msg.msg_iovlen = slices_size;
return sendmsg(native_fd, &msg, MSG_NOSIGNAL);
#else
return ::writev(native_fd, slices.begin(), slices_size);
#endif
});
return write_finish(write_res);
}
Result<size_t> write(Slice slice) {
int native_fd = get_native_fd().socket();
auto write_res = detail::skip_eintr([&] { return ::write(native_fd, slice.begin(), slice.size()); });
auto write_res = detail::skip_eintr([&] {
return
#ifdef MSG_NOSIGNAL
send(native_fd, slice.begin(), slice.size(), MSG_NOSIGNAL);
#else
::write(native_fd, slice.begin(), slice.size());
#endif
});
return write_finish(write_res);
}
Result<size_t> write_finish(ssize_t write_res) {
auto write_errno = errno;
if (write_res >= 0) {
@ -538,6 +558,17 @@ Status init_socket_options(NativeFd &native_fd) {
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<const char *>(&flags), sizeof(flags));
setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, reinterpret_cast<const char *>(&flags), sizeof(flags));
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<const char *>(&flags), sizeof(flags));
#if TD_PORT_POSIX
#ifndef MSG_NOSIGNAL // Darwin
#ifdef SO_NOSIGPIPE
setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, reinterpret_cast<const char *>(&flags), sizeof(flags));
#else
#warning "Failed to suppress SIGPIPE signals. Use signal(SIGPIPE, SIG_IGN) to suppress them."
#endif
#endif
#endif
// TODO: SO_REUSEADDR, SO_KEEPALIVE, TCP_NODELAY, SO_SNDBUF, SO_RCVBUF, TCP_QUICKACK, SO_LINGER
return Status::OK();

View File

@ -67,7 +67,7 @@ void EventFdLinux::release() {
auto native_fd = impl_->info.native_fd().fd();
auto result = [&]() -> Result<size_t> {
auto write_res = detail::skip_eintr([&] { return ::write(native_fd, slice.begin(), slice.size()); });
auto write_res = detail::skip_eintr([&] { return write(native_fd, slice.begin(), slice.size()); });
auto write_errno = errno;
if (write_res >= 0) {
return narrow_cast<size_t>(write_res);