2015-02-10 19:41:24 +00:00
|
|
|
var Consumer = require('vfs-socket/consumer').Consumer;
|
|
|
|
var inherits = require('util').inherits;
|
|
|
|
var spawn = require('child_process').spawn;
|
|
|
|
|
|
|
|
exports.Parent = Parent;
|
|
|
|
|
|
|
|
function Parent(fsOptions) {
|
|
|
|
Consumer.call(this);
|
|
|
|
var options = {};
|
|
|
|
if (fsOptions.hasOwnProperty("gid")) {
|
|
|
|
options.gid = fsOptions.gid;
|
|
|
|
delete fsOptions.gid;
|
|
|
|
}
|
|
|
|
if (fsOptions.hasOwnProperty("uid")) {
|
|
|
|
options.uid = fsOptions.uid;
|
|
|
|
delete fsOptions.uid;
|
|
|
|
}
|
2015-05-01 08:14:25 +00:00
|
|
|
options.stdio = options.customFds = [-1, -1, 2];
|
2015-02-10 19:41:24 +00:00
|
|
|
var args = [require.resolve('./child.js'), JSON.stringify(fsOptions)];
|
2015-05-09 23:42:13 +00:00
|
|
|
var nodeBin = fsOptions.nodeBin || [process.execPath];
|
2015-02-10 19:41:24 +00:00
|
|
|
var child;
|
|
|
|
|
|
|
|
// Override Consumer's connect since the transport logic is internal to this module
|
|
|
|
this.connect = connect.bind(this);
|
|
|
|
function connect(callback) {
|
2015-07-25 19:42:50 +00:00
|
|
|
try {
|
|
|
|
child = spawn(nodeBin[0], args, options).on("error", tryNext);
|
|
|
|
}
|
|
|
|
catch (e) {
|
|
|
|
return tryNext(e);
|
|
|
|
}
|
2015-02-10 19:41:24 +00:00
|
|
|
child.stdin.readable = true;
|
2015-05-09 23:42:13 +00:00
|
|
|
Consumer.prototype.connect.call(this, [child.stdout, child.stdin], tryNext);
|
2015-02-10 19:41:24 +00:00
|
|
|
child.on("exit", disconnect);
|
2015-05-09 23:42:13 +00:00
|
|
|
child.stdin.resume();
|
|
|
|
var _self = this;
|
|
|
|
// try all possible locations of node before giving up
|
|
|
|
function tryNext(err, vfs) {
|
|
|
|
if (!child) return;
|
|
|
|
child.removeListener("error", tryNext);
|
2015-07-25 19:42:50 +00:00
|
|
|
child.on("error", function ignore() {});
|
2015-05-09 23:42:13 +00:00
|
|
|
if (err && err.code == "ENOENT" && nodeBin.length > 1) {
|
|
|
|
child = null;
|
|
|
|
nodeBin.shift();
|
|
|
|
_self.emit("error", err);
|
|
|
|
_self.connect(callback);
|
|
|
|
} else {
|
|
|
|
callback(err, vfs);
|
|
|
|
}
|
|
|
|
}
|
2015-02-10 19:41:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Override Consumer's disconnect to kill the child process afterwards
|
|
|
|
this.disconnect = disconnect.bind(this);
|
|
|
|
function disconnect() {
|
|
|
|
if (!this.transport) return;
|
|
|
|
Consumer.prototype.disconnect.apply(this, arguments);
|
|
|
|
child.kill();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fsOptions.inProcess) {
|
|
|
|
this.connect = function(callback) {
|
|
|
|
var vfs = require('vfs-local')(fsOptions);
|
|
|
|
setImmediate(function(){
|
|
|
|
callback(null, vfs);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
inherits(Parent, Consumer);
|
|
|
|
|