diff --git a/tdutils/td/utils/port/SocketFd.cpp b/tdutils/td/utils/port/SocketFd.cpp index 3b0bcba08..feab6676d 100644 --- a/tdutils/td/utils/port/SocketFd.cpp +++ b/tdutils/td/utils/port/SocketFd.cpp @@ -384,17 +384,37 @@ class SocketFdImpl { const NativeFd &get_native_fd() const { return info.native_fd(); } + Result writev(Span slices) { int native_fd = get_native_fd().socket(); - auto write_res = - detail::skip_eintr([&] { return ::writev(native_fd, slices.begin(), narrow_cast(slices.size())); }); + TRY_RESULT(slices_size, narrow_cast_safe(slices.size())); + auto write_res = detail::skip_eintr([&] { +#ifdef MSG_NOSIGNAL + msghdr msg; + memset(&msg, 0, sizeof(msg)); + msg.msg_iov = const_cast(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 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 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(&flags), sizeof(flags)); setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, reinterpret_cast(&flags), sizeof(flags)); setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast(&flags), sizeof(flags)); +#if TD_PORT_POSIX +#ifndef MSG_NOSIGNAL // Darwin + +#ifdef SO_NOSIGPIPE + setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, reinterpret_cast(&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(); diff --git a/tdutils/td/utils/port/detail/EventFdLinux.cpp b/tdutils/td/utils/port/detail/EventFdLinux.cpp index 8de405592..04521fc0b 100644 --- a/tdutils/td/utils/port/detail/EventFdLinux.cpp +++ b/tdutils/td/utils/port/detail/EventFdLinux.cpp @@ -67,7 +67,7 @@ void EventFdLinux::release() { auto native_fd = impl_->info.native_fd().fd(); auto result = [&]() -> Result { - 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(write_res);