Skip to content

Commit 1b38476

Browse files
committed
fs: add to Dir support for explicit resource management
PR-URL: #58206 Reviewed-By: James M Snell <[email protected]> Reviewed-By: LiviaMedeiros <[email protected]>
1 parent c8500a2 commit 1b38476

File tree

3 files changed

+56
-7
lines changed

3 files changed

+56
-7
lines changed

doc/api/fs.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6728,6 +6728,26 @@ provided by the operating system's underlying directory mechanisms.
67286728
Entries added or removed while iterating over the directory might not be
67296729
included in the iteration results.
67306730
6731+
#### `dir[Symbol.asyncDispose]()`
6732+
6733+
<!-- YAML
6734+
added: REPLACEME
6735+
-->
6736+
6737+
> Stability: 1 - Experimental
6738+
6739+
An alias for `dir.close()`.
6740+
6741+
#### `dir[Symbol.Dispose]()`
6742+
6743+
<!-- YAML
6744+
added: REPLACEME
6745+
-->
6746+
6747+
> Stability: 1 - Experimental
6748+
6749+
An alias for `dir.closeSync()`.
6750+
67316751
### Class: `fs.Dirent`
67326752
67336753
<!-- YAML

lib/internal/fs/dir.js

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const {
44
ArrayPrototypePush,
55
ArrayPrototypeShift,
66
FunctionPrototypeBind,
7-
ObjectDefineProperty,
7+
ObjectDefineProperties,
88
PromiseReject,
99
SymbolAsyncIterator,
1010
} = primordials;
@@ -31,6 +31,10 @@ const {
3131
validateFunction,
3232
validateUint32,
3333
} = require('internal/validators');
34+
const {
35+
SymbolAsyncDispose,
36+
SymbolDispose,
37+
} = internalUtil;
3438

3539
class Dir {
3640
#handle;
@@ -293,12 +297,27 @@ class Dir {
293297
}
294298
}
295299

296-
ObjectDefineProperty(Dir.prototype, SymbolAsyncIterator, {
297-
__proto__: null,
298-
value: Dir.prototype.entries,
300+
const nonEnumerableDescriptor = {
299301
enumerable: false,
300302
writable: true,
301303
configurable: true,
304+
};
305+
ObjectDefineProperties(Dir.prototype, {
306+
[SymbolDispose]: {
307+
__proto__: null,
308+
...nonEnumerableDescriptor,
309+
value: Dir.prototype.closeSync,
310+
},
311+
[SymbolAsyncDispose]: {
312+
__proto__: null,
313+
...nonEnumerableDescriptor,
314+
value: Dir.prototype.close,
315+
},
316+
[SymbolAsyncIterator]: {
317+
__proto__: null,
318+
...nonEnumerableDescriptor,
319+
value: Dir.prototype.entries,
320+
},
302321
});
303322

304323
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)