devtools/data/xvfb-run.sh
branchstable
changeset 8261 d4d9c88d4a5f
child 8327 4d76492508f3
equal deleted inserted replaced
8257:d54fc706d623 8261:d4d9c88d4a5f
       
     1 #!/bin/sh
       
     2 
       
     3 # $Id: xvfb-run 2027 2004-11-16 14:54:16Z branden $
       
     4 
       
     5 # This script starts an instance of Xvfb, the "fake" X server, runs a command
       
     6 # with that server available, and kills the X server when done.  The return
       
     7 # value of the command becomes the return value of this script.
       
     8 #
       
     9 # If anyone is using this to build a Debian package, make sure the package
       
    10 # Build-Depends on xvfb, xbase-clients, and xfonts-base.
       
    11 
       
    12 set -e
       
    13 
       
    14 PROGNAME=xvfb-run
       
    15 SERVERNUM=99
       
    16 AUTHFILE=
       
    17 ERRORFILE=/dev/null
       
    18 STARTWAIT=3
       
    19 XVFBARGS="-screen 0 640x480x8"
       
    20 LISTENTCP="-nolisten tcp"
       
    21 XAUTHPROTO=.
       
    22 
       
    23 # Query the terminal to establish a default number of columns to use for
       
    24 # displaying messages to the user.  This is used only as a fallback in the event
       
    25 # the COLUMNS variable is not set.  ($COLUMNS can react to SIGWINCH while the
       
    26 # script is running, and this cannot, only being calculated once.)
       
    27 DEFCOLUMNS=$(stty size 2>/dev/null | awk '{print $2}') || true
       
    28 if ! expr "$DEFCOLUMNS" : "[[:digit:]]\+$" >/dev/null 2>&1; then
       
    29     DEFCOLUMNS=80
       
    30 fi
       
    31 
       
    32 # Display a message, wrapping lines at the terminal width.
       
    33 message () {
       
    34     echo "$PROGNAME: $*" | fmt -t -w ${COLUMNS:-$DEFCOLUMNS}
       
    35 }
       
    36 
       
    37 # Display an error message.
       
    38 error () {
       
    39     message "error: $*" >&2
       
    40 }
       
    41 
       
    42 # Display a usage message.
       
    43 usage () {
       
    44     if [ -n "$*" ]; then
       
    45         message "usage error: $*"
       
    46     fi
       
    47     cat <<EOF
       
    48 Usage: $PROGNAME [OPTION ...] COMMAND
       
    49 Run COMMAND (usually an X client) in a virtual X server environment.
       
    50 Options:
       
    51 -a        --auto-servernum          try to get a free server number, starting at
       
    52                                     --server-num
       
    53 -e FILE   --error-file=FILE         file used to store xauth errors and Xvfb
       
    54                                     output (default: $ERRORFILE)
       
    55 -f FILE   --auth-file=FILE          file used to store auth cookie
       
    56                                     (default: ./.Xauthority)
       
    57 -h        --help                    display this usage message and exit
       
    58 -n NUM    --server-num=NUM          server number to use (default: $SERVERNUM)
       
    59 -l        --listen-tcp              enable TCP port listening in the X server
       
    60 -p PROTO  --xauth-protocol=PROTO    X authority protocol name to use
       
    61                                     (default: xauth command's default)
       
    62 -s ARGS   --server-args=ARGS        arguments (other than server number and
       
    63                                     "-nolisten tcp") to pass to the Xvfb server
       
    64                                     (default: "$XVFBARGS")
       
    65 -w DELAY  --wait=DELAY              delay in seconds to wait for Xvfb to start
       
    66                                     before running COMMAND (default: $STARTWAIT)
       
    67 EOF
       
    68 }
       
    69 
       
    70 # Find a free server number by looking at .X*-lock files in /tmp.
       
    71 find_free_servernum() {
       
    72     # Sadly, the "local" keyword is not POSIX.  Leave the next line commented in
       
    73     # the hope Debian Policy eventually changes to allow it in /bin/sh scripts
       
    74     # anyway.
       
    75     #local i
       
    76 
       
    77     i=$SERVERNUM
       
    78     while [ -f /tmp/.X$i-lock ]; do
       
    79         i=$(($i + 1))
       
    80     done
       
    81     echo $i
       
    82 }
       
    83 
       
    84 # Clean up files
       
    85 clean_up() {
       
    86     if [ -e "$AUTHFILE" ]; then
       
    87         XAUTHORITY=$AUTHFILE xauth remove ":$SERVERNUM" >>"$ERRORFILE" 2>&1
       
    88     fi
       
    89     if [ -n "$XVFB_RUN_TMPDIR" ]; then
       
    90         if ! rm -r "$XVFB_RUN_TMPDIR"; then
       
    91             error "problem while cleaning up temporary directory"
       
    92             exit 5
       
    93         fi
       
    94     fi
       
    95     if [ -n "$XVFBPID" ]; then
       
    96         kill $XVFBPID
       
    97     fi
       
    98 }
       
    99 
       
   100 # Parse the command line.
       
   101 ARGS=$(getopt --options +ae:f:hn:lp:s:w: \
       
   102        --long auto-servernum,error-file:,auth-file:,help,server-num:,listen-tcp,xauth-protocol:,server-args:,wait: \
       
   103        --name "$PROGNAME" -- "$@")
       
   104 GETOPT_STATUS=$?
       
   105 
       
   106 if [ $GETOPT_STATUS -ne 0 ]; then
       
   107     error "internal error; getopt exited with status $GETOPT_STATUS"
       
   108     exit 6
       
   109 fi
       
   110 
       
   111 eval set -- "$ARGS"
       
   112 
       
   113 while :; do
       
   114     case "$1" in
       
   115         -a|--auto-servernum) SERVERNUM=$(find_free_servernum); AUTONUM="yes" ;;
       
   116         -e|--error-file) ERRORFILE="$2"; shift ;;
       
   117         -f|--auth-file) AUTHFILE="$2"; shift ;;
       
   118         -h|--help) SHOWHELP="yes" ;;
       
   119         -n|--server-num) SERVERNUM="$2"; shift ;;
       
   120         -l|--listen-tcp) LISTENTCP="" ;;
       
   121         -p|--xauth-protocol) XAUTHPROTO="$2"; shift ;;
       
   122         -s|--server-args) XVFBARGS="$2"; shift ;;
       
   123         -w|--wait) STARTWAIT="$2"; shift ;;
       
   124         --) shift; break ;;
       
   125         *) error "internal error; getopt permitted \"$1\" unexpectedly"
       
   126            exit 6
       
   127            ;;
       
   128     esac
       
   129     shift
       
   130 done
       
   131 
       
   132 if [ "$SHOWHELP" ]; then
       
   133     usage
       
   134     exit 0
       
   135 fi
       
   136 
       
   137 if [ -z "$*" ]; then
       
   138     usage "need a command to run" >&2
       
   139     exit 2
       
   140 fi
       
   141 
       
   142 if ! which xauth >/dev/null; then
       
   143     error "xauth command not found"
       
   144     exit 3
       
   145 fi
       
   146 
       
   147 # tidy up after ourselves
       
   148 trap clean_up EXIT
       
   149 
       
   150 # If the user did not specify an X authorization file to use, set up a temporary
       
   151 # directory to house one.
       
   152 if [ -z "$AUTHFILE" ]; then
       
   153     XVFB_RUN_TMPDIR="$(mktemp -d -t $PROGNAME.XXXXXX)"
       
   154     # Create empty file to avoid xauth warning
       
   155     AUTHFILE=$(tempfile -n "$XVFB_RUN_TMPDIR/Xauthority")
       
   156 fi
       
   157 
       
   158 # Start Xvfb.
       
   159 MCOOKIE=$(mcookie)
       
   160 tries=10
       
   161 while [ $tries -gt 0 ]; do
       
   162     tries=$(( $tries - 1 ))
       
   163     XAUTHORITY=$AUTHFILE xauth source - << EOF >>"$ERRORFILE" 2>&1
       
   164 add :$SERVERNUM $XAUTHPROTO $MCOOKIE
       
   165 EOF
       
   166     XAUTHORITY=$AUTHFILE Xvfb ":$SERVERNUM" $XVFBARGS $LISTENTCP >>"$ERRORFILE" 2>&1 &
       
   167     XVFBPID=$!
       
   168 
       
   169     sleep "$STARTWAIT"
       
   170     if kill -0 $XVFBPID 2>/dev/null; then
       
   171         break
       
   172     elif [ -n "$AUTONUM" ]; then
       
   173         # The display is in use so try another one (if '-a' was specified).
       
   174         SERVERNUM=$((SERVERNUM + 1))
       
   175         SERVERNUM=$(find_free_servernum)
       
   176         continue
       
   177     fi
       
   178     error "Xvfb failed to start" >&2
       
   179     exit 1
       
   180 done
       
   181 
       
   182 # Start the command and save its exit status.
       
   183 set +e
       
   184 DISPLAY=:$SERVERNUM XAUTHORITY=$AUTHFILE "$@" 2>&1
       
   185 RETVAL=$?
       
   186 set -e
       
   187 
       
   188 # Return the executed command's exit status.
       
   189 exit $RETVAL
       
   190 
       
   191 # vim:set ai et sts=4 sw=4 tw=80: