Annotation of /trunk/xorg-server/xvfb-run
Parent Directory | Revision Log
Revision 2694 -
(hide annotations)
(download)
Mon Sep 14 09:16:37 2015 UTC (9 years ago) by niro
File size: 5432 byte(s)
Mon Sep 14 09:16:37 2015 UTC (9 years ago) by niro
File size: 5432 byte(s)
-added xvfb-run script
1 | niro | 2694 | #!/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 | } | ||
96 | |||
97 | # Parse the command line. | ||
98 | ARGS=$(getopt --options +ae:f:hn:lp:s:w: \ | ||
99 | --long auto-servernum,error-file:,auth-file:,help,server-num:,listen-tcp,xauth-protocol:,server-args:,wait: \ | ||
100 | --name "$PROGNAME" -- "$@") | ||
101 | GETOPT_STATUS=$? | ||
102 | |||
103 | if [ $GETOPT_STATUS -ne 0 ]; then | ||
104 | error "internal error; getopt exited with status $GETOPT_STATUS" | ||
105 | exit 6 | ||
106 | fi | ||
107 | |||
108 | eval set -- "$ARGS" | ||
109 | |||
110 | while :; do | ||
111 | case "$1" in | ||
112 | -a|--auto-servernum) SERVERNUM=$(find_free_servernum) ;; | ||
113 | -e|--error-file) ERRORFILE="$2"; shift ;; | ||
114 | -f|--auth-file) AUTHFILE="$2"; shift ;; | ||
115 | -h|--help) SHOWHELP="yes" ;; | ||
116 | -n|--server-num) SERVERNUM="$2"; shift ;; | ||
117 | -l|--listen-tcp) LISTENTCP="" ;; | ||
118 | -p|--xauth-protocol) XAUTHPROTO="$2"; shift ;; | ||
119 | -s|--server-args) XVFBARGS="$2"; shift ;; | ||
120 | -w|--wait) STARTWAIT="$2"; shift ;; | ||
121 | --) shift; break ;; | ||
122 | *) error "internal error; getopt permitted \"$1\" unexpectedly" | ||
123 | exit 6 | ||
124 | ;; | ||
125 | esac | ||
126 | shift | ||
127 | done | ||
128 | |||
129 | if [ "$SHOWHELP" ]; then | ||
130 | usage | ||
131 | exit 0 | ||
132 | fi | ||
133 | |||
134 | if [ -z "$*" ]; then | ||
135 | usage "need a command to run" >&2 | ||
136 | exit 2 | ||
137 | fi | ||
138 | |||
139 | if ! which xauth >/dev/null; then | ||
140 | error "xauth command not found" | ||
141 | exit 3 | ||
142 | fi | ||
143 | |||
144 | # tidy up after ourselves | ||
145 | trap clean_up EXIT | ||
146 | |||
147 | # If the user did not specify an X authorization file to use, set up a temporary | ||
148 | # directory to house one. | ||
149 | if [ -z "$AUTHFILE" ]; then | ||
150 | XVFB_RUN_TMPDIR="$(mktemp -d -t $PROGNAME.XXXXXX)" | ||
151 | AUTHFILE="$XVFB_RUN_TMPDIR/Xauthority" | ||
152 | fi | ||
153 | |||
154 | # Start Xvfb. | ||
155 | MCOOKIE=$(mcookie) | ||
156 | XAUTHORITY=$AUTHFILE xauth source - << EOF >>"$ERRORFILE" 2>&1 | ||
157 | add :$SERVERNUM $XAUTHPROTO $MCOOKIE | ||
158 | EOF | ||
159 | XAUTHORITY=$AUTHFILE Xvfb ":$SERVERNUM" $XVFBARGS $LISTENTCP >>"$ERRORFILE" \ | ||
160 | 2>&1 & | ||
161 | XVFBPID=$! | ||
162 | sleep "$STARTWAIT" | ||
163 | if ! kill -0 $XVFBPID 2>/dev/null; then | ||
164 | echo "Xvfb failed to start" >&2 | ||
165 | exit 1 | ||
166 | fi | ||
167 | |||
168 | # Start the command and save its exit status. | ||
169 | set +e | ||
170 | DISPLAY=:$SERVERNUM XAUTHORITY=$AUTHFILE "$@" 2>&1 | ||
171 | RETVAL=$? | ||
172 | set -e | ||
173 | |||
174 | # Kill Xvfb now that the command has exited. | ||
175 | kill $XVFBPID | ||
176 | |||
177 | # Return the executed command's exit status. | ||
178 | exit $RETVAL | ||
179 | |||
180 | # vim:set ai et sts=4 sw=4 tw=80: |