Ingo Schwarze <[email protected]> wrote: > Hello John, > > John Gardner wrote on Thu, Oct 15, 2026 at 01:05:03PM +1100: > > G. Branden Robinson wrote: > >> At 2026-10-14T20:12:37+0200, Bruno Haible wrote: > > >>> It is strange that the error is: > >>> mmroff: fatal error: "./groff -rRef=1 -z -mm -t -T utf8 -P -cbou > >>> ../contrib/mm/tests/artifacts/use-reference.mm" exited with status 4096 > >>> I thought that the maximum portable exit status in POSIX was 127 > >>> (or 255, if you allow process termination by signal). > > Looking at POSIX, i don't see that it handles the bit 0x80 (= 128) > of the exit(3) argument in any special way. It's only the shell > that uses values of 126 and greater in special ways, but no shell > is involved here.
A shell is involved: it is used to exec the process from which output is processed. > >> It's the return value of Perl's `close()`. > > That's not entirely accurate; it isn't the *return value* of close(3p), > but the value that close(3p) stores into the perlvar(1) $? variable, > which perlvar(1) documents as follows: close(3p) does not store a value in $?. $? is the integer value set by wait(2). The perl documentation you quote below makes this clear. > > $CHILD_ERROR > $? The status returned by the last pipe close, backtick (``) > command, successful call to wait(3p) or waitpid(3p), or from > the system(3p) operator. This is just the 16-bit status word > returned by the traditional Unix wait(2) system call (or else > is made up to look like it). Thus, the exit value of the > subprocess is really ($? >> 8), and "$? & 127" gives which > signal, if any, the process died from, and "$? & 128" reports > whether there was a core dump. > > For details, also look at "perldoc -f close". > > >> It'd probably be a good idea to clarify this diagnostic message. > > Indeed. End users of mmroff(1) should not be expected to be familiar > with how the Perl language handles IPC wrapping of Unix system calls, > nor would it be obvious to users of mmroff(1) that this error > message is related to internal Perl IPC mechanics at all. > > >>> I thought that the maximum portable exit status in POSIX was 127 > >>> (or 255, if you allow process termination by signal). > > > Trying to set an exit code greater than 0xFF will just return the value > > modulo 256, which makes the exit status of 4096 so interesting: > > Both of you are confusing POSIX exit(3) and wait(2) - but admittedly, > the message from mmroff(1) provides no hint it is talking about wait(2), > nor should it say so, nor should it be talking about wait(2) in the > first place. mmroff.pl is reporting the sixteen bit value set by wait(2). The high order eight bits are the exit status for a process terminating normally. If the process is terminated by a fatal signal, the low order seven bits indicated that signal. The eighth bit indicates whether a core file was generated. This is probably the source of confusion about bit 0x80, above. In the case in question, mmroff.pl should report $? >> 8. It should also detect signal termination and report accordingly.
