Open gpanders opened 2 years ago
I've hit this bug as well. Like op says, sigset_t
is 128 bytes and should be 8 bytes. Also, the kernel defines NSIG
as 64
, but os/linux.zig has it as 65.
It appears both of these incorrect values came from the musl source code.
Zig Version
0.10.0-dev.3840+2b92c5a23
Steps to Reproduce
Call
std.os.linux.epoll_pwait
with a non-nullsigmask
argument.Complete working example:
Compile with
zig build-exe
and run.Expected Behavior
It should print
epoll_pwait succeeded
.Actual Behavior
It prints
EINVAL
.Zig's implementation of
epoll_pwait
is here: https://github.com/ziglang/zig/blob/36f4f32fad3e88a84b6a10d78df31a4ed2c24465/lib/std/os/linux.zig#L1436-L1446It passes
@sizeOf(sigset_t)
as the final argument of the syscall, which matches what the man page forepoll_pwait
says:Also according to the man page, the only occasion that
EINVAL
should be returned is whenepfd
is not an epoll file descriptor ormaxevents
is less than or equal to zero. But neither of those cases are true in this example. But if you check the Linux kernel sources, you find there is one more case whereEINVAL
can be returned, and that is if thesigsetsize
argument does not match the size of thesigset_t
data structure in the kernel:The
sigset_t
data structure defined in the kernel is 8 bytes (for x86-64):I also checked the glibc sources to see what they are actually doing. They use a macro
__NSIG_BYTES
defined as:which, when you resolve all of the macros, is also 8 bytes for x86-64.
The
sigset_t
that Zig is passing to@sizeOf
is 128 bytes. This size mismatch causes theEINVAL
error. It looks like Zig needs to define a separate constant for thissigsetsize
argument rather than using@sizeOf(sigset_t)
(as theepoll_pwait
man page would have you believe).