From 161b8be6f57c6897949ca74a2b4e0c1c1a679199 Mon Sep 17 00:00:00 2001 From: Earnestly Date: Fri, 1 Dec 2017 20:14:54 +0000 Subject: [PATCH] introduce sx --- LICENSE | 19 +++++++++++++ Makefile | 9 +++++++ README | 56 +++++++++++++++++++++++++++++++++++++++ sx | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ sx.1 | 58 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 223 insertions(+) create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README create mode 100755 sx create mode 100644 sx.1 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..475a055 --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright 2017 Earnestly + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4b47c55 --- /dev/null +++ b/Makefile @@ -0,0 +1,9 @@ +PREFIX ?= /usr/local +bindir ?= /bin +mandir ?= /share/man + +install: sx sx.1 + install -Dm0755 sx $(DESTDIR)$(PREFIX)$(bindir)/sx + install -Dm0644 sx.1 $(DESTDIR)$(PREFIX)$(mandir)/man1/sx.1 + +.PHONY: install diff --git a/README b/README new file mode 100644 index 0000000..ba87c56 --- /dev/null +++ b/README @@ -0,0 +1,56 @@ +sx + +INTRODUCTION + + sx is a simple alternative to both xinit(1) and startx(1). + + It started life as a proof of concept while attempting to learn how both + xinit(1) and startx(1) worked. + + It is not a direct replacement however as it provides a different, more + limited, interface. + + Some of these differences are as follows: + + * The Xorg server's command-line is hard coded and not exposed to the + user. + + * The first DISPLAY is 1 instead of 0 contrary to what X(7) suggests. + + * xauth entries are overwritten if the displayname is identical. + + * Corresponding xauth entries are unconditionally removed when the Xorg + server is terminated. + + * The Xorg server uses the -noreset flag. + + * The Xorg server logs are written to $XDG_DATA_HOME/sx/$DISPLAY instead + of Xorg.$DISPLAY.log + + * While XAUTHORITY is still honoured, $XDG_CONFIG_HOME/sx/xauthfile is + used instead of $HOME/.Xauthority + + * Very little proxy error checking is used preferring instead to let each + tool used speak for itself. + + * None of the typical /etc/X11/xinit infrastructure is directly used. + + * Neither XINITRC is honoured nor .xinitrc used. + + * The XDG_CONFIG_HOME/sx/sxrc file is used instead of .xinitrc and is + required to be executable. + + For a rational on why this exists, the author invites the reader to look + over the source code for both xinit(1) and startx(1). + +REQUIRES + + Notable requirements are for GNU timeout and GNU tail which is used for the + --pid option. Beyond these the usual set of POSIX command-line tools along + with Xorg and xauth are required. + +BUILD + + As there's nothing to build, simply install using a prefered PREFIX. + + make DESTDIR=staged PREFIX=/usr install diff --git a/sx b/sx new file mode 100755 index 0000000..c5c9411 --- /dev/null +++ b/sx @@ -0,0 +1,81 @@ +#!/bin/sh -- +# sx - start an xserver + +# requires fgconsole stty timeout xauth Xorg + +# I'm willing to take advantage of errexit for this script as roughly 85% of +# the error checking would take the form of: +# if ! command; then +# exit +# fi +set -o errexit + +error() { + # To expose printf's DSL we will need to use a positional argument for the + # format string. + # shellcheck disable=SC2059 + printf -- "sx: $2" "${@:3}" >&2 + exit "$1" +} + +cleanup() { + # Return to conventional flow control here as we need to continue + # regardless of failure. + set +o errexit + + if [ "$(ps -o comm= "$1")" = Xorg ]; then + kill "$1" + + # Send SIGKILL after 10 seconds if the xserver is taking too long to + # terminate. + timeout 10 tail --pid="$1" -f /dev/null + + case $? in + 124) kill -s KILL "$1" + esac + + xauth remove :"$tty" + fi + + if ! stty "$stty"; then + stty sane + fi + + exit +} + +stty=$(stty -g) + +tty=$(ps -o tty= $$) + +case $tty in + tty*) tty=${tty#tty} +esac + +cfgdir=${XDG_CONFIG_HOME:-$HOME/.config}/sx +datadir=${XDG_DATA_HOME:-$HOME/.local/share}/sx +XAUTHORITY=${XAUTHORITY:-$cfgdir/xauthfile} + +mkdir -p "$cfgdir" "$datadir" + +trap 'cleanup "$pid"' EXIT + +touch "$XAUTHORITY" +export XAUTHORITY + +xauth add :"$tty" MIT-MAGIC-COOKIE-1 "$(mcookie)" + +# Xorg will check if SIGUSR1 was set to SIG_IGN in its environment and issue +# its own SIGUSR1 back to the parent process when it is ready to accept +# connections. See Xserver(1). + +# We take advantage of this feature to launch our client directly from the +# SIGUSR1 handler and avoid the need to poll for readiness. +trap 'DISPLAY=:$tty "${@:-"$cfgdir"/sxrc}"' USR1 +( + trap '' USR1 + exec /usr/lib/xorg-server/Xorg :"$tty" -keeptty vt"$tty" -noreset \ + -logfile "$datadir/$tty" -auth "$XAUTHORITY" +) & pid=$! + +wait diff --git a/sx.1 b/sx.1 new file mode 100644 index 0000000..455c2fe --- /dev/null +++ b/sx.1 @@ -0,0 +1,58 @@ +.TH sx 1 2017-05-12 sx + +.SH NAME +sx \- start an xserver + +.SH SYNOPSIS +.B sx +.RI [ client ] + +.SH DESCRIPTION +.B sx +can be used to replace both +.BR xinit (1) +and +.BR startx (1) +for starting an Xorg server. By default +.B sx +will attempt execute +.I sxrc +unless a +.I client +argument is provided. + +.SH ENVIRONMENT +.TP +.B XAUTHORITY +This environment represents the file used to store authorisation entries used +to secure +.BR Xorg (1) . +If this environment is not set then +.B sx +will create and use +.IR \%$XDG_CONFIG_HOME/sx/xauthfile +instead. + +.SH FILES +.TP +.BR $XDG_CONFIG_HOME/sx/sxrc " " "" ( $HOME/.config/sx/sxrc ) +The default client started by +.BR sx . +This file must be executable. +.TP +.BR $XDG_DATA_HOME/sx " " "" ( $HOME/.local/share/sx ) +This directory is used for storing the logs generated by +.BR Xorg (1) . +Each log is named numerically based on the +.B DISPLAY +environment. + +.SH SOURCE +.UR https://github.com/Earnestly/sx +.UE + +.SH SEE ALSO +.BR xinit (1), +.BR startx (1), +.BR Xserver (1), +.BR X (7)