Skip to content

Commit 2ebefe0

Browse files
mertcanaltinjuanarbol
authored andcommitted
fs: add signal option to fs.stat()
PR-URL: #57775 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Jason Zhang <xzha4350@gmail.com> Reviewed-By: Edy Silva <edigleyssonsilva@gmail.com> Reviewed-By: Aviv Keller <me@aviv.sh> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
1 parent c96f1a5 commit 2ebefe0

3 files changed

Lines changed: 49 additions & 5 deletions

File tree

‎doc/api/fs.md‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -628,15 +628,17 @@ Read from a file and write to an array of {ArrayBufferView}s
628628
<!-- YAML
629629
added: v10.0.0
630630
changes:
631+
- version: REPLACEME
632+
pr-url: https://github.com/nodejs/node/pull/57775
633+
description: Now accepts an additional `signal` property to allow aborting the operation.
631634
- version: v10.5.0
632635
pr-url: https://github.com/nodejs/node/pull/20220
633-
description: Accepts an additional `options` object to specify whether
634-
the numeric values returned should be bigint.
636+
description: Accepts an additional `options` object to specify whether the numeric values returned should be bigint.
635637
-->
636638
637639
* `options` {Object}
638-
* `bigint` {boolean} Whether the numeric values in the returned
639-
{fs.Stats} object should be `bigint`. **Default:** `false`.
640+
* `bigint` {boolean} Whether the numeric values in the returned {fs.Stats} object should be `bigint`. **Default:** `false`.
641+
* `signal` {AbortSignal} An AbortSignal to cancel the operation. **Default:** `undefined`.
640642
* Returns: {Promise} Fulfills with an {fs.Stats} for the file.
641643
642644
#### `filehandle.sync()`

‎lib/fs.js‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1652,7 +1652,7 @@ function lstat(path, options = { bigint: false }, callback) {
16521652
/**
16531653
* Asynchronously gets the stats of a file.
16541654
* @param {string | Buffer | URL} path
1655-
* @param {{ bigint?: boolean; }} [options]
1655+
* @param {{ bigint?: boolean, signal?: AbortSignal }} [options]
16561656
* @param {(
16571657
* err?: Error,
16581658
* stats?: Stats
@@ -1663,8 +1663,16 @@ function stat(path, options = { bigint: false, throwIfNoEntry: true }, callback)
16631663
if(typeofoptions==='function'){
16641664
callback=options;
16651665
options=kEmptyObject;
1666+
}elseif(options===null||typeofoptions!=='object'){
1667+
options=kEmptyObject;
1668+
}else{
1669+
options=getOptions(options,{bigint: false});
16661670
}
1671+
16671672
callback=makeStatsCallback(callback);
1673+
path=getValidatedPath(path);
1674+
1675+
if(checkAborted(options.signal,callback))return;
16681676

16691677
constreq=newFSReqCallback(options.bigint);
16701678
req.oncomplete=callback;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
'use strict';
2+
3+
require('../common');
4+
consttest=require('node:test');
5+
constassert=require('node:assert');
6+
constfs=require('node:fs');
7+
consttmpdir=require('../common/tmpdir');
8+
9+
test('fs.stat should throw AbortError when called with an already aborted AbortSignal',async()=>{
10+
// This test verifies that fs.stat immediately throws an AbortError if the provided AbortSignal
11+
// has already been canceled. This approach is used because trying to abort an fs.stat call in flight
12+
// is unreliable given that file system operations tend to complete very quickly on many platforms.
13+
tmpdir.refresh();
14+
15+
constfilePath=tmpdir.resolve('temp.txt');
16+
fs.writeFileSync(filePath,'Test');
17+
18+
// Create an already aborted AbortSignal.
19+
constsignal=AbortSignal.abort();
20+
21+
const{ promise, resolve, reject }=Promise.withResolvers();
22+
fs.stat(filePath,{ signal },(err,stats)=>{
23+
if(err){
24+
returnreject(err);
25+
}
26+
resolve(stats);
27+
});
28+
29+
// Assert that the promise is rejected with an AbortError.
30+
awaitassert.rejects(promise,{name: 'AbortError'});
31+
32+
fs.unlinkSync(filePath);
33+
tmpdir.refresh();
34+
});

0 commit comments

Comments
 (0)