mirror of
https://github.com/nodejs/node.git
synced 2026-11-09 15:11:11 -05:00
child_process_uv: add exec, fix simple/test-child-process-exec-cwd
This commit is contained in:
1 parent
4ac633bf21
commit
19a62589b2
4 files changed
+138
-17
No files matched your search
@@ -234,8 +234,9 @@ UVTEST += simple/test-tls-request-timeout
|
||||
UVTEST += simple/test-tls-set-encoding
|
||||
|
||||
# child_process
|
||||
UVTEST += simple/test-child-process-exit-code.js
|
||||
UVTEST += simple/test-child-process-buffering.js
|
||||
UVTEST += simple/test-child-process-exit-code
|
||||
UVTEST += simple/test-child-process-buffering
|
||||
UVTEST += simple/test-child-process-exec-cwd
|
||||
|
||||
|
||||
test-uv: all
|
||||
|
||||
@@ -47,6 +47,125 @@ function createSocket(pipe, readable) {
|
||||
}
|
||||
|
||||
|
||||
exports.exec = function(command /*, options, callback */) {
|
||||
var rest = Array.prototype.slice.call(arguments, 1);
|
||||
var args = ['/bin/sh', ['-c', command]].concat(rest);
|
||||
return exports.execFile.apply(this, args);
|
||||
};
|
||||
|
||||
|
||||
exports.execFile = function(file /* args, options, callback */) {
|
||||
var args, optionArg, callback;
|
||||
var options = {
|
||||
encoding: 'utf8',
|
||||
timeout: 0,
|
||||
maxBuffer: 200 * 1024,
|
||||
killSignal: 'SIGTERM',
|
||||
setsid: false,
|
||||
cwd: null,
|
||||
env: null
|
||||
};
|
||||
|
||||
// Parse the parameters.
|
||||
|
||||
if (typeof arguments[arguments.length - 1] === 'function') {
|
||||
callback = arguments[arguments.length - 1];
|
||||
}
|
||||
|
||||
if (Array.isArray(arguments[1])) {
|
||||
args = arguments[1];
|
||||
if (typeof arguments[2] === 'object') optionArg = arguments[2];
|
||||
} else {
|
||||
args = [];
|
||||
if (typeof arguments[1] === 'object') optionArg = arguments[1];
|
||||
}
|
||||
|
||||
// Merge optionArg into options
|
||||
if (optionArg) {
|
||||
var keys = Object.keys(options);
|
||||
for (var i = 0, len = keys.length; i < len; i++) {
|
||||
var k = keys[i];
|
||||
if (optionArg[k] !== undefined) options[k] = optionArg[k];
|
||||
}
|
||||
}
|
||||
|
||||
var child = spawn(file, args, {
|
||||
cwd: options.cwd,
|
||||
env: options.env
|
||||
});
|
||||
|
||||
var stdout = '';
|
||||
var stderr = '';
|
||||
var killed = false;
|
||||
var exited = false;
|
||||
var timeoutId;
|
||||
|
||||
var err;
|
||||
|
||||
function exithandler(code, signal) {
|
||||
if (exited) return;
|
||||
exited = true;
|
||||
|
||||
if (timeoutId) {
|
||||
clearTimeout(timeoutId);
|
||||
timeoutId = null;
|
||||
}
|
||||
|
||||
if (!callback) return;
|
||||
|
||||
if (err) {
|
||||
callback(err, stdout, stderr);
|
||||
} else if (code === 0 && signal === null) {
|
||||
callback(null, stdout, stderr);
|
||||
} else {
|
||||
var e = new Error('Command failed: ' + stderr);
|
||||
e.killed = child.killed || killed;
|
||||
e.code = code;
|
||||
e.signal = signal;
|
||||
callback(e, stdout, stderr);
|
||||
}
|
||||
}
|
||||
|
||||
function kill() {
|
||||
killed = true;
|
||||
child.kill(options.killSignal);
|
||||
process.nextTick(function() {
|
||||
exithandler(null, options.killSignal);
|
||||
});
|
||||
}
|
||||
|
||||
if (options.timeout > 0) {
|
||||
timeoutId = setTimeout(function() {
|
||||
kill();
|
||||
timeoutId = null;
|
||||
}, options.timeout);
|
||||
}
|
||||
|
||||
child.stdout.setEncoding(options.encoding);
|
||||
child.stderr.setEncoding(options.encoding);
|
||||
|
||||
child.stdout.addListener('data', function(chunk) {
|
||||
stdout += chunk;
|
||||
if (stdout.length > options.maxBuffer) {
|
||||
err = new Error('maxBuffer exceeded.');
|
||||
kill();
|
||||
}
|
||||
});
|
||||
|
||||
child.stderr.addListener('data', function(chunk) {
|
||||
stderr += chunk;
|
||||
if (stderr.length > options.maxBuffer) {
|
||||
err = new Error('maxBuffer exceeded.');
|
||||
kill();
|
||||
}
|
||||
});
|
||||
|
||||
child.addListener('exit', exithandler);
|
||||
|
||||
return child;
|
||||
};
|
||||
|
||||
|
||||
var spawn = exports.spawn = function(file, args, options) {
|
||||
var child = new ChildProcess();
|
||||
|
||||
|
||||
+1
-1
@@ -106,7 +106,7 @@ class ProcessWrap : public HandleWrap {
|
||||
// options.cwd
|
||||
Local<Value> cwd_v = js_options->Get(String::New("cwd"));
|
||||
if (!cwd_v.IsEmpty() && cwd_v->IsString()) {
|
||||
String::Utf8Value cwd(js_options->ToString());
|
||||
String::Utf8Value cwd(cwd_v->ToString());
|
||||
options.cwd = strdup(*cwd);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,27 +26,28 @@ var success_count = 0;
|
||||
var error_count = 0;
|
||||
var response = '';
|
||||
|
||||
var child = exec('/usr/bin/env', {env: {'HELLO': 'WORLD'}},
|
||||
function(err, stdout, stderr) {
|
||||
if (err) {
|
||||
error_count++;
|
||||
console.log('error!: ' + err.code);
|
||||
console.log('stdout: ' + JSON.stringify(stdout));
|
||||
console.log('stderr: ' + JSON.stringify(stderr));
|
||||
assert.equal(false, err.killed);
|
||||
} else {
|
||||
success_count++;
|
||||
assert.equal(true, stdout != '');
|
||||
}
|
||||
});
|
||||
function after(err, stdout, stderr) {
|
||||
if (err) {
|
||||
error_count++;
|
||||
console.log('error!: ' + err.code);
|
||||
console.log('stdout: ' + JSON.stringify(stdout));
|
||||
console.log('stderr: ' + JSON.stringify(stderr));
|
||||
assert.equal(false, err.killed);
|
||||
} else {
|
||||
success_count++;
|
||||
assert.equal(true, stdout != '');
|
||||
}
|
||||
}
|
||||
|
||||
var child = exec('/usr/bin/env', { env: { 'HELLO': 'WORLD' } }, after);
|
||||
|
||||
child.stdout.setEncoding('utf8');
|
||||
|
||||
child.stdout.addListener('data', function(chunk) {
|
||||
response += chunk;
|
||||
});
|
||||
|
||||
process.addListener('exit', function() {
|
||||
console.log("response: ", response);
|
||||
assert.equal(1, success_count);
|
||||
assert.equal(0, error_count);
|
||||
assert.ok(response.indexOf('HELLO=WORLD') >= 0);
|
||||
|
||||
Reference in new issue
Block a user