1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/tests/xvfb-run Fri Jul 08 08:26:29 2016 +0100
1.3 @@ -0,0 +1,190 @@
1.4 +#!/bin/sh
1.5 +
1.6 +# This script starts an instance of Xvfb, the "fake" X server, runs a command
1.7 +# with that server available, and kills the X server when done. The return
1.8 +# value of the command becomes the return value of this script.
1.9 +#
1.10 +# If anyone is using this to build a Debian package, make sure the package
1.11 +# Build-Depends on xvfb and xauth.
1.12 +
1.13 +set -e
1.14 +
1.15 +PROGNAME=xvfb-run
1.16 +SERVERNUM=99
1.17 +AUTHFILE=
1.18 +ERRORFILE=/dev/null
1.19 +XVFBARGS="-screen 0 640x480x8"
1.20 +LISTENTCP="-nolisten tcp"
1.21 +XAUTHPROTO=.
1.22 +
1.23 +# Query the terminal to establish a default number of columns to use for
1.24 +# displaying messages to the user. This is used only as a fallback in the event
1.25 +# the COLUMNS variable is not set. ($COLUMNS can react to SIGWINCH while the
1.26 +# script is running, and this cannot, only being calculated once.)
1.27 +DEFCOLUMNS=$(stty size 2>/dev/null | awk '{print $2}') || true
1.28 +if ! expr "$DEFCOLUMNS" : "[[:digit:]]\+$" >/dev/null 2>&1; then
1.29 + DEFCOLUMNS=80
1.30 +fi
1.31 +
1.32 +# Display a message, wrapping lines at the terminal width.
1.33 +message () {
1.34 + echo "$PROGNAME: $*" | fmt -t -w ${COLUMNS:-$DEFCOLUMNS}
1.35 +}
1.36 +
1.37 +# Display an error message.
1.38 +error () {
1.39 + message "error: $*" >&2
1.40 +}
1.41 +
1.42 +# Display a usage message.
1.43 +usage () {
1.44 + if [ -n "$*" ]; then
1.45 + message "usage error: $*"
1.46 + fi
1.47 + cat <<EOF
1.48 +Usage: $PROGNAME [OPTION ...] COMMAND
1.49 +Run COMMAND (usually an X client) in a virtual X server environment.
1.50 +Options:
1.51 +-a --auto-servernum try to get a free server number, starting at
1.52 + --server-num
1.53 +-e FILE --error-file=FILE file used to store xauth errors and Xvfb
1.54 + output (default: $ERRORFILE)
1.55 +-f FILE --auth-file=FILE file used to store auth cookie
1.56 + (default: ./.Xauthority)
1.57 +-h --help display this usage message and exit
1.58 +-n NUM --server-num=NUM server number to use (default: $SERVERNUM)
1.59 +-l --listen-tcp enable TCP port listening in the X server
1.60 +-p PROTO --xauth-protocol=PROTO X authority protocol name to use
1.61 + (default: xauth command's default)
1.62 +-s ARGS --server-args=ARGS arguments (other than server number and
1.63 + "-nolisten tcp") to pass to the Xvfb server
1.64 + (default: "$XVFBARGS")
1.65 +EOF
1.66 +}
1.67 +
1.68 +# Find a free server number by looking at .X*-lock files in /tmp.
1.69 +find_free_servernum() {
1.70 + # Sadly, the "local" keyword is not POSIX. Leave the next line commented in
1.71 + # the hope Debian Policy eventually changes to allow it in /bin/sh scripts
1.72 + # anyway.
1.73 + #local i
1.74 +
1.75 + i=$SERVERNUM
1.76 + while [ -f /tmp/.X$i-lock ]; do
1.77 + i=$(($i + 1))
1.78 + done
1.79 + echo $i
1.80 +}
1.81 +
1.82 +# Clean up files
1.83 +clean_up() {
1.84 + if [ -e "$AUTHFILE" ]; then
1.85 + XAUTHORITY=$AUTHFILE xauth remove ":$SERVERNUM" >>"$ERRORFILE" 2>&1
1.86 + fi
1.87 + if [ -n "$XVFB_RUN_TMPDIR" ]; then
1.88 + if ! rm -r "$XVFB_RUN_TMPDIR"; then
1.89 + error "problem while cleaning up temporary directory"
1.90 + exit 5
1.91 + fi
1.92 + fi
1.93 + if [ -n "$XVFBPID" ]; then
1.94 + kill "$XVFBPID" >>"$ERRORFILE" 2>&1
1.95 + fi
1.96 +}
1.97 +
1.98 +# Parse the command line.
1.99 +ARGS=$(getopt --options +ae:f:hn:lp:s:w: \
1.100 + --long auto-servernum,error-file:,auth-file:,help,server-num:,listen-tcp,xauth-protocol:,server-args:,wait: \
1.101 + --name "$PROGNAME" -- "$@")
1.102 +GETOPT_STATUS=$?
1.103 +
1.104 +if [ $GETOPT_STATUS -ne 0 ]; then
1.105 + error "internal error; getopt exited with status $GETOPT_STATUS"
1.106 + exit 6
1.107 +fi
1.108 +
1.109 +eval set -- "$ARGS"
1.110 +
1.111 +while :; do
1.112 + case "$1" in
1.113 + -a|--auto-servernum) SERVERNUM=$(find_free_servernum); AUTONUM="yes" ;;
1.114 + -e|--error-file) ERRORFILE="$2"; shift ;;
1.115 + -f|--auth-file) AUTHFILE="$2"; shift ;;
1.116 + -h|--help) SHOWHELP="yes" ;;
1.117 + -n|--server-num) SERVERNUM="$2"; shift ;;
1.118 + -l|--listen-tcp) LISTENTCP="" ;;
1.119 + -p|--xauth-protocol) XAUTHPROTO="$2"; shift ;;
1.120 + -s|--server-args) XVFBARGS="$2"; shift ;;
1.121 + -w|--wait) shift ;;
1.122 + --) shift; break ;;
1.123 + *) error "internal error; getopt permitted \"$1\" unexpectedly"
1.124 + exit 6
1.125 + ;;
1.126 + esac
1.127 + shift
1.128 +done
1.129 +
1.130 +if [ "$SHOWHELP" ]; then
1.131 + usage
1.132 + exit 0
1.133 +fi
1.134 +
1.135 +if [ -z "$*" ]; then
1.136 + usage "need a command to run" >&2
1.137 + exit 2
1.138 +fi
1.139 +
1.140 +if ! which xauth >/dev/null; then
1.141 + error "xauth command not found"
1.142 + exit 3
1.143 +fi
1.144 +
1.145 +# tidy up after ourselves
1.146 +trap clean_up EXIT
1.147 +
1.148 +# If the user did not specify an X authorization file to use, set up a temporary
1.149 +# directory to house one.
1.150 +if [ -z "$AUTHFILE" ]; then
1.151 + XVFB_RUN_TMPDIR="$(mktemp -d -t $PROGNAME.XXXXXX)"
1.152 + # Create empty file to avoid xauth warning
1.153 + AUTHFILE=$(tempfile -n "$XVFB_RUN_TMPDIR/Xauthority")
1.154 +fi
1.155 +
1.156 +# Start Xvfb.
1.157 +MCOOKIE=$(mcookie)
1.158 +tries=10
1.159 +while [ $tries -gt 0 ]; do
1.160 + tries=$(( $tries - 1 ))
1.161 + XAUTHORITY=$AUTHFILE xauth source - << EOF >>"$ERRORFILE" 2>&1
1.162 +add :$SERVERNUM $XAUTHPROTO $MCOOKIE
1.163 +EOF
1.164 + # handle SIGUSR1 so Xvfb knows to send a signal when it's ready to accept
1.165 + # connections
1.166 + trap : USR1
1.167 + (trap '' USR1; exec Xvfb ":$SERVERNUM" $XVFBARGS $LISTENTCP -auth $AUTHFILE >>"$ERRORFILE" 2>&1) &
1.168 + XVFBPID=$!
1.169 +
1.170 + wait || :
1.171 + if kill -0 $XVFBPID 2>/dev/null; then
1.172 + break
1.173 + elif [ -n "$AUTONUM" ]; then
1.174 + # The display is in use so try another one (if '-a' was specified).
1.175 + SERVERNUM=$((SERVERNUM + 1))
1.176 + SERVERNUM=$(find_free_servernum)
1.177 + continue
1.178 + fi
1.179 + error "Xvfb failed to start" >&2
1.180 + XVFBPID=
1.181 + exit 1
1.182 +done
1.183 +
1.184 +# Start the command and save its exit status.
1.185 +set +e
1.186 +DISPLAY=:$SERVERNUM XAUTHORITY=$AUTHFILE "$@" 2>&1
1.187 +RETVAL=$?
1.188 +set -e
1.189 +
1.190 +# Return the executed command's exit status.
1.191 +exit $RETVAL
1.192 +
1.193 +# vim:set ai et sts=4 sw=4 tw=80: