Skip to content

Commit 4a86be2

Browse files
authored
fs: add to Dir support for explicit resource management
PR-URL: #58206 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: LiviaMedeiros <livia@cirno.name>
1 parent 917600c commit 4a86be2

File tree

3 files changed

+54
-7
lines changed

3 files changed

+54
-7
lines changed

doc/api/fs.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6740,6 +6740,26 @@ provided by the operating system's underlying directory mechanisms.
67406740
Entries added or removed while iterating over the directory might not be
67416741
included in the iteration results.
67426742
6743+
#### `dir[Symbol.asyncDispose]()`
6744+
6745+
<!-- YAML
6746+
added: REPLACEME
6747+
-->
6748+
6749+
> Stability: 1 - Experimental
6750+
6751+
An alias for `dir.close()`.
6752+
6753+
#### `dir[Symbol.Dispose]()`
6754+
6755+
<!-- YAML
6756+
added: REPLACEME
6757+
-->
6758+
6759+
> Stability: 1 - Experimental
6760+
6761+
An alias for `dir.closeSync()`.
6762+
67436763
### Class: `fs.Dirent`
67446764
67456765
<!-- YAML

lib/internal/fs/dir.js

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ const {
44
ArrayPrototypePush,
55
ArrayPrototypeShift,
66
FunctionPrototypeBind,
7-
ObjectDefineProperty,
7+
ObjectDefineProperties,
88
PromiseReject,
9+
SymbolAsyncDispose,
910
SymbolAsyncIterator,
11+
SymbolDispose,
1012
} = primordials;
1113

1214
const pathModule = require('path');
@@ -293,12 +295,27 @@ class Dir {
293295
}
294296
}
295297

296-
ObjectDefineProperty(Dir.prototype, SymbolAsyncIterator, {
297-
__proto__: null,
298-
value: Dir.prototype.entries,
298+
const nonEnumerableDescriptor = {
299299
enumerable: false,
300300
writable: true,
301301
configurable: true,
302+
};
303+
ObjectDefineProperties(Dir.prototype, {
304+
[SymbolDispose]: {
305+
__proto__: null,
306+
...nonEnumerableDescriptor,
307+
value: Dir.prototype.closeSync,
308+
},
309+
[SymbolAsyncDispose]: {
310+
__proto__: null,
311+
...nonEnumerableDescriptor,
312+
value: Dir.prototype.close,
313+
},
314+
[SymbolAsyncIterator]: {
315+
__proto__: null,
316+
...nonEnumerableDescriptor,
317+
value: Dir.prototype.entries,
318+
},
302319
});
303320

304321
function opendir(path, options, callback) {
Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
11
'use strict';
22

33
const common = require('../common');
4-
const { promises: fs } = require('fs');
4+
const assert = require('assert');
5+
const { opendirSync, promises: fs } = require('fs');
56

6-
async function doOpen() {
7+
async function explicitCall() {
78
const fh = await fs.open(__filename);
89
fh.on('close', common.mustCall());
910
await fh[Symbol.asyncDispose]();
11+
12+
const dh = await fs.opendir(__dirname);
13+
await dh[Symbol.asyncDispose]();
14+
await assert.rejects(dh.read(), { code: 'ERR_DIR_CLOSED' });
15+
16+
const dhSync = opendirSync(__dirname);
17+
dhSync[Symbol.dispose]();
18+
assert.throws(() => dhSync.readSync(), { code: 'ERR_DIR_CLOSED' });
1019
}
1120

12-
doOpen().then(common.mustCall());
21+
explicitCall().then(common.mustCall());
22+
// TODO(aduh95): add test for implicit calls, with `await using` syntax.

0 commit comments

Comments
 (0)