Skip to content

Commit

Permalink
internal: lazy load fs due to circular dependency
Browse files Browse the repository at this point in the history
The fs module requires internal/fs and internal/fs requires fs which
causes a circular dependency. This change lazy loads fs inside of
internal/fs to prevent assertEncoding from breaking when requiring via
stdin.

Fixes: nodejs#11257
  • Loading branch information
evanlucas committed Feb 9, 2017
1 parent c38b6d2 commit 4f6d4d5
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 3 deletions.
14 changes: 11 additions & 3 deletions lib/internal/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

const Buffer = require('buffer').Buffer;
const Writable = require('stream').Writable;
const fs = require('fs');
const util = require('util');
const constants = process.binding('constants').fs;

Expand All @@ -15,6 +14,15 @@ const O_SYNC = constants.O_SYNC | 0;
const O_TRUNC = constants.O_TRUNC | 0;
const O_WRONLY = constants.O_WRONLY | 0;

let fs;
// Lazy load fs due to a circular dependency.
function lazyFS() {
if (!fs) {
fs = require('fs');
}
return fs;
}

function assertEncoding(encoding) {
if (encoding && !Buffer.isEncoding(encoding)) {
throw new Error(`Unknown encoding: ${encoding}`);
Expand Down Expand Up @@ -72,7 +80,7 @@ function SyncWriteStream(fd, options) {
util.inherits(SyncWriteStream, Writable);

SyncWriteStream.prototype._write = function(chunk, encoding, cb) {
fs.writeSync(this.fd, chunk, 0, chunk.length);
lazyFS().writeSync(this.fd, chunk, 0, chunk.length);
cb();
return true;
};
Expand All @@ -82,7 +90,7 @@ SyncWriteStream.prototype._destroy = function() {
return;

if (this.autoClose)
fs.closeSync(this.fd);
lazyFS().closeSync(this.fd);

this.fd = null;
return true;
Expand Down
20 changes: 20 additions & 0 deletions test/parallel/test-stdin-require.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use strict';

const common = require('../common');
const assert = require('assert');
const execSync = require('child_process').execSync;
const fs = require('fs');
const path = require('path');

common.refreshTmpDir();
const filename = path.join(__dirname, '..', 'fixtures', 'baz.js');
const out = path.join(common.tmpDir, 'js.out');
const bin = process.execPath;
const input = `require('${filename}'); console.log('PASS');`;
const cmd = common.isWindows ?
`echo "${input}" | ${bin} > ${out} 2>&1; more ${out}` :
`echo "${input}" | ${bin} &> ${out}; cat ${out}`;

const result = execSync(cmd).toString();
assert.strictEqual(result.trim(), 'PASS');
fs.unlinkSync(out);

0 comments on commit 4f6d4d5

Please sign in to comment.