Skip to content

Conversation

blblack
Copy link
Contributor

@blblack blblack commented Sep 11, 2025

When not linking libc on 64-bit Linux and calling posix.setsid(), we get a type error at compile time inside of posix.errno(). This is because posix.errno()'s non-libc branch expects a usize-sized value, which is what all the error-returning os.linux syscalls return, and linux.setsid() instead returned a pid_t, which is only 32 bits wide.

This and the other 3 pid-related calls just below it (getpid(), getppid(), and gettid()) are the only Linux syscall examples here that are casting their return values to pid_t. For the other 3 this makes sense: those calls are documented to have no possible errors and always return a valid pid_t value.

However, setsid() actually can return the error EPERM, and therefore needs to return the raw value from syscall0 for posix.errno() to process like normal.

Additionally, posix.setsid() needs an @intcast(rc) for the success case as a result, like most other such cases.

@rootbeer
Copy link
Contributor

Looks great to me.

Not required, but I'd vote for adding some comments in the non-standard (i.e., pid_t-casting wrappers) that says they can do this because the syscall can't fail. Might prevent future copypasta problems?

// Cast result directly to a pid_t because getppid() cannot fail.
return @bitCast(@as(u32, @truncate(syscall0(.getppid))));

Hmm, not really your change but shouldn't that be pid_t instead of u32 in the @as()?

(Again, feel free to leave this as-is, or ignore me in favor of whatever the Zig team members say.)

@alexrp alexrp self-assigned this Sep 12, 2025
@blblack
Copy link
Contributor Author

blblack commented Sep 12, 2025

Hmm, not really your change but shouldn't that be pid_t instead of u32 in the @as()?

I think not, for the same reasons as #25205 (comment) . If these can't fail, the value should never be negative, even though pid_t technically can be.

@blblack
Copy link
Contributor Author

blblack commented Sep 12, 2025

Hmm, not really your change but shouldn't that be pid_t instead of u32 in the @as()?

I think not, for the same reasons as #25205 (comment) . If these can't fail, the value should never be negative, even though pid_t technically can be.

Hmmm no that was tired-brain thinking. The way it is now isn't any safer. Really if anything, these other calls should be asserting the positive-ness of the return value, perhaps like:

// Cast result to a pid_t, safety-checking positive-ness, because getppid() cannot fail.
return @intCast(@as(u32, @truncate(syscall0(.getppid))));

When not linking libc on 64-bit Linux and calling posix.setsid(),
we get a type error at compile time inside of posix.errno().  This
is because posix.errno()'s non-libc branch expects a usize-sized
value, which is what all the error-returning os.linux syscalls
return, and linux.setsid() instead returned a pid_t, which is only
32 bits wide.

This and the other 3 pid-related calls just below it (getpid(),
getppid(), and gettid()) are the only Linux syscall examples here
that are casting their return values to pid_t. For the other 3
this makes sense: those calls are documented to have no possible
errors and always return a valid pid_t value.

However, setsid() actually can return the error EPERM, and
therefore needs to return the raw value from syscall0 for
posix.errno() to process like normal.

Additionally, posix.setsid() needs an @intcast(rc) for the success
case as a result, like most other such cases.
The switch from @bitcast() to @intcast() here safety-checks
Linux's assertion that these 3 calls never return errors (negative
values as pid_t).  getppid() can legally return 0 if the parent is
in a different pid namespace, but this is not an error.
@rootbeer
Copy link
Contributor

I like the new comments and the @intCast check (which I now notice is similar to how some syscalls above, like gitgid and getuid do it). Thanks! 👍

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.

3 participants