1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
#!/bin/bash
# This file is part of util-linux.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This file is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
TS_TOPDIR="${0%/*}/../.."
TS_DESC="decode functions"
. "$TS_TOPDIR/functions.sh"
ts_init "$*"
# make sure we do not use shell built-in command
if [ "$TS_USE_SYSTEM_COMMANDS" == "yes" ]; then
TS_CMD_KILL="$(which kill)"
fi
ts_skip_qemu_user
ts_check_test_command "$TS_CMD_KILL"
ts_check_test_command "$TS_HELPER_SIGSTATE"
ts_check_prog "sed"
ts_check_prog "sort"
ts_check_prog "tr"
. "$TS_SELF/kill_functions.sh"
decode()
{
"$TS_CMD_KILL" -l "$1"
}
signame2num()
{
local name=$1
local n s
"$TS_CMD_KILL" -L | while read n s; do
if [[ "$s" == "$name" ]]; then
echo "$n"
return 0
fi
done
return 1
}
encode()
{
local s
local n
local -i bits=0
for s in "$@"; do
n=$(signame2num "$s")
if [[ -z "$n" ]]; then
ts_log_both "failed to encode the signal name: $s"
# The test may fail.
continue
fi
(( bits |= 1 << (n - 1) ))
done
printf "0x%0.16x\n" "$bits"
}
sort_signals_by_name()
{
local field
local siglist
while IFS=: read field siglist; do
echo "${field}:"
echo $siglist | tr ' ' '\n' | sort
done
}
PID=
ACK=
{
for siglist in "INT ILL ABRT FPE SEGV TERM" \
"HUP QUIT TRAP PIPE ALRM" \
"USR1"; do
printf 'encode-decode round-trip "%s":\n' "${siglist}"
d=$(encode ${siglist})
decode "$d"
done
coproc SIGSTATE { "$TS_HELPER_SIGSTATE" ; }
if read -u ${SIGSTATE[0]} PID; then
"$TS_CMD_KILL" -USR1 "$PID"
if read -u ${SIGSTATE[0]} ACK; then
# The target process is in its signal handler for USR1.
# Sending one more USR1 is for making the signal pending state.
"$TS_CMD_KILL" -USR1 "$PID"
"$TS_CMD_KILL" -d "$PID" | {
SIGRTMIN=$("$TS_CMD_KILL" -L | grep -o '[0-9]\+ RTMIN' | cut -d " " -f 1)
if [[ $("$TS_CMD_KILL" --list=$SIGRTMIN) == RT0 ]]; then
# See man signal(7).
# The Linux kernel supports a range of 33 different real-time signals,
# numbered 32 to 64. However, the glibc POSIX threads implementation in‐
# ternally uses two (for NPTL) or three (for LinuxThreads) real-time sig‐
# nals (see pthreads(7)), and adjusts the value of SIGRTMIN suitably (to
# 34 or 35).
sed_cmd="sed"
for ((i=32; i<=SIGRTMIN; i++)); do
sed_cmd+=" -e s/' $i'//"
done
eval $sed_cmd
else
cat
fi
} | sort_signals_by_name
fi
echo DONE >&"${SIGSTATE[1]}"
fi
wait ${SIGSTATE_PID}
} > "$TS_OUTPUT" 2>&1
ts_finalize
|