Files
sausage/userland/brush/source/brush-shell/tests/cases/compat/builtins/kill.yaml
T
2026-11-11 22:04:16 +00:00

246 lines
8.2 KiB
YAML

name: "Builtins: kill"
cases:
- name: "kill -l"
ignore_stderr: true
stdin: |
for i in $(seq 1 31); do kill -l $i; done
# limit the number of signals to 31. Realtime signals are not implemented yet.
for i in $(kill -l | sed -e "s/[[:digit:]]*)//g"); do echo $i; done | head -31
# invalid option
kill -l 9999
kill -l HUP
kill -l iNt
kill -l int
kill -l SIGHUP
kill -l EXIT
- name: "kill -s"
stdin: |
kill -s USR1 $$
- name: "kill -n"
stdin: |
kill -n 9 $$
- name: "kill -s with its signal attached"
stdin: |
kill -sUSR1 $$
- name: "kill -n with its signal attached"
stdin: |
kill -n15 $$
- name: "kill -SIGNAME"
stdin: |
kill -HUP $$
- name: "kill -s SIG -- pid"
stdin: |
kill -s HUP -- $$
- name: "kill -SIG -- pid"
known_failure: true # TODO(kill): `--` after -SIG is taken for a pid
stdin: |
kill -9 -- $$
- name: "kill -n 0"
stdin: |
kill -n $((5-5)) $$
echo OK
- name: "A shell ignores SIGQUIT, even when not interactive"
known_failure: true # TODO(signals): bash ignores SIGQUIT in all cases, but a brush that isn't interactive takes its default action
stdin: |
"$BASH" -c 'kill -QUIT $$; echo survived'
echo "status: $?"
- name: "A program that a signal ends is reported"
known_failure: true # TODO(jobs): brush reports nothing when a signal other than SIGINT or SIGPIPE ends a program, as bash does on stderr
stdin: |
sh -c 'kill -TERM $$'
echo "status: $?"
- name: "An interactive shell without a terminal survives SIGTERM"
known_failure: true # TODO(signals): brush has an interactive shell survive signals only once it takes a terminal
stdin: |
echo 'kill -TERM $$; echo survived' | "$BASH" --norc --noprofile -i 2>/dev/null
echo "status: $?"
- name: "kill -sigspec"
stdin: |
kill -USR1 $$
- name: "kill -sigspec (numeric)"
stdin: |
kill -9 $$
- name: "kill -0 (numeric)"
stdin: |
kill -0000 $$
echo OK
- name: "kill -0 (numeric, non-existent)"
ignore_stderr: true
stdin: |
kill -0 99999999
- name: "kill continues a stopped job sent SIGTERM, so it can act on it"
ignore_stderr: true
stdin: |
set -m
sh -c 'trap "echo terminated >status.txt; exit 3" TERM; kill -STOP $$; echo resumed'
kill -TERM %1
for i in $(seq 100); do [ -s status.txt ] && break; sleep 0.1; done
cat status.txt
rm -f status.txt
- name: "kill continues a job sent SIGTERM that stopped again in the background"
ignore_stderr: true
stdin: |
set -m
sh -c 'echo $$ >pid.txt; trap "echo terminated >status.txt; exit 3" TERM; kill -STOP $$; kill -STOP $$'
bg >/dev/null
for i in $(seq 100); do case $(ps -o stat= -p "$(cat pid.txt)") in T*) break ;; esac; sleep 0.1; done
kill -TERM %1
for i in $(seq 100); do [ -s status.txt ] && break; sleep 0.1; done
cat status.txt
rm -f pid.txt status.txt
- name: "A stopped job that survives SIGTERM runs on"
ignore_stderr: true
stdin: |
set -m
sh -c 'trap "echo caught >status.txt" TERM; kill -STOP $$; while [ ! -e done.txt ]; do sleep 0.1; done'
kill -TERM %1
for i in $(seq 100); do [ -s status.txt ] && break; sleep 0.1; done
cat status.txt
jobs -r >running.txt; echo "running: $(( $(wc -l <running.txt) ))"
jobs -s >stopped.txt; echo "stopped: $(( $(wc -l <stopped.txt) ))"
touch done.txt
wait %1
rm -f status.txt done.txt running.txt stopped.txt
- name: "kill -sigspec (numeric, full name resolution)"
stdin: |
kill -l $(kill -l KILL)
- name: "kill -sigspec (numeric, invalid)"
ignore_stderr: true
stdin: |
kill -9999 $$
echo "exit code: $?"
- name: "kill -s without a signal fails with status 1"
known_failure: true # TODO(kill): brush returns 2
ignore_stderr: true
stdin: |
kill -s
echo "missing signal: $?"
- name: "kill with a bad or missing signal fails with status 1"
known_failure: true # TODO(kill): brush returns 2
ignore_stderr: true
stdin: |
kill -s BOGUS $$
echo "unknown signal: $?"
kill -s
echo "missing signal: $?"
- name: "kill sends SIGTERM by default"
known_failure: true # TODO(kill): sends SIGKILL by default, where bash sends SIGTERM
stdin: |
sh -c 'trap "echo got TERM; exit 0" TERM; echo $$ > pidfile; while :; do sleep 0.05; done' &
while [ ! -s pidfile ]; do sleep 0.05; done
kill "$(cat pidfile)"
wait
# The process ID differs from run to run.
rm pidfile
- name: "kill takes -- before a process group, and -s 0"
known_failure: true # TODO(signals): kill's default signal and option parsing
ignore_stderr: true
stdin: |
kill -0 -- $$; echo "a=$?"
kill -s 0 $$; echo "b=$?"
kill -0 -- -$(ps -o pgid= -p $$ | tr -d ' '); echo "c=$?"
# An exited process's ID names no process or group, so nothing else is signaled.
dead=$(sh -c 'echo $$')
kill -- -$dead; echo "d=$?"
kill -s TERM -- -$dead; echo "e=$?"
- name: "kill takes -N after a signal as a process group"
known_failure: true # TODO(kill): -N after a signal is taken for an invalid signal
ignore_stderr: true
stdin: |
# Signal 0 checks this shell's own group without signaling it.
kill -0 -$(ps -o pgid= -p $$ | tr -d ' '); echo "a=$?"
# An exited process's ID names no process or group, so nothing else is
# signaled; only the reason kill gives for failing is compared.
dead=$(sh -c 'echo $$')
kill -TERM -$dead 2>&1 | grep -c 'invalid signal'; echo "b=${PIPESTATUS[0]}"
- name: "kill takes -N alone as a signal number"
ignore_stderr: true
stdin: |
# -999999 is an invalid signal number here, not a target.
kill -999999 2>&1 | grep -c 'invalid signal'; echo "rc=${PIPESTATUS[0]}"
- name: "kill takes the words after its first operand as operands"
ignore_stderr: true
stdin: |
kill -0 $$ -l || true
echo "done"
- name: "kill takes its signal in each form"
ignore_stderr: true
stdin: |
kill -l -- 9
kill -l HUP
# An exited process's ID names no process or group, so nothing else is
# signaled; only the reason kill gives for failing is compared.
dead=$(sh -c 'echo $$')
kill -sUSR1 $dead 2>&1 | grep -c 'invalid signal'; echo "a=${PIPESTATUS[0]}"
kill -n9 $dead 2>&1 | grep -c 'invalid signal'; echo "b=${PIPESTATUS[0]}"
kill -HUP $dead 2>&1 | grep -c 'invalid signal'; echo "c=${PIPESTATUS[0]}"
- name: "kill takes options after a -SIG shorthand"
known_failure: true # TODO(kill): a word after -SIG is taken for an operand
ignore_stderr: true
stdin: |
# Each sends signal 0 to this shell, which only checks that it exists.
kill -0 -n 0 $$; echo "a=$?"
kill -TERM -s 0 $$; echo "b=$?"
- name: "kill takes -- after a signal"
known_failure: true # TODO(kill): `-9 --` takes `--` for a pid
ignore_stderr: true
stdin: |
# An exited process's ID names no process or group, so nothing else is
# signaled; only the reason kill gives for failing is compared.
dead=$(sh -c 'echo $$')
kill -9 -- $dead 2>&1 | grep -c 'invalid signal'; echo "a=${PIPESTATUS[0]}"
kill -s HUP -- -$dead 2>&1 | grep -c 'invalid signal'; echo "b=${PIPESTATUS[0]}"
- name: "kill -s takes a signal number"
known_failure: true # TODO(kill): -s takes only signal names
ignore_stderr: true
stdin: |
# The shell's termination status shows which signal it was sent.
kill -s 15 $$
echo "survived: $?"
- name: "kill -l with several signals prints each"
known_failure: true # TODO(kill): `kill -l` with more than one signal fails as too many jobs
stdin: |
kill -l 15 9
- name: "kill -l maps an exit status above 128 to its signal"
known_failure: true # TODO(kill): a status above 128 is an invalid signal specification
stdin: |
kill -l 129
- name: "kill -l lists the signals in columns"
known_failure: true # TODO(kill): one signal a line, not bash's table
stdin: |
kill -l | head -n 1