Suppress SIGPIPE signals on write.
GitOrigin-RevId: 19ff2a079a4dc69535e34282bfb2c2f381856def
This commit is contained in:
parent
5fc7a7727e
commit
fc5bf9ef06
@ -384,17 +384,37 @@ class SocketFdImpl {
|
|||||||
const NativeFd &get_native_fd() const {
|
const NativeFd &get_native_fd() const {
|
||||||
return info.native_fd();
|
return info.native_fd();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<size_t> writev(Span<IoSlice> slices) {
|
Result<size_t> writev(Span<IoSlice> slices) {
|
||||||
int native_fd = get_native_fd().socket();
|
int native_fd = get_native_fd().socket();
|
||||||
auto write_res =
|
TRY_RESULT(slices_size, narrow_cast_safe<int>(slices.size()));
|
||||||
detail::skip_eintr([&] { return ::writev(native_fd, slices.begin(), narrow_cast<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);
|
return write_finish(write_res);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<size_t> write(Slice slice) {
|
Result<size_t> write(Slice slice) {
|
||||||
int native_fd = get_native_fd().socket();
|
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);
|
return write_finish(write_res);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<size_t> write_finish(ssize_t write_res) {
|
Result<size_t> write_finish(ssize_t write_res) {
|
||||||
auto write_errno = errno;
|
auto write_errno = errno;
|
||||||
if (write_res >= 0) {
|
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_REUSEADDR, reinterpret_cast<const char *>(&flags), sizeof(flags));
|
||||||
setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, 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));
|
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
|
// TODO: SO_REUSEADDR, SO_KEEPALIVE, TCP_NODELAY, SO_SNDBUF, SO_RCVBUF, TCP_QUICKACK, SO_LINGER
|
||||||
|
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
|
@ -67,7 +67,7 @@ void EventFdLinux::release() {
|
|||||||
auto native_fd = impl_->info.native_fd().fd();
|
auto native_fd = impl_->info.native_fd().fd();
|
||||||
|
|
||||||
auto result = [&]() -> Result<size_t> {
|
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;
|
auto write_errno = errno;
|
||||||
if (write_res >= 0) {
|
if (write_res >= 0) {
|
||||||
return narrow_cast<size_t>(write_res);
|
return narrow_cast<size_t>(write_res);
|
||||||
|
Loading…
Reference in New Issue
Block a user