summaryrefslogtreecommitdiff
path: root/lib/fs.js
diff options
context:
space:
mode:
authorisaacs <i@izs.me>2012-06-11 14:49:31 -0700
committerisaacs <i@izs.me>2012-06-11 15:54:28 -0700
commit6ce013dd4bbe660c12ce11c338b788163305cd2b (patch)
tree32ae5774367a67a388de525c501748ec8ae5ae52 /lib/fs.js
parentd53cdc5378db082cda85179f1172db27a14dd33e (diff)
downloadnodejs-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.js73
1 files changed, 60 insertions, 13 deletions
diff --git a/lib/fs.js b/lib/fs.js
index d6f195afe..6f8e3b736 100644
--- a/lib/fs.js
+++ b/lib/fs.js
@@ -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;
};