def __init__(self): tmpdir = mkdtemp(prefix='XvfbServer.', dir=Workspace.get_base_tempdir()) for servernum in range(os.getpid(), 65536): if os.path.exists('/tmp/.X{0}-lock'.format(servernum)): continue self.display = ':' + str(servernum) self.authfile = os.path.join(tmpdir, 'Xauthority.' + self.display) mcookie = codecs.encode(os.urandom(16), "hex_codec") subprocess.check_call([ 'xauth', '-f', self.authfile, 'add', self.display, '.', mcookie ]) errfile = os.path.join(tmpdir, 'Xvfb.' + self.display + '.err') with open( errfile, 'w' ) as f: # use a file instead of a pipe to simplify polling p = subprocess.Popen( [self.xvfb_command, self.display, '-fbdir', tmpdir] + self.xvfb_args, stderr=f, env=dict(os.environ, XAUTHORITY=self.authfile)) self.fbmem = os.path.join(tmpdir, 'Xvfb_screen0') while not os.path.exists(self.fbmem): if p.poll() is not None: break time.sleep(0.1) else: p.poll() if p.returncode is not None: with open(errfile) as f: err = f.read() if 'Server is already active for display' in err: continue else: raise RuntimeError('Failed to start Xvfb', p.returncode, err) print('Xvfb started in ' + tmpdir) # for debugging self.process = p # If we terminate abnormally, ensure the Xvfb server is cleaned up after us. self._cleanup_script = subprocess.Popen(""" while kill -0 {0} 2>/dev/null; do sleep 1; done kill -INT {1} while kill -0 {1} 2>/dev/null; do sleep 1; done """.format(os.getpid(), p.pid), shell=True) break else: raise RuntimeError( 'Unable to find a free server number to start Xvfb')
def __init__(self): tmpdir = mkdtemp(prefix='XvfbServer.', dir=Workspace.get_base_tempdir()) for servernum in range(os.getpid(), 65536): if os.path.exists('/tmp/.X{0}-lock'.format(servernum)): continue self.display = ':' + str(servernum) self.authfile = os.path.join(tmpdir, 'Xauthority.' + self.display) mcookie = codecs.encode(os.urandom(16), "hex_codec") subprocess.check_call(['xauth', '-f', self.authfile, 'add', self.display, '.', mcookie]) errfile = os.path.join(tmpdir, 'Xvfb.' + self.display + '.err') with open(errfile, 'w') as f: # use a file instead of a pipe to simplify polling p = subprocess.Popen([self.xvfb_command, self.display, '-fbdir', tmpdir] + self.xvfb_args, stderr=f, env=dict(os.environ, XAUTHORITY=self.authfile)) self.fbmem = os.path.join(tmpdir, 'Xvfb_screen0') while not os.path.exists(self.fbmem): if p.poll() is not None: break time.sleep(0.1) else: p.poll() if p.returncode is not None: with open(errfile) as f: err = f.read() if 'Server is already active for display' in err: continue else: raise RuntimeError('Failed to start Xvfb', p.returncode, err) print('Xvfb started in ' + tmpdir) # for debugging self.process = p # If we terminate abnormally, ensure the Xvfb server is cleaned up after us. self._cleanup_script = subprocess.Popen(""" while kill -0 {0} 2>/dev/null; do sleep 1; done kill -INT {1} while kill -0 {1} 2>/dev/null; do sleep 1; done """.format(os.getpid(), p.pid), shell=True) break else: raise RuntimeError('Unable to find a free server number to start Xvfb')