From 40b7302af84be97993c0b17432b331466e99f67c Mon Sep 17 00:00:00 2001 From: Bert Belder Date: Fri, 6 Apr 2012 02:54:33 +0200 Subject: [PATCH] fs.readFile: don't make the callback before the fd is closed On Windows it is not possible to unlink() the read file in the callback. This fixes #3051. A test is included. --- lib/fs.js | 9 +++-- test/simple/test-fs-readfile-unlink.js | 48 ++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 test/simple/test-fs-readfile-unlink.js diff --git a/lib/fs.js b/lib/fs.js index 44370cdeed..c3d4b5f0dd 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -78,6 +78,7 @@ fs.readFile = function(path, encoding_) { var readStream = fs.createReadStream(path); var buffers = []; var nread = 0; + var error; readStream.on('data', function(chunk) { buffers.push(chunk); @@ -85,11 +86,15 @@ fs.readFile = function(path, encoding_) { }); readStream.on('error', function(er) { - callback(er); + error = er; readStream.destroy(); }); - readStream.on('end', function() { + readStream.on('close', function() { + if (error) { + return callback(error); + } + // copy all the buffers into one var buffer; switch (buffers.length) { diff --git a/test/simple/test-fs-readfile-unlink.js b/test/simple/test-fs-readfile-unlink.js new file mode 100644 index 0000000000..0bb4a67f78 --- /dev/null +++ b/test/simple/test-fs-readfile-unlink.js @@ -0,0 +1,48 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var assert = require('assert'), + common = require('../common'), + fs = require('fs'), + path = require('path'), + dirName = path.resolve(common.fixturesDir, 'test-readfile-unlink'), + fileName = path.resolve(dirName, 'test.bin'); + +var buf = new Buffer(512 * 1024); +buf.fill(42); + +try { + fs.mkdirSync(dirName); +} catch (e) { + // Ignore if the directory already exists. + if (e.code != 'EEXIST') throw e; +} + +fs.writeFileSync(fileName, buf); + +fs.readFile(fileName, function(err, data) { + assert.ifError(err); + assert(data.length == buf.length); + assert.strictEqual(buf[0], 42); + + fs.unlinkSync(fileName); + fs.rmdirSync(dirName); +});