123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- #!/bin/sh --
- set -u
- # sx - start an xorg server
- # https://github.com/Earnestly/sx
- : "${SX_CLIENT_SIGNAL:=TERM}"
- : "${SX_CLIENT_STOP_CMD:=:}"
- : "${SX_LOCK:=${XDG_RUNTIME_DIR:-${TMPDIR:-/tmp}/runtime-${USER:-$(id -un)}}/sx.lock}"
- unexport_env() {
- unset SX_LOCK
- unset SX_CLIENT_SIGNAL
- unset SX_CLIENT_STOP_CMD
- "${@}"
- }
- local_kill() {
- pid="${1:?}"
- shift
- kill -0 "${pid}" 2>/dev/null && {
- kill "${@}" "${pid}"
- wait "${pid}"
- local_kill_exit="${?}"
- }
- }
- CLEANUP_DONE=0
- cleanup() {
- if [ "${CLEANUP_DONE}" -eq 1 ]; then
- return
- fi
- if [ -n "${SX_CLIENT_STOP_CMD}" ] && [ "${SX_CLIENT_STOP_CMD}" != : ]; then
- ${SX_CLIENT_STOP_CMD}
- else
- local_kill "${client}" -s "${SX_CLIENT_SIGNAL}"
- fi
- local_kill_exit=0
- local_kill "${server}"
- CLEANUP_DONE=1
- if ! stty "${stty}"; then
- stty sane
- fi
- [ -n "${RMDIR:-}" ] && chmod +w -R "${XAUTHORITY%/*}"
- xauth remove :"${tty}"
- [ -n "${RMDIR:-}" ] && rm -rf "${XAUTHORITY%/*}"
- }
- usage() {
- printf '%s\n' \
- "Usage: ${0##*/} [action]" \
- ' start <pid> cmd args... - start user services' \
- ' stop <pid> - stop user services' \
- ' help - show this help'
- exit "${1:-0}"
- }
- exec 3<>"${SX_LOCK}"
- cmd="${1:-}"
- shift
- case "${cmd}" in
- start)
- flock -n 3 || {
- IFS= read -r sx_pid <&3
- echo "sx already running (pid=${sx_pid})" 1>&2
- exit 1
- }
- [ "${#}" -gt 0 ] || {
- echo "please provide command to start after Xorg is ready" 1>&2
- exit 1
- }
- printf '%d\n' "${$}" 1>&3
- ;;
- stop)
- IFS= read -r sx_pid <&3
- rm -f "${SX_LOCK}" || :
- exec kill "${sx_pid:?}"
- ;;
- help | -h) usage 0 ;;
- *) usage 1 ;;
- esac
- server=
- client=
- stty="$(stty -g)"
- tty="${TTY:-$(tty)}"
- tty="${tty#/dev/tty}"
- RMDIR=
- [ -n "${XAUTHORITY:-}" ] || {
- XAUTHORITY="$(mktemp --suffix='.Xauthority' -d)/cookie"
- RMDIR=1
- }
- touch -- "${XAUTHORITY}"
- export XAUTHORITY
- trap 'cleanup; exit "${local_kill_exit:-0}"' EXIT
- # shellcheck disable=2016
- trap='cleanup; trap - "${signal}"'
- for signal in HUP INT QUIT TERM; do
- # shellcheck disable=2064
- trap "${trap}" "${signal}"
- done
- # Xorg will return a USR1 signal to the parent process indicating it is ready
- # to accept connections if it inherited a USR1 signal with a SIG_IGN
- # disposition. Consequently a client may be started directly from a USR1
- # signal handler and obviate the need to poll for server readiness.
- trap 'DISPLAY=":${tty}" unexport_env "${@}" 3>&- & wait "${!}"' USR1
- xauth add ":${tty}" MIT-MAGIC-COOKIE-1 \
- "$(od -An -N16 -tx /dev/urandom | tr -d ' ')"
- if [ -n "${RMDIR:-}" ]; then
- chmod -w -R "${XAUTHORITY%*}"
- fi
- (
- trap '' USR1 &&
- exec Xorg ":${tty}" "vt${tty}" \
- -auth "${XAUTHORITY}" \
- -arinterval 20 \
- -nolisten tcp \
- -ardelay 200 \
- -keeptty \
- -noreset
- ) &
- server="${!}"
- wait "${server}"
|