Fetch a list of all child PIDs before forwarding the termination signal. Once the main process is terminated, forward that term signal to all found children also (if they are still running)
118 lines
4.7 KiB
Bash
Executable File
118 lines
4.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
###
|
|
# File: sunshine-run
|
|
# Project: bin
|
|
# File Created: Tuesday, 23rd August 2023 3:28:52 pm
|
|
# Author: Josh.5 (jsunnex@gmail.com)
|
|
# -----
|
|
# Last Modified: Friday, 23rd August 2023 4:21:00 pm
|
|
# Modified By: Josh.5 (jsunnex@gmail.com)
|
|
###
|
|
set -e
|
|
|
|
exec >> >(tee -a ${USER_HOME:?}/.cache/log/sunshine_run.log) 2>&1
|
|
echo
|
|
echo "-------------------------------"
|
|
echo
|
|
date
|
|
echo
|
|
echo "-------------------------------"
|
|
echo
|
|
echo "**** Execute sunshine-run ****"
|
|
echo
|
|
|
|
# Trap SIGINT, SIGQUIT, SIGHUP, SIGTERM to forward signals to the child process
|
|
_term() {
|
|
if [ -n "${proc_pid}" ]; then
|
|
# Read all child processes of proc_pid first
|
|
child_pids=$(pgrep -P $proc_pid)
|
|
# Forward the signal proc_pid
|
|
echo " - Checking for status of main process ${proc_pid}"
|
|
if kill -0 "${proc_pid}" 2>/dev/null; then
|
|
echo " - Forwarding signal $1 to process ${proc_pid}"
|
|
kill -s "${1}" "${proc_pid}"
|
|
else
|
|
echo " - Process ${proc_pid} is already stopped. Nothing to do here."
|
|
fi
|
|
for child_pid in ${child_pids:-}; do
|
|
echo " - Checking for status of child process ${child_pid}"
|
|
if kill -0 "${child_pid}" 2>/dev/null; then
|
|
echo " - Forwarding signal $1 to process ${child_pid}"
|
|
kill -s "${1}" "${child_pid}"
|
|
else
|
|
echo " - Process ${child_pid} is already stopped. Nothing to do here."
|
|
fi
|
|
done
|
|
fi
|
|
}
|
|
trap '_term INT' SIGINT
|
|
trap '_term QUIT' SIGQUIT
|
|
trap '_term HUP' SIGHUP
|
|
trap '_term TERM' SIGTERM
|
|
|
|
# Record sunshine-run PID
|
|
echo " - Recording sunshine-run PID '$$' in /tmp/sunshine-exec-run.pid"
|
|
echo "$$" > /tmp/sunshine-exec-run.pid
|
|
|
|
# Wipe session config
|
|
echo "" > /tmp/sunshine-exec-run.conf
|
|
|
|
# Update display resolution and refresh reate if client provided the required details
|
|
if ([ "X${SUNSHINE_CLIENT_WIDTH:-}" != "X" ] && [ "X${SUNSHINE_CLIENT_HEIGHT:-}" != "X" ] && [ "X${SUNSHINE_CLIENT_FPS:-}" != "X" ]); then
|
|
# Don't fail script if something goes wrong here. Set +e in subprocess
|
|
(
|
|
set +e
|
|
echo " - Setting display resolution to ${SUNSHINE_CLIENT_WIDTH:?}x${SUNSHINE_CLIENT_HEIGHT:?} ${SUNSHINE_CLIENT_FPS:?}Hz"
|
|
|
|
# Read current display mode and extract resolution and refresh rate from the mode string
|
|
__xrandr_out="$(xrandr)"
|
|
__current_current_mode=$(echo "${__xrandr_out:?}" | awk '/\*/ {print $0}')
|
|
__current_resolution=$(echo ${__current_current_mode:?} | awk '{print $1}')
|
|
__current_refresh_rate=$(echo ${__current_current_mode:?} | awk '{sub(/\*/, "", $2); print $2}')
|
|
|
|
# Get the primary output device
|
|
__primary_output="$(echo "${__xrandr_out:?}" | grep primary | awk '{print $1}')"
|
|
|
|
# Get the modeline from cvt and extract the second line (which contains the modeline)
|
|
__client_modeline=$(cvt "${SUNSHINE_CLIENT_WIDTH:?}" "${SUNSHINE_CLIENT_HEIGHT:?}" "${SUNSHINE_CLIENT_FPS:?}" | grep Modeline | sed -e 's/Modeline //')
|
|
|
|
# Create a new mode for this. This allows us to force a set refresh rate that may not be supported by the display
|
|
__client_mode=$(echo "${__client_modeline:?}" | awk -F '"' '{print $2}')
|
|
|
|
# Check if tthis mode is alread added to the primary display
|
|
if ! echo "${__xrandr_out:?}" | grep -q "${__client_mode:?}"; then
|
|
echo " - Adding new mode '${__client_mode:?}' with new modeline '${__client_modeline:?}'"
|
|
xrandr --newmode "${__client_mode:?}" ${__client_modeline##*\"}
|
|
echo " - Adding new mode '${__client_mode:?}' to device '${__primary_output:?}'"
|
|
xrandr --addmode "${__primary_output:?}" "${__client_mode:?}"
|
|
fi
|
|
|
|
# Set the current resoultion to the new mode
|
|
echo " - Setting the display mode to '${__client_mode:?}'"
|
|
xrandr --output "${__primary_output:?}" --mode "${__client_mode:?}" --rate "${SUNSHINE_CLIENT_FPS:?}"
|
|
|
|
# Save original display settings to config file. This will be read and used to restore the original display settings when the client disconnects.
|
|
echo "primary_output='${__primary_output:?}'" >> /tmp/sunshine-exec-run.conf
|
|
echo "display_mode='${__current_resolution:?}'" >> /tmp/sunshine-exec-run.conf
|
|
echo "display_rate='${__current_refresh_rate:?}'" >> /tmp/sunshine-exec-run.conf
|
|
)
|
|
fi
|
|
|
|
# Run child process
|
|
/usr/bin/dumb-init "${@}" &
|
|
proc_pid=$!
|
|
|
|
# Wait for child process to exit:
|
|
echo " - Waiting for PID '${proc_pid}' to exit"
|
|
wait "$proc_pid"
|
|
|
|
# Clean up PID file
|
|
if [ -f /tmp/sunshine-exec-run.pid ]; then
|
|
echo " - Removing sunshine-run pidfile."
|
|
rm -f /tmp/sunshine-exec-run.pid
|
|
else
|
|
echo " - WARNING: No sunshine-run pidfile found for removal."
|
|
fi
|
|
|
|
echo "DONE"
|