unix: use memcpy() instead of type punning (#3990)

Libuv makes no claim to being strict aliasing-clean but type punning
makes me feel unclean so replace it with memcpy().
This commit is contained in:
Ben Noordhuis 2023-05-12 20:12:47 +02:00 committed by GitHub
parent 3990fcad62
commit ff7dcd2654
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -797,13 +797,7 @@ static int uv__try_write(uv_stream_t* stream,
cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS; cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN(sizeof(fd_to_send)); cmsg->cmsg_len = CMSG_LEN(sizeof(fd_to_send));
memcpy(CMSG_DATA(cmsg), &fd_to_send, sizeof(fd_to_send));
/* silence aliasing warning */
{
void* pv = CMSG_DATA(cmsg);
int* pi = pv;
*pi = fd_to_send;
}
do do
n = sendmsg(uv__stream_fd(stream), &msg, 0); n = sendmsg(uv__stream_fd(stream), &msg, 0);
@ -989,46 +983,36 @@ static int uv__stream_queue_fd(uv_stream_t* stream, int fd) {
static int uv__stream_recv_cmsg(uv_stream_t* stream, struct msghdr* msg) { static int uv__stream_recv_cmsg(uv_stream_t* stream, struct msghdr* msg) {
struct cmsghdr* cmsg; struct cmsghdr* cmsg;
int fd;
int err;
size_t i;
size_t count;
for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) { for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) {
char* start;
char* end;
int err;
void* pv;
int* pi;
unsigned int i;
unsigned int count;
if (cmsg->cmsg_type != SCM_RIGHTS) { if (cmsg->cmsg_type != SCM_RIGHTS) {
fprintf(stderr, "ignoring non-SCM_RIGHTS ancillary data: %d\n", fprintf(stderr, "ignoring non-SCM_RIGHTS ancillary data: %d\n",
cmsg->cmsg_type); cmsg->cmsg_type);
continue; continue;
} }
/* silence aliasing warning */ assert(cmsg->cmsg_len >= CMSG_LEN(0));
pv = CMSG_DATA(cmsg); count = cmsg->cmsg_len - CMSG_LEN(0);
pi = pv; assert(count % sizeof(fd) == 0);
count /= sizeof(fd);
/* Count available fds */
start = (char*) cmsg;
end = (char*) cmsg + cmsg->cmsg_len;
count = 0;
while (start + CMSG_LEN(count * sizeof(*pi)) < end)
count++;
assert(start + CMSG_LEN(count * sizeof(*pi)) == end);
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
memcpy(&fd, (char*) CMSG_DATA(cmsg) + i * sizeof(fd), sizeof(fd));
/* Already has accepted fd, queue now */ /* Already has accepted fd, queue now */
if (stream->accepted_fd != -1) { if (stream->accepted_fd != -1) {
err = uv__stream_queue_fd(stream, pi[i]); err = uv__stream_queue_fd(stream, fd);
if (err != 0) { if (err != 0) {
/* Close rest */ /* Close rest */
for (; i < count; i++) for (; i < count; i++)
uv__close(pi[i]); uv__close(fd);
return err; return err;
} }
} else { } else {
stream->accepted_fd = pi[i]; stream->accepted_fd = fd;
} }
} }
} }