Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: misleading message for SIGFPE



FYI, bosh, a POSIXified fork of the Bourne shell by the late
Jörg Schilling has $/, ${.sh.code}, ${.sh.codename} and a few
more special parameters to complement $?. See also the $status
of rc that has text representation of the exit status.

$ bosh -o fullexitcode -c 'sh -c "kill -s SEGV \$\$"; printf "%s\n" "?=$?" "/=$/" "code=${.sh.code}" "codename=${.sh.codename}" "status=${.sh.status}" "termsig=${.sh.termsig}" "signo=${.sh.signo}" "signame=${.sh.signame}"'                 Segmentation fault - core dumped
?=139
/=SEGV
code=3
codename=DUMPED
status=11
termsig=SEGV
signo=17
signame=CHLD

$ rc -c 'sh -c '\''kill -s SEGV $$'\''; echo $status'
segmentation violation--core dumped
sigsegv+core


See in bosh man page at https://codeberg.org/schilytools/schilytools/src/commit/e835e64f0d84a614b3c8d619ac646060ea6922a5/sh/sh.1#L1809

> ?       The  decimal  value returned by the last synchronously executed
>         command or a decimal number derived from the signal number that
>         killed the process.
>
>         Only the low 8 bits of the exit code from the command are visi‐
>         ble   unless   exit   code   masking   is   switched   off   by
>         ``set -o fullexitcode''.   The  ability to see all 32 bits from
>         the exit code requires a modern UNIX compliant operating system
>         with working support for waitid(2).
>
>         If the executable file could not be found, the  returned  value
>         is  127.  If the file exists but could not be executed, the re‐
>         turned value is 126.
>
>         If bosh has been compiled with DO_EXIT_MODFIX (which is not the
>         default and not recommended by POSIX) and if a  command's  exit
>         code  modulo  256 is zero and ``set -o fullexitcode'' is not in
>         effect, the returned value is 128, except  when  the  operating
>         system  does  not  support  waitid(2), as the exit code then is
>         masked by the kernel.
>
>         If the command was killed by a signal, the  returned  value  is
>         128  + the signal number.  As a result, apparent exit code val‐
>         ues in the range 129..200 may also have been caused by  a  sig‐
>         nal.
>
>         If  the  shell  itself  or  a  sub shell catches a signal while
>         preparing a job, the exit code is 2000, or (when exit codes are
>         masked to only the low 8 bits) 208.
>
> /       A decimal number or text indicating the exit status returned by
>         the last synchronously executed command.
>
>         If $/ returns a decimal number, this is (on a POSIX system) the
>         32 bit exit code from the last command that did normally  exit.
>         Older  non-POSIX systems like Linux or UNIX systems from before
>         SVr4 return only the low 8 bits from the  exit  code.   In  any
>         case, the number was a result from a normal program exit.
>
>         If $/ returns text, this is either a signal name with the lead‐
>         ing  ``SIG''  stripped  off, like ``INT'' (see kill -l) for the
>         signal that terminated  the  program  or  one  of  the  strings
>         ``NOEXEC''  or  ``NOTFOUND'',  in case the program could not be
>         run at all.  The strings ``NOEXEC'' and  ``NOTFOUND''  are  re‐
>         turned  reliably from vfork(2) childs or when the related state
>         is already known by the cache.  This is  true  for  all  simple
>         commands.
>
>         Note  that  unless ``set -o fullexitcode'' is in effect, $/ may
>         have a non-zero value where value mod 256 == 0 and the shell in
>         such a case evaluates conditional execution as if the exit code
>         was zero.  This is the default behavior required by  POSIX  for
>         compatibility with historic shells.
[...]
> .sh.code
>         The  numerical  reason  waitid(2) returned for the child status
>         change. It matches the CLD_* definitions from  signal.h.   Note
>         that  the numbers are usually in the range 1..6 but this is not
>         guaranteed.  Use ${.sh.codename} for portability.
>
> .sh.codename
>         The reason waitid(2) returned for the child  status  change  as
>         text  that  is generated by stripping off CLD_ from the related
>         definitions from signal.h.  Possible values are:
>
>         EXITED      The  program  had  a  normal  termination  and  the
>                     exit(2) code is in ${.sh.status}.
>
>         KILLED      The program was killed by a signal, the signal num‐
>                     ber  is  in  ${.sh.status}  the  signal  name is in
>                     ${.sh.termsig}.
>
>         DUMPED      The program was killed  by  a  signal,  similar  to
>                     KILLED above, but the program in addition created a
>                     core dump.
>
>         TRAPPED     A traced child has trapped.
>
>         STOPPED     The  program  was  stopped  by a signal, the signal
>                     number is in ${.sh.status} the signal  name  is  in
>                     ${.sh.termsig}.
>
>         CONTINUED   A stopped child was continued.
>
>         NOEXEC      An  existing  file  could not be executed. This can
>                     happen when e.g. either the type of the file is not
>                     plain file or when the file does not  have  execute
>                     permission, or when the argument list is too long.
>
>                     This  is  not  a result from waitid(2) but from ex‐
>                     ecve(2).
>
>         NOTFOUND    A file was not found and thus  could  not  be  exe‐
>                     cuted.
>
>                     This  is  not  a result from waitid(2) but from ex‐
>                     ecve(2).
>
>         The child codes NOEXEC and  NOTFOUND  in  ${.sh.codename}  need
>         shared  memory (e.g. from vfork(2)) to allow a reliable report‐
>         ing.
[...]
> .sh.status
>         The  decimal  value returned by the last synchronously executed
>         command.  The value is unaltered and contains the full int from
>         the exit(2) call in the child in case the shell  is  run  on  a
>         modern os.

"modern os" here meaning one where waitid() returns the full
value (not truncated to 8 bits) which is not case of Linux (Jörg
had a bit of a grudge against GNU/Linux).

>
> .sh.termsig
>         The  signal  name related to the numerical ${.sh.status} value.
>         The translation to  signal  names  takes  place  regardless  of
>         whether the child was terminated by a signal or terminated nor‐
>         mally.
[...]

And also, only remotely related:

> .sh.signame
>         The name of the causing signal.  If the status is related to  a
>         set  of waitid(2) return values, this is CHLD or CLD, depending
>         on the os.  When a trap(1) command is executed,  ${.sh.signame}
>         holds the signal that caused the trap.
>
> .sh.signo
>         The signal number related to ${.sh.signame}.

-- 
Stephane




Messages sorted by: Reverse Date, Date, Thread, Author