Sway IPC: avoid reinterpret_cast
This commit is contained in:
@@ -11,6 +11,7 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <limits>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@@ -135,14 +136,18 @@ struct Ipc::ipc_response Ipc::recv(int fd) {
|
|||||||
throw std::runtime_error("Invalid IPC magic");
|
throw std::runtime_error("Invalid IPC magic");
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto* data32 = reinterpret_cast<uint32_t*>(header.data() + ipc_magic_.size());
|
uint32_t payload_size = 0;
|
||||||
|
uint32_t payload_type = 0;
|
||||||
|
memcpy(&payload_size, header.data() + ipc_magic_.size(), sizeof payload_size);
|
||||||
|
memcpy(&payload_type, header.data() + ipc_magic_.size() + sizeof payload_size,
|
||||||
|
sizeof payload_type);
|
||||||
|
|
||||||
std::string payload;
|
std::string payload;
|
||||||
payload.resize(data32[0]);
|
payload.resize(payload_size);
|
||||||
|
|
||||||
total = 0;
|
total = 0;
|
||||||
while (total < data32[0]) {
|
while (total < payload_size) {
|
||||||
const ssize_t res = ::recv(fd, payload.data() + total, data32[0] - total, 0);
|
const ssize_t res = ::recv(fd, payload.data() + total, payload_size - total, 0);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
if (errno == EINTR || errno == EAGAIN) {
|
if (errno == EINTR || errno == EAGAIN) {
|
||||||
continue;
|
continue;
|
||||||
@@ -155,16 +160,19 @@ struct Ipc::ipc_response Ipc::recv(int fd) {
|
|||||||
total += static_cast<size_t>(res);
|
total += static_cast<size_t>(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {.size = data32[0], .type = data32[1], .payload = std::move(payload)};
|
return {.size = payload_size, .type = payload_type, .payload = std::move(payload)};
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Ipc::ipc_response Ipc::send(int fd, uint32_t type, const std::string& payload) {
|
struct Ipc::ipc_response Ipc::send(int fd, uint32_t type, const std::string& payload) {
|
||||||
std::string header;
|
std::string header;
|
||||||
header.resize(ipc_header_size_);
|
header.resize(ipc_header_size_);
|
||||||
memcpy(header.data(), ipc_magic_.data(), ipc_magic_.size());
|
memcpy(header.data(), ipc_magic_.data(), ipc_magic_.size());
|
||||||
auto* data32 = reinterpret_cast<uint32_t*>(header.data() + ipc_magic_.size());
|
if (payload.size() > std::numeric_limits<uint32_t>::max()) {
|
||||||
data32[0] = payload.size();
|
throw std::runtime_error("IPC payload is too large");
|
||||||
data32[1] = type;
|
}
|
||||||
|
const auto payload_size = static_cast<uint32_t>(payload.size());
|
||||||
|
memcpy(header.data() + ipc_magic_.size(), &payload_size, sizeof payload_size);
|
||||||
|
memcpy(header.data() + ipc_magic_.size() + sizeof payload_size, &type, sizeof type);
|
||||||
|
|
||||||
sendAll(fd, header.data(), ipc_header_size_, "Unable to send IPC header");
|
sendAll(fd, header.data(), ipc_header_size_, "Unable to send IPC header");
|
||||||
sendAll(fd, payload.data(), payload.size(), "Unable to send IPC payload");
|
sendAll(fd, payload.data(), payload.size(), "Unable to send IPC payload");
|
||||||
|
|||||||
Reference in New Issue
Block a user