/
child-process.js
97 lines (84 loc) · 2.62 KB
/
child-process.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// vim: expandtab:ts=2:sw=2
var
fs = require('fs'),
path = require('path'),
existsSync = fs.existsSync || path.existsSync,
spawn = require('child_process').spawn;
module.exports.genericChildProcess = function spawnGenericChildProcess(configFile, cb) {
var
configFilePath = path.join(__dirname, 'outband', configFile),
command_args = [path.join(__dirname, 'spawn-generic.js'), configFilePath];
// make sure that the config file exists
if (!existsSync(configFilePath))
return cb(new Error('ENOENT: configFile ' + configFilePath + ' does not exist'));
_do_spawn(command_args, cb);
};
module.exports.childProcess = function spawnChildProcess(configFile, cb, detach) {
var
configFilePath = path.join(__dirname, 'outband', configFile),
command_args = [path.join(__dirname, 'spawn-custom.js'), configFilePath];
// make sure that the config file exists
if (!existsSync(configFilePath))
return cb(new Error('ENOENT: configFile ' + configFilePath + ' does not exist'));
if (arguments.length > 2) {
for (var i=2; i<arguments.length; i++) {
command_args.push(arguments[i]);
}
}
_do_spawn(command_args, cb, detach);
}
function _do_spawn(command_args, cb, detach) {
var
node_path = process.argv[0],
stdoutBufs = [],
stderrBufs = [],
child,
done = false,
stderrDone = false,
stdoutDone = false;
// spawn doesn’t have the quoting problems that exec does,
// especially when going for Windows portability.
child = spawn(node_path, command_args, detach ? { detached:true } : undefined);
child.stdin.end();
// TODO:we no longer support node 0.6
// Cannot use 'close' event because not on node-0.6.
function _close() {
var
stderr = _bufferConcat(stderrBufs).toString(),
stdout = _bufferConcat(stdoutBufs).toString();
if (stderrDone && stdoutDone && !done) {
done = true;
cb(null, stderr, stdout);
}
}
child.on('error', function _spawnError(err) {
if (!done) {
done = true;
cb(err);
}
});
child.stdout.on('data', function _stdoutData(data) {
stdoutBufs.push(data);
}).on('close', function _stdoutEnd() {
stdoutDone = true;
_close();
});
child.stderr.on('data', function _stderrData(data) {
stderrBufs.push(data);
}).on('close', function _stderrEnd() {
stderrDone = true;
_close();
});
}
function _bufferConcat(buffers) {
if (Buffer.concat) {
return Buffer.concat.apply(this, arguments);
} else {
return new Buffer(buffers.reduce(function (acc, buf) {
for (var i = 0; i < buf.length; i++) {
acc.push(buf[i]);
}
return acc;
}, []));
}
}