Closed zeldin closed 2 years ago
Good catch.
I think that int
comes from macOS which is my main machine. Its manual says that the type is int
for this field. And when I apply your patch to master
, the test gets stacked.
We need to find a good way both for Linux and macOS.
Never mind. I was looking at master
. (Old text: We should modify cbits/cmsg.c
, too.)
I made a mistake. On macOS, CMSG_LEN
is defined:
#define CMSG_LEN(l) (__DARWIN_ALIGN32(sizeof(struct cmsghdr)) + (l))
So, its return type is size_t
.
I'm puzzled why tests fail with this PR.
Looking at <sys/socket.h>
on Monterey, the sizes of the fields are indeed different. cmsg_len
and msg_controllen
are socklen_t
, which is 32 bits, while msg_iovlen
is int
(meaning that it was mismatched already before)...
Now I kind of wonder what POSIX.1-2008 actually say about these fields. 😟
The network stack of macOS is a bit strange. Could you put #ifdef
to take macOS as a special case?
Should be possible I guess. Although it's plausible that it's actually Linux that is the special case. macOS is ostensibly based on BSD, which is the source of the sendmsg
API. Anyway, I think I need to set up ghc on my mac so that I can run the tests there as well.
Yes, POSIX.1-2008 supports the macOS definition of the structs, so I guess Linux unilaterally changed the API to fix security issues. Thus, Linux is the special case.
Actually, rather than hardcoding special cases, I think the best solution would be to just use #type
. I'll see if I can cook up something that works.
There, now the tests pass both on macOS (arm64) and Linux (ppc64) for me. The second force-push was just updating the commit message to be more accurate.
Unfortunately it was not possible to use #type
to match the type of a field member (presumable because this would require use of typeof()
, which is C2x), so I still had to use #ifdef
where Linux used a different type name from what POSIX specifies.
Merged. Thanks you for your awesome contribution!
These fields are size_t, so using CInt on LP64 only accesses 32 bits of the total 64. This is especially noticable on big endian, where the lower 32 bits of the number are written to the upper 32 bits of the field.