fs: support pseudofiles in promises.readFile

PR-URL: https://github.com/nodejs/node/pull/21497
Fixes: https://github.com/nodejs/node/issues/21331
Refs: http://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html
Refs: https://groups.google.com/forum/#!topic/nodejs-dev/rxZ_RoH1Gn0
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
This commit is contained in:
Timothy Gu 2018-06-24 01:11:53 -04:00
parent c01601e1fe
commit 5057dd40a1
No known key found for this signature in database
GPG Key ID: 7FE6B095B582B0D4
3 changed files with 56 additions and 20 deletions

View File

@ -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);

View File

@ -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());

View File

@ -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)))
);
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
writeFile(fn, buffer)
.then(() => readFile(fn))
.then((readBuffer) => {
assert.strictEqual(readBuffer.equals(buffer), true);
})
// 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());