Andreas Kempe
2024-02-02 16:05:14 UTC
Hello everyone,
I'm wondering why, at least on Linux and FreeBSD, a process exit
status was chosen to be only the lower 8 bits in the C interface, i.e.
exit() and wait().
This did bite some colleagues at work at one point who were porting a
modem manager from a real-time OS to Linux because they were returning
negative status codes for errors. We fixed it by changing the status
codes and I never really thought about why this is the state of
things... until now!
Having a look at man 3 exit on my FreeBSD system, it states
decide how to handle the int type argument.
Having a look at man 2 _exit, the system call man page, it says
nothing about the lower 8 bits, but claims conformance with
IEEE Std 1003.1-1990 ("POSIX.1") which says
in Part 1: System Application Program Interface (API) [C Language], 3.2.2.2 § 2
Looking at a more modern POSIX, IEEE Std 1003.1-2017, that has
waitid() defined, it has the following for _exit()
dispelled.
The question that remains is what the rationale behind using the lower
8 bits was from the start? Is it historical legacy that no one wanted
to change for backwards compatibility? Is there no need for exit codes
larger than 8 bits?
I don't know if I have ever come into contact with software that deals
with status codes that actually looks at the full value. My daily
driver shell, fish, certainly does not.
I'm wondering why, at least on Linux and FreeBSD, a process exit
status was chosen to be only the lower 8 bits in the C interface, i.e.
exit() and wait().
This did bite some colleagues at work at one point who were porting a
modem manager from a real-time OS to Linux because they were returning
negative status codes for errors. We fixed it by changing the status
codes and I never really thought about why this is the state of
things... until now!
Having a look at man 3 exit on my FreeBSD system, it states
Both functions make the low-order eight bits of the status argument
available to a parent process which has called a wait(2)-family
function.
and that it is conforming to the C99 standardavailable to a parent process which has called a wait(2)-family
function.
The exit() and _Exit() functions conform to ISO/IEC 9899:1999
(“ISO C99”).
C99 7.20.4.3 § 5 states(“ISO C99”).
Finally, control is returned to the host environment. If the value of
status is zero or EXIT_SUCCESS, an implementation-defined form of the
status successful termination is returned. If the value of status is
EXIT_FAILURE, an implementation-defined form of the status
unsuccessful termination is returned. Otherwise the status returned
is implementation-defined.
which I read as the C standard leaving it to the implementation tostatus is zero or EXIT_SUCCESS, an implementation-defined form of the
status successful termination is returned. If the value of status is
EXIT_FAILURE, an implementation-defined form of the status
unsuccessful termination is returned. Otherwise the status returned
is implementation-defined.
decide how to handle the int type argument.
Having a look at man 2 _exit, the system call man page, it says
nothing about the lower 8 bits, but claims conformance with
IEEE Std 1003.1-1990 ("POSIX.1") which says
in Part 1: System Application Program Interface (API) [C Language], 3.2.2.2 § 2
If the parent process of the calling process is executing a wait() or
waitpid(), it is notified of the termination of the calling process
and the low order 8 bits of status are made available to it; see
3.2.1.
that only puts a requirement on making the lower 8 bits available.waitpid(), it is notified of the termination of the calling process
and the low order 8 bits of status are made available to it; see
3.2.1.
Looking at a more modern POSIX, IEEE Std 1003.1-2017, that has
waitid() defined, it has the following for _exit()
The value of status may be 0, EXIT_SUCCESS, EXIT_FAILURE, or any
other value, though only the least significant 8 bits (that is,
status & 0377) shall be available from wait() and waitpid(); the
full value shall be available from waitid() and in the siginfo_t
passed to a signal handler for SIGCHLD.
so the mystery of why the implementation is the way it is wasother value, though only the least significant 8 bits (that is,
status & 0377) shall be available from wait() and waitpid(); the
full value shall be available from waitid() and in the siginfo_t
passed to a signal handler for SIGCHLD.
dispelled.
The question that remains is what the rationale behind using the lower
8 bits was from the start? Is it historical legacy that no one wanted
to change for backwards compatibility? Is there no need for exit codes
larger than 8 bits?
I don't know if I have ever come into contact with software that deals
with status codes that actually looks at the full value. My daily
driver shell, fish, certainly does not.
--
Best regards,
Andreas Kempe
Best regards,
Andreas Kempe