Skip to content

Commit b4b101f

Browse files
bnoordhuistargos
authored andcommitted
fs: default open/openSync flags argument to 'r'
Make fs.open() and fs.openSync() more economic to use by making the flags argument optional. You can now write: fs.open(file, cb) Instead of the more verbose: fs.open(file, 'r', cb) This idiom is already supported by functions like fs.readFile(). PR-URL: #23767 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
1 parent 0312d8b commit b4b101f

File tree

4 files changed

+70
-12
lines changed

4 files changed

+70
-12
lines changed

doc/api/fs.md

+5-3
Original file line numberDiff line numberDiff line change
@@ -2309,7 +2309,7 @@ this API: [`fs.mkdtemp()`][].
23092309
The optional `options` argument can be a string specifying an encoding, or an
23102310
object with an `encoding` property specifying the character encoding to use.
23112311

2312-
## fs.open(path, flags[, mode], callback)
2312+
## fs.open(path[, flags[, mode]], callback)
23132313
<!-- YAML
23142314
added: v0.0.2
23152315
changes:
@@ -2324,6 +2324,7 @@ changes:
23242324

23252325
* `path` {string|Buffer|URL}
23262326
* `flags` {string|number} See [support of file system `flags`][].
2327+
**Default:** `'r'`.
23272328
* `mode` {integer} **Default:** `0o666` (readable and writable)
23282329
* `callback` {Function}
23292330
* `err` {Error}
@@ -2345,7 +2346,7 @@ a colon, Node.js will open a file system stream, as described by
23452346
Functions based on `fs.open()` exhibit this behavior as well:
23462347
`fs.writeFile()`, `fs.readFile()`, etc.
23472348

2348-
## fs.openSync(path, flags[, mode])
2349+
## fs.openSync(path[, flags, mode])
23492350
<!-- YAML
23502351
added: v0.1.21
23512352
changes:
@@ -2356,7 +2357,8 @@ changes:
23562357
-->
23572358

23582359
* `path` {string|Buffer|URL}
2359-
* `flags` {string|number} See [support of file system `flags`][].
2360+
* `flags` {string|number} **Default:** `'r'`.
2361+
See [support of file system `flags`][].
23602362
* `mode` {integer} **Default:** `0o666`
23612363
* Returns: {number}
23622364

lib/fs.js

+12-7
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ function tryReadSync(fd, isUserFd, buffer, pos, len) {
345345
function readFileSync(path, options) {
346346
options = getOptions(options, { flag: 'r' });
347347
const isUserFd = isFd(path); // file descriptor ownership
348-
const fd = isUserFd ? path : fs.openSync(path, options.flag || 'r', 0o666);
348+
const fd = isUserFd ? path : fs.openSync(path, options.flag, 0o666);
349349

350350
const stats = tryStatSync(fd, isUserFd);
351351
const size = isFileType(stats, S_IFREG) ? stats[8] : 0;
@@ -411,14 +411,19 @@ function closeSync(fd) {
411411
function open(path, flags, mode, callback) {
412412
path = toPathIfFileURL(path);
413413
validatePath(path);
414-
const flagsNumber = stringToFlags(flags);
415-
if (arguments.length < 4) {
416-
callback = makeCallback(mode);
414+
if (arguments.length < 3) {
415+
callback = flags;
416+
flags = 'r';
417417
mode = 0o666;
418-
} else {
418+
} else if (arguments.length === 3) {
419+
callback = mode;
420+
mode = 0o666;
421+
}
422+
const flagsNumber = stringToFlags(flags);
423+
if (arguments.length >= 4) {
419424
mode = validateMode(mode, 'mode', 0o666);
420-
callback = makeCallback(callback);
421425
}
426+
callback = makeCallback(callback);
422427

423428
const req = new FSReqCallback();
424429
req.oncomplete = callback;
@@ -433,7 +438,7 @@ function open(path, flags, mode, callback) {
433438
function openSync(path, flags, mode) {
434439
path = toPathIfFileURL(path);
435440
validatePath(path);
436-
const flagsNumber = stringToFlags(flags);
441+
const flagsNumber = stringToFlags(flags || 'r');
437442
mode = validateMode(mode, 'mode', 0o666);
438443

439444
const ctx = { path };

lib/internal/fs/promises.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -196,11 +196,12 @@ async function copyFile(src, dest, flags) {
196196
async function open(path, flags, mode) {
197197
path = toPathIfFileURL(path);
198198
validatePath(path);
199+
if (arguments.length < 2) flags = 'r';
200+
const flagsNumber = stringToFlags(flags);
199201
mode = validateMode(mode, 'mode', 0o666);
200202
return new FileHandle(
201203
await binding.openFileHandle(pathModule.toNamespacedPath(path),
202-
stringToFlags(flags),
203-
mode, kUsePromises));
204+
flagsNumber, mode, kUsePromises));
204205
}
205206

206207
async function read(handle, buffer, offset, length, position) {

test/parallel/test-fs-open.js

+50
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ try {
3636
}
3737
assert.strictEqual(caughtException, true);
3838

39+
fs.openSync(__filename);
40+
41+
fs.open(__filename, common.mustCall((err) => {
42+
assert.ifError(err);
43+
}));
44+
3945
fs.open(__filename, 'r', common.mustCall((err) => {
4046
assert.ifError(err);
4147
}));
@@ -44,6 +50,39 @@ fs.open(__filename, 'rs', common.mustCall((err) => {
4450
assert.ifError(err);
4551
}));
4652

53+
fs.open(__filename, 'r', 0, common.mustCall((err) => {
54+
assert.ifError(err);
55+
}));
56+
57+
fs.open(__filename, 'r', null, common.mustCall((err) => {
58+
assert.ifError(err);
59+
}));
60+
61+
async function promise() {
62+
await fs.promises.open(__filename);
63+
await fs.promises.open(__filename, 'r');
64+
}
65+
66+
promise().then(common.mustCall()).catch(common.mustNotCall());
67+
68+
common.expectsError(
69+
() => fs.open(__filename, 'r', 'boom', common.mustNotCall()),
70+
{
71+
code: 'ERR_INVALID_ARG_VALUE',
72+
type: TypeError
73+
}
74+
);
75+
76+
for (const extra of [[], ['r'], ['r', 0], ['r', 0, 'bad callback']]) {
77+
common.expectsError(
78+
() => fs.open(__filename, ...extra),
79+
{
80+
code: 'ERR_INVALID_CALLBACK',
81+
type: TypeError
82+
}
83+
);
84+
}
85+
4786
[false, 1, [], {}, null, undefined].forEach((i) => {
4887
common.expectsError(
4988
() => fs.open(i, 'r', common.mustNotCall()),
@@ -59,4 +98,15 @@ fs.open(__filename, 'rs', common.mustCall((err) => {
5998
type: TypeError
6099
}
61100
);
101+
fs.promises.open(i, 'r')
102+
.then(common.mustNotCall())
103+
.catch(common.mustCall((err) => {
104+
common.expectsError(
105+
() => { throw err; },
106+
{
107+
code: 'ERR_INVALID_ARG_TYPE',
108+
type: TypeError
109+
}
110+
);
111+
}));
62112
});

0 commit comments

Comments
 (0)