tcp_socket: send() with MSG_NOSIGNAL
I don't want to crash when a send fails.
Bug: 120027270
Test: run vnc_server on pie
Change-Id: I09758f33a191ff74156e038575af4bb736be073d
diff --git a/common/libs/tcp_socket/tcp_socket.cpp b/common/libs/tcp_socket/tcp_socket.cpp
index 0c152eb..64da7d7 100644
--- a/common/libs/tcp_socket/tcp_socket.cpp
+++ b/common/libs/tcp_socket/tcp_socket.cpp
@@ -66,14 +66,14 @@
return buf;
}
-ssize_t ClientSocket::Send(const uint8_t* data, std::size_t size) {
+ssize_t ClientSocket::SendNoSignal(const uint8_t* data, std::size_t size) {
std::lock_guard<std::mutex> lock(send_lock_);
ssize_t written{};
while (written < static_cast<ssize_t>(size)) {
if (!fd_->IsOpen()) {
LOG(ERROR) << "fd_ is closed";
}
- auto just_written = fd_->Write(data + written, size - written);
+ auto just_written = fd_->Send(data + written, size - written, MSG_NOSIGNAL);
if (just_written <= 0) {
LOG(INFO) << "Couldn't write to client: " << strerror(errno);
{
@@ -87,8 +87,8 @@
return written;
}
-ssize_t ClientSocket::Send(const Message& message) {
- return Send(&message[0], message.size());
+ssize_t ClientSocket::SendNoSignal(const Message& message) {
+ return SendNoSignal(&message[0], message.size());
}
ServerSocket::ServerSocket(int port)
diff --git a/common/libs/tcp_socket/tcp_socket.h b/common/libs/tcp_socket/tcp_socket.h
index dc78c94..e484f48 100644
--- a/common/libs/tcp_socket/tcp_socket.h
+++ b/common/libs/tcp_socket/tcp_socket.h
@@ -50,12 +50,13 @@
// RecvAny will receive whatever is available.
// An empty message returned indicates error or close.
Message RecvAny(std::size_t length);
- ssize_t Send(const std::uint8_t* data, std::size_t size);
- ssize_t Send(const Message& message);
+ // Sends are called with MSG_NOSIGNAL to suppress SIGPIPE
+ ssize_t SendNoSignal(const std::uint8_t* data, std::size_t size);
+ ssize_t SendNoSignal(const Message& message);
template <std::size_t N>
- ssize_t Send(const std::uint8_t (&data)[N]) {
- return Send(data, N);
+ ssize_t SendNoSignal(const std::uint8_t (&data)[N]) {
+ return SendNoSignal(data, N);
}
bool closed() const;
diff --git a/host/frontend/vnc_server/vnc_client_connection.cpp b/host/frontend/vnc_server/vnc_client_connection.cpp
index 98920ac..9bed6ff 100644
--- a/host/frontend/vnc_server/vnc_client_connection.cpp
+++ b/host/frontend/vnc_server/vnc_client_connection.cpp
@@ -184,7 +184,8 @@
void VncClientConnection::SetupProtocol() {
static constexpr char kRFBVersion[] = "RFB 003.008\n";
static constexpr auto kVersionLen = (sizeof kRFBVersion) - 1;
- client_.Send(reinterpret_cast<const std::uint8_t*>(kRFBVersion), kVersionLen);
+ client_.SendNoSignal(reinterpret_cast<const std::uint8_t*>(kRFBVersion),
+ kVersionLen);
auto client_protocol = client_.Recv(kVersionLen);
if (std::memcmp(&client_protocol[0], kRFBVersion,
std::min(kVersionLen, client_protocol.size())) != 0) {
@@ -198,7 +199,7 @@
static constexpr std::uint8_t kNoneSecurity = 0x1;
// The first '0x1' indicates the number of items that follow
static constexpr std::uint8_t kOnlyNoneSecurity[] = {0x01, kNoneSecurity};
- client_.Send(kOnlyNoneSecurity);
+ client_.SendNoSignal(kOnlyNoneSecurity);
auto client_security = client_.Recv(1);
if (client_.closed()) {
return;
@@ -208,7 +209,7 @@
<< static_cast<int>(client_security.front());
}
static constexpr std::uint8_t kZero[4] = {};
- client_.Send(kZero);
+ client_.SendNoSignal(kZero);
}
void VncClientConnection::GetClientInit() {
@@ -227,7 +228,7 @@
pixel_format_.blue_shift, std::uint16_t{}, // padding
std::uint8_t{}, // padding
static_cast<std::uint32_t>(server_name.size()), server_name);
- client_.Send(server_init);
+ client_.SendNoSignal(server_init);
}
Message VncClientConnection::MakeFrameBufferUpdateHeader(
@@ -361,7 +362,7 @@
? "portrait"
: "landscape")
<< " mode";
- client_.Send(MakeFrameBufferUpdate(stripes));
+ client_.SendNoSignal(MakeFrameBufferUpdate(stripes));
}
if (aggressive) {
bb_->FrameBufferUpdateRequestReceived(this);
@@ -371,13 +372,13 @@
void VncClientConnection::SendDesktopSizeUpdate() {
static constexpr int32_t kDesktopSizeEncoding = -223;
- client_.Send(cvd::CreateMessage(std::uint8_t{0}, // message-type,
- std::uint8_t{}, // padding
- std::uint16_t{1}, // one pseudo rectangle
- std::uint16_t{0}, std::uint16_t{0},
- static_cast<std::uint16_t>(ScreenWidth()),
- static_cast<std::uint16_t>(ScreenHeight()),
- kDesktopSizeEncoding));
+ client_.SendNoSignal(cvd::CreateMessage(
+ std::uint8_t{0}, // message-type,
+ std::uint8_t{}, // padding
+ std::uint16_t{1}, // one pseudo rectangle
+ std::uint16_t{0}, std::uint16_t{0},
+ static_cast<std::uint16_t>(ScreenWidth()),
+ static_cast<std::uint16_t>(ScreenHeight()), kDesktopSizeEncoding));
}
bool VncClientConnection::IsUrgent(