diff --git a/nodes/core/core/75-exec.html b/nodes/core/core/75-exec.html
index 0efa61058..713cd9699 100644
--- a/nodes/core/core/75-exec.html
+++ b/nodes/core/core/75-exec.html
@@ -75,12 +75,20 @@
payload string
the standard output of the command.
+
+ - rc object
+ - exec mode only, a copy of the return code object (also available on port 3)
+
Standard error
- payload string
- the standard error of the command.
+
+ - rc object
+ - exec mode only, a copy of the return code object (also available on port 3)
+
Return code
diff --git a/nodes/core/core/75-exec.js b/nodes/core/core/75-exec.js
index 8b10bec28..2638dd1da 100644
--- a/nodes/core/core/75-exec.js
+++ b/nodes/core/core/75-exec.js
@@ -125,14 +125,15 @@ module.exports = function(RED) {
if (node.append.trim() !== "") { cl += " "+node.append; }
/* istanbul ignore else */
if (RED.settings.verbose) { node.log(cl); }
- child = exec(cl, {encoding: 'binary', maxBuffer:10000000}, function (error, stdout, stderr) {
+ child = exec(cl, {encoding:'binary', maxBuffer:10000000}, function (error, stdout, stderr) {
+ var msg2, msg3;
+ delete msg.payload;
+ if (stderr) {
+ msg2 = RED.util.cloneMessage(msg);
+ msg2.payload = stderr;
+ }
msg.payload = Buffer.from(stdout,"binary");
if (isUtf8(msg.payload)) { msg.payload = msg.payload.toString(); }
- var msg2 = null;
- if (stderr) {
- msg2 = {payload: stderr};
- }
- var msg3 = null;
node.status({});
//console.log('[exec] stdout: ' + stdout);
//console.log('[exec] stderr: ' + stderr);
@@ -142,10 +143,15 @@ module.exports = function(RED) {
if (error.code === null) { node.status({fill:"red",shape:"dot",text:"killed"}); }
else { node.status({fill:"red",shape:"dot",text:"error:"+error.code}); }
node.log('error:' + error);
- } else if (node.oldrc === "false") {
+ }
+ else if (node.oldrc === "false") {
msg3 = {payload:{code:0}};
}
if (!msg3) { node.status({}); }
+ else {
+ msg.rc = msg3.payload;
+ if (msg2) { msg2.rc = msg3.payload; }
+ }
node.send([msg,msg2,msg3]);
if (child.tout) { clearTimeout(child.tout); }
delete node.activeProcesses[child.pid];
diff --git a/test/nodes/core/core/75-exec_spec.js b/test/nodes/core/core/75-exec_spec.js
index 10a9f5fd3..c56647bee 100644
--- a/test/nodes/core/core/75-exec_spec.js
+++ b/test/nodes/core/core/75-exec_spec.js
@@ -76,11 +76,15 @@ describe('exec node', function() {
msg.should.have.property("payload");
msg.payload.should.be.a.String();
msg.payload.should.equal("echo");
+ msg.should.have.property("rc");
+ msg.rc.should.have.property("code",0);
msg = messages[1];
msg.should.have.property("payload");
msg.payload.should.be.a.String();
msg.payload.should.equal("ECHO");
+ msg.should.have.property("rc");
+ msg.rc.should.have.property("code",0);
msg = messages[2];
msg.should.have.property("payload");
@@ -88,7 +92,8 @@ describe('exec node', function() {
child_process.exec.restore();
done();
- } catch(err) {
+ }
+ catch(err) {
child_process.exec.restore();
done(err);
}
@@ -136,20 +141,23 @@ describe('exec node', function() {
msg.should.have.property("payload");
msg.payload.should.be.a.String();
msg.payload.should.equal("echo and more");
+ msg.should.have.property("rc");
+ msg.rc.should.have.property("code",0);
msg = messages[1];
msg.should.have.property("payload");
msg.payload.should.be.a.String();
msg.payload.should.equal("ECHO AND MORE");
+ msg.should.have.property("rc");
+ msg.rc.should.have.property("code",0);
child_process.exec.restore();
done();
- } catch(err) {
+ }
+ catch(err) {
child_process.exec.restore();
done(err);
}
};
-
-
n2.on("input", function(msg) {
messages[0] = msg;
completeTest();
@@ -169,7 +177,7 @@ describe('exec node', function() {
function(arg1, arg2, arg3, arg4) {
//console.log(arg1);
// arg3(error,stdout,stderr);
- arg3("error",new Buffer([0x01,0x02,0x03,0x88]));
+ arg3("error",new Buffer([0x01,0x02,0x03,0x88]),new Buffer([0x01,0x02,0x03,0x88]));
});
helper.load(execNode, flow, function() {
var n1 = helper.getNode("n1");
@@ -199,33 +207,11 @@ describe('exec node', function() {
// Although Windows timeout command is equivalent to sleep, this cannot be used because it promptly outputs a message.
flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"ping", addpay:false, append:"192.0.2.0 -n 1 -w 1000 > NUL", timer:"0.3", oldrc:"false"},
{id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}];
- } else {
+ }
+ else {
flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"sleep", addpay:false, append:"1", timer:"0.3", oldrc:"false"},
{id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}];
}
- helper.load(execNode, flow, function() {
- var n1 = helper.getNode("n1");
- var n2 = helper.getNode("n2");
- var n3 = helper.getNode("n3");
- var n4 = helper.getNode("n4");
- n4.on("input", function(msg) {
- msg.should.have.property("payload");
- msg.payload.should.have.property("signal","SIGTERM");
- done();
- });
- n1.receive({});
- });
- });
-
- it('should be able to kill a long running command', function(done) {
- var flow;
- if (osType === "Windows_NT") {
- flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"ping", addpay:false, append:"192.0.2.0 -n 1 -w 1000 > NUL", timer:"2", oldrc:"false"},
- {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}];
- } else {
- flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"sleep", addpay:false, append:"1", timer:"2", oldrc:"false"},
- {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}];
- }
helper.load(execNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
@@ -236,9 +222,42 @@ describe('exec node', function() {
msg.should.have.property("payload");
msg.payload.should.have.property("signal","SIGTERM");
done();
- } catch(err) {
- done(err);
}
+ catch(err) { done(err); }
+ });
+ n1.receive({});
+ });
+ });
+
+ it('should be able to kill a long running command', function(done) {
+ var flow;
+ if (osType === "Windows_NT") {
+ flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"ping", addpay:false, append:"192.0.2.0 -n 1 -w 1000 > NUL", timer:"2", oldrc:"false"},
+ {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}];
+ }
+ else {
+ flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"sleep", addpay:false, append:"1", timer:"2", oldrc:"false"},
+ {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}];
+ }
+ helper.load(execNode, flow, function() {
+ var n1 = helper.getNode("n1");
+ var n2 = helper.getNode("n2");
+ var n3 = helper.getNode("n3");
+ var n4 = helper.getNode("n4");
+ n2.on("input", function(msg) {
+ try {
+ msg.should.have.property("rc");
+ msg.rc.should.have.property("code",null);
+ msg.rc.should.have.property("signal","SIGTERM");
+ } catch(err) { done(err); }
+ });
+ n4.on("input", function(msg) {
+ try {
+ msg.should.have.property("payload");
+ msg.payload.should.have.property("signal","SIGTERM");
+ done();
+ }
+ catch(err) { done(err); }
});
setTimeout(function() {
n1.receive({kill:""});
@@ -262,14 +281,19 @@ describe('exec node', function() {
var n2 = helper.getNode("n2");
var n3 = helper.getNode("n3");
var n4 = helper.getNode("n4");
+ n2.on("input", function(msg) {
+ try {
+ msg.should.have.property("rc");
+ msg.rc.should.have.property("code",null);
+ msg.rc.should.have.property("signal","SIGINT");
+ } catch(err) { done(err); }
+ });
n4.on("input", function(msg) {
try {
msg.should.have.property("payload");
msg.payload.should.have.property("signal",sig);
done();
- } catch(err) {
- done(err);
- }
+ } catch(err) { done(err); }
});
setTimeout(function() {
n1.receive({kill:"SIGINT"});
@@ -278,7 +302,6 @@ describe('exec node', function() {
});
});
-
it('should return the rc for a failing command', function(done) {
var flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"error", addpay:false, append:"", oldrc:"false"},
{id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}];
@@ -305,6 +328,9 @@ describe('exec node', function() {
msg.should.have.property("payload");
msg.payload.should.be.a.String();
msg.payload.should.equal("error");
+ msg.should.have.property("rc");
+ msg.rc.should.have.property("code",1);
+ msg.rc.should.have.property("message",undefined);
msg = messages[1];
msg.should.have.property("payload");
@@ -317,7 +343,8 @@ describe('exec node', function() {
child_process.exec.restore();
done();
- } catch(err) {
+ }
+ catch(err) {
child_process.exec.restore();
done(err);
}
@@ -369,9 +396,8 @@ describe('exec node', function() {
msg.payload.should.be.a.String();
msg.payload.should.equal(expected);
done();
- } catch(err) {
- done(err);
}
+ catch(err) { done(err); }
});
n1.receive({payload:"hello world"});
});
@@ -397,10 +423,13 @@ describe('exec node', function() {
var n4 = helper.getNode("n4");
n2.on("input", function(msg) {
//console.log(msg);
- msg.should.have.property("payload");
- msg.payload.should.be.a.String();
- msg.payload.should.equal(expected);
- done();
+ try {
+ msg.should.have.property("payload");
+ msg.payload.should.be.a.String();
+ msg.payload.should.equal(expected);
+ done();
+ }
+ catch(err) { done(err); }
});
n1.receive({payload:12345});
});
@@ -431,9 +460,8 @@ describe('exec node', function() {
msg.payload.length.should.equal(7);
}
done();
- } catch(err) {
- done(err);
}
+ catch(err) { done(err); }
});
n1.receive({payload:new Buffer([0x01,0x02,0x03,0x88])});
});
@@ -474,12 +502,12 @@ describe('exec node', function() {
should.exist(msg.payload);
msg.payload.should.have.property("code",0);
done();
- } catch(err) {
+ }
+ catch(err) {
done(err);
}
};
-
n2.on("input", function(msg) {
messages[0] = msg;
completeTest();
@@ -501,10 +529,13 @@ describe('exec node', function() {
var n3 = helper.getNode("n3");
var n4 = helper.getNode("n4");
n4.on("input", function(msg) {
- msg.should.have.property("payload");
- msg.payload.should.have.property("code");
- msg.payload.code.should.be.below(0);
- done();
+ try {
+ msg.should.have.property("payload");
+ msg.payload.should.have.property("code");
+ msg.payload.code.should.be.below(0);
+ done();
+ }
+ catch(err) { done(err); }
});
n1.receive({payload:null});
});
@@ -521,7 +552,7 @@ describe('exec node', function() {
} else {
flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"mkdir /foo/bar/doo/dah", addpay:false, append:"", useSpawn:"true", oldrc:"false"},
{id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}];
- expected = "mkdir: /foo/bar/doo: No such file or directory\n";
+ expected = ' directory';
}
helper.load(execNode, flow, function() {
var n1 = helper.getNode("n1");
@@ -529,14 +560,20 @@ describe('exec node', function() {
var n3 = helper.getNode("n3");
var n4 = helper.getNode("n4");
n3.on("input", function(msg) {
- msg.should.have.property("payload");
- msg.payload.should.be.a.String();
- msg.payload.should.equal(expected);
+ try {
+ msg.should.have.property("payload");
+ msg.payload.should.be.a.String();
+ msg.payload.indexOf(expected).should.not.be.equal(-1);
+ }
+ catch(err) { done(err); }
});
n4.on("input", function(msg) {
- msg.should.have.property("payload");
- msg.payload.should.have.property("code",1);
- done();
+ try {
+ msg.should.have.property("payload");
+ msg.payload.should.have.property("code",1);
+ done();
+ }
+ catch(err) { done(err); }
});
n1.receive({payload:null});
});
@@ -557,10 +594,13 @@ describe('exec node', function() {
var n3 = helper.getNode("n3");
var n4 = helper.getNode("n4");
n4.on("input", function(msg) {
- msg.should.have.property("payload");
- msg.payload.should.have.property("code",null);
- msg.payload.should.have.property("signal","SIGTERM");
- done();
+ try {
+ msg.should.have.property("payload");
+ msg.payload.should.have.property("code",null);
+ msg.payload.should.have.property("signal","SIGTERM");
+ done();
+ }
+ catch(err) { done(err); }
});
n1.receive({});
});
@@ -581,9 +621,12 @@ describe('exec node', function() {
var n3 = helper.getNode("n3");
var n4 = helper.getNode("n4");
n4.on("input", function(msg) {
- msg.should.have.property("payload");
- msg.payload.should.have.property("signal","SIGTERM");
- done();
+ try {
+ msg.should.have.property("payload");
+ msg.payload.should.have.property("signal","SIGTERM");
+ done();
+ }
+ catch(err) { done(err); }
});
setTimeout(function() {
n1.receive({kill:""});
@@ -608,9 +651,12 @@ describe('exec node', function() {
var n3 = helper.getNode("n3");
var n4 = helper.getNode("n4");
n4.on("input", function(msg) {
- msg.should.have.property("payload");
- msg.payload.should.have.property("signal",sig);
- done();
+ try {
+ msg.should.have.property("payload");
+ msg.payload.should.have.property("signal",sig);
+ done();
+ }
+ catch(err) { done(err); }
});
setTimeout(function() {
n1.receive({kill:"SIGINT"});