diff --git a/.travis.yml b/.travis.yml index 2b8e294..3218f2b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,10 @@ before_script: - "export DISPLAY=:99.0" - - "sh -e /etc/init.d/xvfb start" + - "/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -nolisten $NOLISTEN" + +env: + - NOLISTEN=tcp + - NOLISTEN=unix language: node_js node_js: diff --git a/lib/xcore.js b/lib/xcore.js index 5766dc6..2a8aa15 100644 --- a/lib/xcore.js +++ b/lib/xcore.js @@ -20,10 +20,9 @@ var coreRequests = require('./corereqs'); var stdatoms = require('./stdatoms'); var em = require('./eventmask').eventMask; -function XClient(stream, displayNum, screenNum, options) +function XClient(displayNum, screenNum, options) { EventEmitter.call(this); - this.stream = stream; this.options = options ? options : {}; // TODO: this is probably not used @@ -33,6 +32,12 @@ function XClient(stream, displayNum, screenNum, options) this.displayNum = displayNum; this.screenNum = screenNum; this.authHost = os.hostname(); +} +util.inherits(XClient, EventEmitter); + +XClient.prototype.init = function(stream) +{ + this.stream = stream; var pack_stream = new PackStream(); @@ -108,7 +113,6 @@ function XClient(stream, displayNum, screenNum, options) this.startHandshake(); this._closing = false; } -util.inherits(XClient, EventEmitter); // TODO: close() = set 'closing' flag, watch it in replies and writeQueue, terminate if empty XClient.prototype.terminate = function() @@ -569,6 +573,8 @@ module.exports.createClient = function(options, initCb) // open stream var stream; + var connected = false; + var cbCalled = false; var socketPath; // try local socket on non-windows platforms @@ -585,18 +591,35 @@ module.exports.createClient = function(options, initCb) socketPath = '/tmp/.X11-unix/X' + displayNum; } //socketPath = '/tmp/.X11-unix/X' + displayNum; - if(socketPath) - { - stream = net.createConnection(socketPath); - } - else - { - stream = net.createConnection(6000 + parseInt(displayNum), host); - } - var client = new XClient(stream, displayNum, screenNum, options); + var client = new XClient(displayNum, screenNum, options); + + var connectStream = function() { + if (socketPath) { + stream = net.createConnection(socketPath); + } else { + stream = net.createConnection(6000 + parseInt(displayNum), host); + } + stream.on('connect', function() { + connected = true; + client.init(stream); + }); + stream.on('error', function(err) { + if (!connected && socketPath && err.code === 'ENOENT') { + // Retry connection with TCP on localhost + socketPath = null; + host = 'localhost'; + connectStream(); + } else if (initCb && !cbCalled) { + cbCalled = true; + initCb(err); + } else { + client.emit('error', err); + } + }); + }; + connectStream(); if (initCb) { - var cbCalled = false; client.on('connect', function(display) { // opt-in BigReq if (!options.disableBigRequests) { @@ -614,14 +637,6 @@ module.exports.createClient = function(options, initCb) initCb(undefined, display); } }); - stream.on('error', function(err) { - if (cbCalled) - client.emit('error', err); - else { - cbCalled = true; - initCb(err); - } - }); } return client; }