Skip to content

Commit

Permalink
process: swallow stdout/stderr error events
Browse files Browse the repository at this point in the history
This is a step in making `console` safe, swallows EPIPE and other
errors by registering an empty 'error' event listener.

Also fixes writes to stdout/stderr not working after `end()` is called,
even though we already override `destroy()` so the stream is never
actually closed.

Refs: nodejs#831
Fixes: nodejs#947
Fixes: nodejs#9403
  • Loading branch information
Fishrock123 committed Nov 4, 2016
1 parent 690bded commit 373402f
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 13 deletions.
38 changes: 38 additions & 0 deletions lib/internal/process/stdio.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,64 @@ function setupStdio() {
function getStdout() {
if (stdout) return stdout;
stdout = createWritableStdioStream(1);

Object.defineProperty(stdout._writableState, 'ended', {
set() {},
get() {
return false;
}
});
// XXX(Fishrock123): This should work I think, but it causes
// problems with some child-process related tests.
//
// Object.defineProperty(stdout, 'destroyed', {
// set() {},
// get() {
// return true;
// }
// });

stdout.destroy = stdout.destroySoon = function(er) {
stdout.destroyed = true;
er = er || new Error('process.stdout cannot be closed.');
stdout.emit('error', er);
};
if (stdout.isTTY) {
process.on('SIGWINCH', () => stdout._refreshSize());
}
stdout.on('error', () => {});
return stdout;
}

function getStderr() {
if (stderr) return stderr;
stderr = createWritableStdioStream(2);

Object.defineProperty(stderr._writableState, 'ended', {
set() {},
get() {
return false;
}
});
// XXX(Fishrock123): This should work I think, but it causes
// problems with some child-process related tests.
//
// Object.defineProperty(stderr, 'destroyed', {
// set() {},
// get() {
// return true;
// }
// });

stderr.destroy = stderr.destroySoon = function(er) {
stderr.destroyed = true;
er = er || new Error('process.stderr cannot be closed.');
stderr.emit('error', er);
};
if (stderr.isTTY) {
process.on('SIGWINCH', () => stderr._refreshSize());
}
stderr.on('error', () => {});
return stderr;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ function parent() {
});

child.on('close', function(code, signal) {
assert(code);
assert.strictEqual(code, 0, 'exit code should be zero');
assert.equal(out, 'foo');
assert(/process\.stdout cannot be closed/.test(err));
assert.strictEqual(err, '', 'stderr should be empty');
console.log('ok');
});
}
17 changes: 6 additions & 11 deletions test/pseudo-tty/test-tty-stdout-end.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
'use strict';
require('../common');
const common = require('../common');
const assert = require('assert');

const shouldThrow = function() {
process.stdout.end();
};

const validateError = function(e) {
return e instanceof Error &&
e.message === 'process.stdout cannot be closed.';
};

assert.throws(shouldThrow, validateError);
process.stdout.on('error', common.mustCall(function(e) {
assert(e instanceof Error, 'e is an Error');
assert.strictEqual(e.message, 'process.stdout cannot be closed.');
}));
process.stdout.end();

0 comments on commit 373402f

Please sign in to comment.