99 lines
1.3 KiB
Plaintext
99 lines
1.3 KiB
Plaintext
#!@BASH_PATH@
|
|
# A simple reimplementation of killall5 from sysvinit-tools
|
|
|
|
get_my_tree() {
|
|
local my_pid
|
|
read my_pid garbage < "/proc/self/stat"
|
|
child="$my_pid"
|
|
|
|
while [[ "$parent" != 1 ]]; do
|
|
read a b c parent d < "/proc/$child/stat";
|
|
child="$parent"
|
|
echo "$parent"
|
|
done
|
|
}
|
|
|
|
get_all_procs() {
|
|
local processlist
|
|
|
|
for i in /proc/*/exe; do
|
|
process_dir="${i%/*}"
|
|
process_pid="${process_dir##*/}"
|
|
|
|
readlink -e "$i" &>/dev/null && {
|
|
echo "$process_pid"
|
|
}
|
|
done
|
|
}
|
|
|
|
get_procs_to_kill() {
|
|
for i in "${all_procs[@]}"; do
|
|
unset skip
|
|
for p in "${my_tree[@]}"; do
|
|
[[ "$i" == "$p" ]] && { skip=1; }
|
|
done
|
|
|
|
[[ "$skip" ]] || { echo "$i"; }
|
|
done
|
|
}
|
|
|
|
pids_exist() {
|
|
for i in "$@"; do
|
|
if [[ -d "/proc/$i" ]]; then
|
|
return 0
|
|
fi
|
|
done
|
|
|
|
return 1
|
|
}
|
|
|
|
pid_wait() {
|
|
declare counter
|
|
|
|
while pids_exist "$@"; do
|
|
if (( counter == timeout )); then
|
|
return 1
|
|
fi
|
|
|
|
sleep 1
|
|
|
|
(( counter++ ))
|
|
done
|
|
}
|
|
|
|
main() {
|
|
timeout=30
|
|
signal=15
|
|
|
|
while (( $# )); do
|
|
case $1 in
|
|
-w)
|
|
flag_wait=1
|
|
timeout=$2
|
|
shift
|
|
;;
|
|
|
|
-s)
|
|
signal=$2
|
|
shift
|
|
;;
|
|
esac
|
|
|
|
shift
|
|
done
|
|
|
|
my_tree=( $(get_my_tree) self thread-self )
|
|
all_procs=( $(get_all_procs) )
|
|
procs_to_kill=( $(get_procs_to_kill) )
|
|
|
|
kill -n "$signal" "${procs_to_kill[@]}" 2>/dev/null
|
|
|
|
if (( flag_wait )); then
|
|
pid_wait "${procs_to_kill[@]}"
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
main "$@"
|