introduce sx

This commit is contained in:
Earnestly 2017-12-01 20:14:54 +00:00
commit 161b8be6f5
5 changed files with 223 additions and 0 deletions

19
LICENSE Normal file
View File

@ -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.

9
Makefile Normal file
View File

@ -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

56
README Normal file
View File

@ -0,0 +1,56 @@
sx <https://github.com/Earnestly/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

81
sx Executable file
View File

@ -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

58
sx.1 Normal file
View File

@ -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)