Permalink
Browse files

fs: avoid emitting error EBADF for double close

Changed the logic in fs.ReadStream and fs.WriteStream so that
close always calls the prototype method rather than the internal
event listener.

Fixes: #2950
PR-URL: #11225
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>
  • Loading branch information...
mcollina committed Feb 7, 2017
1 parent 6dd979e commit b1fc7745f2c7f279d388d8c88781df776b740259
Showing with 37 additions and 13 deletions.
  1. +12 −13 lib/fs.js
  2. +11 −0 test/parallel/test-fs-read-stream-double-close.js
  3. +14 −0 test/parallel/test-fs-write-stream-double-close.js
View
@@ -1855,28 +1855,27 @@ ReadStream.prototype.destroy = function() {
ReadStream.prototype.close = function(cb) {
var self = this;
if (cb)
this.once('close', cb);
if (this.closed || typeof this.fd !== 'number') {
if (typeof this.fd !== 'number') {
this.once('open', close);
this.once('open', this.close.bind(this, null));
return;
}
return process.nextTick(() => this.emit('close'));
}
this.closed = true;
close();
function close(fd) {
fs.close(fd || self.fd, function(er) {
if (er)
self.emit('error', er);
else
self.emit('close');
});
self.fd = null;
}
fs.close(this.fd, (er) => {
if (er)
this.emit('error', er);
else
this.emit('close');
});
this.fd = null;
};
@@ -0,0 +1,11 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const s = fs.createReadStream(__filename);
s.close(common.mustCall(noop));
s.close(common.mustCall(noop));
function noop() {}
@@ -0,0 +1,14 @@
'use strict';
const common = require('../common');
const fs = require('fs');
const path = require('path');
common.refreshTmpDir();
const s = fs.createWriteStream(path.join(common.tmpDir, 'rw'));
s.close(common.mustCall(noop));
s.close(common.mustCall(noop));
function noop() {}

0 comments on commit b1fc774

Please sign in to comment.