#!/usr/bin/env bash
# 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
}

main() {
	my_tree=( $(get_my_tree) self thread-self )
	all_procs=( $(get_all_procs) )
	procs_to_kill=( $(get_procs_to_kill) )

	signal="${1:-"-15"}"

	kill "$signal" "${procs_to_kill[@]}" 2>/dev/null

	return 0
}

main "$@"
