Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fs: make SyncWriteStream inherit from Writable #8830

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 18 additions & 42 deletions lib/internal/fs.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';

const Buffer = require('buffer').Buffer;
const Stream = require('stream').Stream;
const Writable = require('stream').Writable;
const fs = require('fs');
const util = require('util');
const constants = process.binding('constants').fs;
Expand Down Expand Up @@ -58,65 +58,41 @@ exports.stringToFlags = stringToFlags;

// Temporary hack for process.stdout and process.stderr when piped to files.
function SyncWriteStream(fd, options) {
Stream.call(this);
Writable.call(this);

options = options || {};

this.fd = fd;
this.writable = true;
this.readable = false;
this.autoClose = options.autoClose === undefined ? true : options.autoClose;
}

util.inherits(SyncWriteStream, Stream);

SyncWriteStream.prototype.write = function(data, arg1, arg2) {
var encoding, cb;

// parse arguments
if (arg1) {
if (typeof arg1 === 'string') {
encoding = arg1;
cb = arg2;
} else if (typeof arg1 === 'function') {
cb = arg1;
} else {
throw new Error('Bad arguments');
}
}
assertEncoding(encoding);

// Change strings to buffers. SLOW
if (typeof data === 'string') {
data = Buffer.from(data, encoding);
}

fs.writeSync(this.fd, data, 0, data.length);
this.on('end', () => this._destroy());
}

if (cb) {
process.nextTick(cb);
}
util.inherits(SyncWriteStream, Writable);

SyncWriteStream.prototype._write = function(chunk, encoding, cb) {
fs.writeSync(this.fd, chunk, 0, chunk.length);
cb();
return true;
};

SyncWriteStream.prototype._destroy = function() {
if (this.fd === null) // already destroy()ed
return;

SyncWriteStream.prototype.end = function(data, arg1, arg2) {
if (data) {
this.write(data, arg1, arg2);
}
this.destroy();
};


SyncWriteStream.prototype.destroy = function() {
if (this.autoClose)
fs.closeSync(this.fd);

this.fd = null;
this.emit('close');
return true;
};

SyncWriteStream.prototype.destroySoon = SyncWriteStream.prototype.destroy;
SyncWriteStream.prototype.destroySoon =
SyncWriteStream.prototype.destroy = function() {
this._destroy();
this.emit('close');
return true;
};

exports.SyncWriteStream = SyncWriteStream;
40 changes: 40 additions & 0 deletions test/parallel/test-fs-syncwritestream.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const spawn = require('child_process').spawn;
const stream = require('stream');
const fs = require('fs');
const path = require('path');

// require('internal/fs').SyncWriteStream is used as a stdio implementation
// when stdout/stderr point to files.

if (process.argv[2] === 'child') {
// Note: Calling console.log() is part of this test as it exercises the
// SyncWriteStream#_write() code path.
console.log(JSON.stringify([process.stdout, process.stderr].map((stdio) => ({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Perhaps a note here quickly indicating that the console.log is intentional and part of the test? There are plenty of places around in the tests where console.log is used without serving much purpose.

instance: stdio instanceof stream.Writable,
readable: stdio.readable,
writable: stdio.writable,
}))));

return;
}

common.refreshTmpDir();

const filename = path.join(common.tmpDir, 'stdout');
const stdoutFd = fs.openSync(filename, 'w');

const proc = spawn(process.execPath, [__filename, 'child'], {
stdio: ['inherit', stdoutFd, stdoutFd ]
});

proc.on('close', common.mustCall(() => {
fs.closeSync(stdoutFd);

assert.deepStrictEqual(JSON.parse(fs.readFileSync(filename, 'utf8')), [
{ instance: true, readable: false, writable: true },
{ instance: true, readable: false, writable: true }
]);
}));