Browse Source

child_process_uv: add exec, fix simple/test-child-process-exec-cwd

v0.7.4-release
Ryan Dahl 14 years ago
parent
commit
19a62589b2
  1. 5
      Makefile
  2. 119
      lib/child_process_uv.js
  3. 2
      src/process_wrap.cc
  4. 9
      test/simple/test-child-process-exec-env.js

5
Makefile

@ -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

119
lib/child_process_uv.js

@ -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();

2
src/process_wrap.cc

@ -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);
}

9
test/simple/test-child-process-exec-env.js

@ -26,8 +26,7 @@ var success_count = 0;
var error_count = 0;
var response = '';
var child = exec('/usr/bin/env', {env: {'HELLO': 'WORLD'}},
function(err, stdout, stderr) {
function after(err, stdout, stderr) {
if (err) {
error_count++;
console.log('error!: ' + err.code);
@ -38,15 +37,17 @@ var child = exec('/usr/bin/env', {env: {'HELLO': 'WORLD'}},
success_count++;
assert.equal(true, stdout != '');
}
});
}
child.stdout.setEncoding('utf8');
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);

Loading…
Cancel
Save