Skip to content

Conversation

lunagl
Copy link
Contributor

@lunagl lunagl commented Sep 7, 2025

Implements posix.wait4 using waitid on Linux, because the wait4 syscall is not always available on newer architectures (e.g. riscv32).
At the moment we don't seem to have constants defined for the siginfo codes, so I used the numbers directly since I don't know if and where those constants should be added.

Closes #23262

@alexrp
Copy link
Member

alexrp commented Sep 7, 2025

To clarify, whatever handling we do for this should be at a higher level such as std.posix; we don't generally do this kind of elaborate syscall emulation in std.os.linux.

But that aside, could we just always use waitid for Linux in the standard library?

@alexrp alexrp self-assigned this Sep 7, 2025
@lunagl
Copy link
Contributor Author

lunagl commented Sep 7, 2025

Yes technically the waitid syscall is sufficient and it would make sense to only use it (without extra emulation on top), but due to the way our system layer works, we have to mirror the posix/libc functions there (that would be waitpid, wait4 and waitid).

So in order to provide all of these I think we have to do emulation in the system layer. Unfortunately we also can't just make higher level code such as std.posix use only waitid and remove waitpid/wait4 from the system layer, because the posix waitid function doesn't include the resource usage argument.

@alexrp
Copy link
Member

alexrp commented Sep 7, 2025

There are other functions in std.posix that just don't work on platforms like riscv32. For example, I believe all of the stat-like functions will just fail to compile when not linking libc because only the statx syscall exists.

In fact, this situation seems basically identical to the statx one in that the legacy syscalls should just be compile errors in std.os.linux for riscv32 (and other affected targets), and higher level layers of the standard library should prefer waitid on Linux w/o libc. See the std.fs code for inspiration.

@lunagl
Copy link
Contributor Author

lunagl commented Sep 7, 2025

Hmm I see, but then we definitely need to include the rusage argument in our waitid binding, making it incompatible with the Posix definition that one would get when linking libc. Otherwise waitid is simply not sufficient.

I think the problem is that std.os.linux is designed to be libc compatible, but that also means the functions in there don't always directly correspond to actual syscalls, and usually you'd expect emulation or additional logic to happen when necessary.

@alexrp
Copy link
Member

alexrp commented Sep 7, 2025

It's fine for std.os.linux to differ from C/POSIX. In cases where this affects higher level layers like std.posix, they just need to add a Linux special case. In general, std.os.linux shouldn't be thought of as a libc layer or anything like that; rather, it's the unfiltered Linux UAPI layer.

I don't believe std.posix has a waitid wrapper anyway, and it won't need one either if you follow the statx example.

@lunagl
Copy link
Contributor Author

lunagl commented Sep 7, 2025

In general, std.os.linux shouldn't be thought of as a libc layer or anything like that; rather, it's the unfiltered Linux UAPI layer.

That's surprising to me, because std.posix.system is documented as being "A libc-compatible API layer", and std.os.linux already contains simple emulation for a good number of syscalls (including waitpid), just nothing as complex as this.

But I agree it makes sense, I'll try to move the emulation to std.posix.

@alexrp
Copy link
Member

alexrp commented Sep 7, 2025

That's surprising to me, because std.posix.system is documented as being "A libc-compatible API layer", and std.os.linux already contains simple emulation for a good number of syscalls (including waitpid), just nothing as complex as this.

The line is admittedly a bit fuzzy, but "simple" emulation where all we need to do is straightforwardly invoke another syscall is generally OK. Extra logic beyond that starts to get into "basically implementing libc" territory, which is not what std.os.linux is about.

And yeah, that doc comment is just wrong.

@lunagl
Copy link
Contributor Author

lunagl commented Sep 8, 2025

Now I'm wondering if we should either remove std.os.linux.waitpid or make it use the actual waitpid system call, since the current status (unconditionally delegating to wait4) seems weird if we're not trying to provide a libc compatible interface anyway.

sidenote: I am also once again not sure why that one test is failing :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

riscv32-linux missing wait4
2 participants