The prior commit 666b87e would still fail if the sx program itself was
killed leaving an xorg server behind. While trap handlers aren't
typically allowed to change the exit status, if we explicitly exit with
a value then it is honoured.
This works around the subshell setting an exit status of 138 (due to
SIGUSR1) by explicitly using the return value from the last wait or the
last command if the server never started at all.
Due to the use of errexit when Xorg replied back to us with SIGUSR1 the
subshell would return an exit status of 128 + 10 (SIGUSR1)[1].
This combined with trap handlers not changing the exit value unless
explicitly done with exit $? means sx was always exiting with a status
of 138.
This change instead removes errexit and simply lets unset or erroneous
commands leak through until it hits a point where the combined errors
result in non-zero termination.
By splitting out the termination of Xorg to the end we can simply return
the return value from the last wait, which is the wait associated with
Xorg itself.
1. http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_28
Sending SIGKILL is not an appropriate response in most cases especially
after an arbitrary timeout. If signals are being ignored it's likely
due to D state. If the process is busy spinning in an infinite loop
then bug reports need to be made. Papering over significant issues is
worse for everyone in the end.
This commit also trusts the PID we get is an xorg server process. I
have no real reason to check outside of paranoia which borders on theater.
Instead I check the PID is still alive and send TERM. Then we wait
until it is done. Anything else is surely abnormal and needs manual
intervention.
This condition will always be triggered even if the Xorg server
terminates promptly. This will simply result in confusing diagnostics
being printed in the common case. As kill has no quiet option, I will
have to unfortunately silence them instead.
I was under the false assumption that -a, like &&, was used
short-circuit semantics. However the behaviour of -a is not specified
by POSIX.
At least on Linux using bash or dash the behaviour is not
short-circuiting.
As there's no reason to test the RHS if the LHS is false I've switched
back to [ ] && notation which is defined to be short-circuiting.
Turns out openssl rand would obnoxiously create a HOME/.rnd dotfile
unless told otherwise with the RANDFILE environment. Unfortunately
this neither options are compelling and neither can openssl rand be
told to not write this file.
Instead I'm going to use /dev/urandom which appears to be available
on practically every UNIX.
This commit also tidies up the timeout kill logic to better express
what I am doing.
Upon review of GNU tail I discovered that the implemention of --pid was
the same method as polling kill -0 on a sleep interval, which defaults
to 1 second unless -s is used.
This is perhaps expected due to the lack of a pwait(2) system call, I
decided to implement the same mechanic myself and drop both the
requirement on GNU tail and GNU timeout at the same time.
This commit also replaces mcookie from util-linux with openssl rand
which is used to generate a random MD5 checksum for use in the
MIT-MAGIC-COOKIE-1 value.
We need to do this in sx as neither xauth(1) or touch(1) will create the
path. Requiring the user to do this would lead to additional code on
their side to account for a detail that sx already controls. There
is no obvious benefit for omitting this functionality.
There's not a lot of point in absorbing the xserver's log file when it
will just be less intuitive for those looking for it in the standard
location. Since the log is generated by Xorg and not sx, it only seems
reasonable.
This commit also renames xauthfile to xauthority for a little more
consistency with documentation and prior art.
Xorg.wrap default system of autodetection of root rights requirement is
wrong in every case I've seen it used. The result is the Xorg server
runs as the root user when it is not necessary.
The main autodetection failure case is when the proprietary nvidia
drivers are used, incorrectly assuming Xorg needs to be run as root.