Interpreting exit code given to "exit" procedure Lassi Kortela 14 Aug 2019 14:36 UTC

Here's another interesting Unix feature:

$ for i in 254 255 256 257 258; do chibi-scheme -e "(exit $i)"; echo
"exited with code $?"; done

exited with code 254
exited with code 255
exited with code 0
exited with code 1
exited with code 2

$ for i in -254 -255 -256 0 -2 -1; do chibi-scheme -e "(exit $i)"; echo
"exited with code $?"; done

exited with code 2
exited with code 1
exited with code 0
exited with code 0
exited with code 254
exited with code 255

That's because the Unix _exit(i) system call uses only the lowest 8 bits
of the actual exit code.

Gambit guards against this:

$ gsi -e '(exit 256)'
*** ERROR IN (string)@1.1 -- (Argument 1) Unsigned 8 bit exact INTEGER
expected

$ gsi -e '(exit -1)'
*** ERROR IN (string)@1.1 -- (Argument 1) Unsigned 8 bit exact INTEGER
expected

We don't say anything about (exit) in the current SRFI 170 draft. Should
we specify something about the interpretation of the exit code?

Posix says in
<https://pubs.opengroup.org/onlinepubs/9699919799/functions/_Exit.html>
that:

* only the least significant 8 bits 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 situation is somewhat baffling. I didn't even know there's a
syscall known as waitid (not "pid" but "id").

Also for more fun, Plan 9 accepts strings as exit codes, with a blank
string meaning success naturally enough.
<http://man.cat-v.org/plan_9/2/exits>. R7RS allows for this, as the
(exit) argument doesn't need to be an integer.