]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
profile/systemd-osc-context: Bring exit up to spec
authorChris Lindee <chris.lindee+github@gmail.com>
Mon, 16 Feb 2026 06:08:31 +0000 (00:08 -0600)
committerChris Lindee <chris.lindee+github@gmail.com>
Mon, 16 Feb 2026 09:14:43 +0000 (03:14 -0600)
The exit status should be compared against 128 — not 127 — as the Bash
manual, under the EXIT STATUS section, states [0]:

    When a command terminates on a fatal signal N, bash uses the value
    of 128+N as the exit status.

    If a command is not found, the child process created to execute it
    returns a status of 127.  If a command is found but is not
    executable, the return status is 126.

Furthermore, UAPI.15 specifies the `signal` value must be the symbolic
signal name, not a numerical value [1].  Luckily, POSIX.1-2008 ensures
the shell must supply `kill -l`, which must be able to convert `$?` to
the signal that could cause such an exit in that shell [2].  It should
be noted that only a select handful of signals have a standard numeric
value; all others are implementation-defined [3].  This is why UAPI.15
requires the symbolic name, as the value may differ across systems.

Notably, not every value above 128 needs to correspond to a signal; on
my Linux system, only exit codes 129–192 indicate a signal.  Again, we
can use `kill -l`, which will exit non-zero when an exit code does not
come from a signal (plus 128) [4].

Signal 0 (which would correspond to exit code 128) is reserved for the
null signal, per POSIX.1-2008 [5], and therefore will never be an exit
signal.

This change brings the implementation into compliance.

References:
 [0] https://www.man7.org/linux/man-pages//man1/bash.1.html#EXIT_STATUS
 [1] https://uapi-group.org/specifications/specs/osc_context/
 [2] https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/utilities/kill.html#:~:text=The%20letter%20ell
 [3] https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/utilities/kill.html#:~:text=The%20effects%20of%20specifying%20any%20signal_number
 [4] https://www.man7.org/linux/man-pages//man1/bash.1.html#:~:text=false%20if%20an%20error%20occurs%20or%20an%20invalid%20option%20is%20encountered
 [5] https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/basedefs/signal.h.html#:~:text=The%20value%200%20is%20reserved%20for%20use%20as%20the%20null%20signal

profile.d/80-systemd-osc-context.sh

index cfc8795d321ba029ff68e3a2d8300632da461a65..c7a556f66adbf94415287bcf5c6c6a729837a29a 100644 (file)
@@ -39,12 +39,12 @@ __systemd_osc_context_common() {
 }
 
 __systemd_osc_context_precmdline() {
-    local systemd_exitstatus="$?"
+    local systemd_exitstatus="$?" systemd_signal
 
     # Close previous command
     if [ -n "${systemd_osc_context_cmd_id:-}" ]; then
-        if [ "$systemd_exitstatus" -ge 127 ]; then
-            printf "\033]3008;end=%s;exit=interrupt;signal=%s\033\\" "$systemd_osc_context_cmd_id" $((systemd_exitstatus-127))
+        if [ "$systemd_exitstatus" -gt 128 ] && systemd_signal=$(kill -l "$systemd_exitstatus" 2>&-); then
+            printf "\033]3008;end=%s;exit=interrupt;signal=SIG%s\033\\" "$systemd_osc_context_cmd_id" "$systemd_signal"
         elif [ "$systemd_exitstatus" -ne 0 ]; then
             printf "\033]3008;end=%s;exit=failure;status=%s\033\\" "$systemd_osc_context_cmd_id" $((systemd_exitstatus))
         else