diff options
author | isaacs <i@izs.me> | 2012-06-11 14:49:31 -0700 |
---|---|---|
committer | isaacs <i@izs.me> | 2012-06-11 15:54:28 -0700 |
commit | 6ce013dd4bbe660c12ce11c338b788163305cd2b (patch) | |
tree | 32ae5774367a67a388de525c501748ec8ae5ae52 /lib/fs.js | |
parent | d53cdc5378db082cda85179f1172db27a14dd33e (diff) | |
download | nodejs-6ce013dd4bbe660c12ce11c338b788163305cd2b.tar.gz nodejs-6ce013dd4bbe660c12ce11c338b788163305cd2b.tar.bz2 nodejs-6ce013dd4bbe660c12ce11c338b788163305cd2b.zip |
fix fs.readFile with lying size=0 stat results
Diffstat (limited to 'lib/fs.js')
-rw-r--r-- | lib/fs.js | 73 |
1 files changed, 60 insertions, 13 deletions
@@ -108,7 +108,8 @@ fs.readFile = function(path, encoding_) { // first, stat the file, so we know the size. var size; - var buffer; + var buffer; // single buffer with file data + var buffers; // list for when size is unknown var pos = 0; var fd; @@ -120,8 +121,10 @@ fs.readFile = function(path, encoding_) { if (er) return callback(er); size = st.size; if (size === 0) { - buffer = new Buffer(0); - return afterRead(null, 0); + // the kernel lies about many files. + // Go ahead and try to read some bytes. + buffers = []; + return read(); } buffer = new Buffer(size); @@ -130,7 +133,12 @@ fs.readFile = function(path, encoding_) { }); function read() { - fs.read(fd, buffer, pos, size - pos, pos, afterRead); + if (size === 0) { + buffer = new Buffer(8192); + fs.read(fd, buffer, 0, 8192, pos, afterRead); + } else { + fs.read(fd, buffer, pos, size - pos, pos, afterRead); + } } function afterRead(er, bytesRead) { @@ -141,12 +149,27 @@ fs.readFile = function(path, encoding_) { } pos += bytesRead; - if (pos === size) close(); - else read(); + if (size !== 0) { + if (pos === size) close(); + else read(); + } else { + // unknown size, just read until we don't get bytes. + if (bytesRead > 0) { + buffers.push(buffer.slice(0, bytesRead)); + read(); + } else { + close(); + } + } } function close() { fs.close(fd, function(er) { + if (size === 0) { + // collected the data into the buffers list. + buffer = Buffer.concat(buffer.length, pos); + } + if (encoding) buffer = buffer.toString(encoding); return callback(er, buffer); }); @@ -165,28 +188,52 @@ fs.readFileSync = function(path, encoding) { if (threw) fs.closeSync(fd); } + var pos = 0; + var buffer; // single buffer with file data + var buffers; // list for when size is unknown + if (size === 0) { - fs.closeSync(fd); - return encoding ? '' : new Buffer(0); + buffers = []; + } else { + buffer = new Buffer(size); } - var buffer = new Buffer(size); - var pos = 0; - - while (pos < size) { + var done = false; + while (!done) { var threw = true; try { - var bytesRead = fs.readSync(fd, buffer, pos, size - pos, pos); + if (size !== 0) { + var bytesRead = fs.readSync(fd, buffer, pos, size - pos, pos); + } else { + // the kernel lies about many files. + // Go ahead and try to read some bytes. + buffer = new Buffer(8192); + var bytesRead = fs.readSync(fd, buffer, 0, 8192, pos); + if (bytesRead) { + buffers.push(buffer.slice(0, bytesRead)); + } + } threw = false; } finally { if (threw) fs.closeSync(fd); } pos += bytesRead; + + if (size !== 0) { + done = pos >= size; + } else { + done = bytesRead > 0; + } } fs.closeSync(fd); + if (size === 0) { + // data was collected into the buffers list. + buffer = Buffer.concat(buffers, pos); + } + if (encoding) buffer = buffer.toString(encoding); return buffer; }; |