diff --git a/lib/internal/fs/promises.js b/lib/internal/fs/promises.js index befcccb2769589..e567bf0731b5c7 100644 --- a/lib/internal/fs/promises.js +++ b/lib/internal/fs/promises.js @@ -125,6 +125,10 @@ async function writeFileHandle(filehandle, data, options) { } while (remaining > 0); } +// Note: This is different from kReadFileBufferLength used for non-promisified +// fs.readFile. +const kReadFileMaxChunkSize = 16384; + async function readFileHandle(filehandle, options) { const statFields = await binding.fstat(filehandle.fd, false, kUsePromises); @@ -135,22 +139,19 @@ async function readFileHandle(filehandle, options) { size = 0; } - if (size === 0) - return options.encoding ? '' : Buffer.alloc(0); - if (size > kMaxLength) throw new ERR_FS_FILE_TOO_LARGE(size); const chunks = []; - const chunkSize = Math.min(size, 16384); - let totalRead = 0; + const chunkSize = size === 0 ? + kReadFileMaxChunkSize : + Math.min(size, kReadFileMaxChunkSize); let endOfFile = false; do { const buf = Buffer.alloc(chunkSize); const { bytesRead, buffer } = - await read(filehandle, buf, 0, chunkSize, totalRead); - totalRead += bytesRead; - endOfFile = bytesRead !== chunkSize; + await read(filehandle, buf, 0, chunkSize, -1); + endOfFile = bytesRead === 0; if (bytesRead > 0) chunks.push(buffer.slice(0, bytesRead)); } while (!endOfFile); diff --git a/test/parallel/test-fs-promises-file-handle-readFile.js b/test/parallel/test-fs-promises-file-handle-readFile.js index 316fd6581fa446..9e6fcc2784c49d 100644 --- a/test/parallel/test-fs-promises-file-handle-readFile.js +++ b/test/parallel/test-fs-promises-file-handle-readFile.js @@ -28,5 +28,22 @@ async function validateReadFile() { assert.deepStrictEqual(buffer, readFileData); } +async function validateReadFileProc() { + // Test to make sure reading a file under the /proc directory works. Adapted + // from test-fs-read-file-sync-hostname.js. + // Refs: + // - https://groups.google.com/forum/#!topic/nodejs-dev/rxZ_RoH1Gn0 + // - https://github.com/nodejs/node/issues/21331 + + // Test is Linux-specific. + if (!common.isLinux) + return; + + const fileHandle = await open('/proc/sys/kernel/hostname', 'r'); + const hostname = await fileHandle.readFile(); + assert.ok(hostname.length > 0); +} + validateReadFile() + .then(() => validateReadFileProc()) .then(common.mustCall()); diff --git a/test/parallel/test-fs-promises-readfile.js b/test/parallel/test-fs-promises-readfile.js index 4334673c30f5fb..b1186ad2172507 100644 --- a/test/parallel/test-fs-promises-readfile.js +++ b/test/parallel/test-fs-promises-readfile.js @@ -12,17 +12,35 @@ const fn = path.join(tmpdir.path, 'large-file'); common.crashOnUnhandledRejection(); -// Creating large buffer with random content -const buffer = Buffer.from( - Array.apply(null, { length: 16834 * 2 }) - .map(Math.random) - .map((number) => (number * (1 << 8))) -); - -// Writing buffer to a file then try to read it -writeFile(fn, buffer) - .then(() => readFile(fn)) - .then((readBuffer) => { - assert.strictEqual(readBuffer.equals(buffer), true); - }) +async function validateReadFile() { + // Creating large buffer with random content + const buffer = Buffer.from( + Array.apply(null, { length: 16834 * 2 }) + .map(Math.random) + .map((number) => (number * (1 << 8))) + ); + + // Writing buffer to a file then try to read it + await writeFile(fn, buffer); + const readBuffer = await readFile(fn); + assert.strictEqual(readBuffer.equals(buffer), true); +} + +async function validateReadFileProc() { + // Test to make sure reading a file under the /proc directory works. Adapted + // from test-fs-read-file-sync-hostname.js. + // Refs: + // - https://groups.google.com/forum/#!topic/nodejs-dev/rxZ_RoH1Gn0 + // - https://github.com/nodejs/node/issues/21331 + + // Test is Linux-specific. + if (!common.isLinux) + return; + + const hostname = await readFile('/proc/sys/kernel/hostname'); + assert.ok(hostname.length > 0); +} + +validateReadFile() + .then(() => validateReadFileProc()) .then(common.mustCall());