Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 04e8f07

Browse filesBrowse files
joyeecheungtargos
authored andcommitted
fs: support BigInt in fs.*stat and fs.watchFile
Add the `bigint: true` option to all the `fs.*stat` methods and `fs.watchFile`. PR-URL: #20220 Fixes: #12115 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
1 parent ea4be72 commit 04e8f07
Copy full SHA for 04e8f07

File tree

Expand file treeCollapse file tree

15 files changed

+341
-79
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

15 files changed

+341
-79
lines changed
Open diff view settings
Collapse file

‎lib/fs.js‎

Copy file name to clipboardExpand all lines: lib/fs.js
+34-22Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ function readFileAfterOpen(err, fd) {
248248
const req = new FSReqWrap();
249249
req.oncomplete = readFileAfterStat;
250250
req.context = context;
251-
binding.fstat(fd, req);
251+
binding.fstat(fd, false, req);
252252
}
253253

254254
function readFileAfterStat(err, stats) {
@@ -307,7 +307,7 @@ function readFile(path, options, callback) {
307307

308308
function tryStatSync(fd, isUserFd) {
309309
const ctx = {};
310-
const stats = binding.fstat(fd, undefined, ctx);
310+
const stats = binding.fstat(fd, false, undefined, ctx);
311311
if (ctx.errno !== undefined && !isUserFd) {
312312
fs.closeSync(fd);
313313
throw errors.uvException(ctx);
@@ -760,55 +760,67 @@ function readdirSync(path, options) {
760760
return result;
761761
}
762762

763-
function fstat(fd, callback) {
763+
function fstat(fd, options, callback) {
764+
if (arguments.length < 3) {
765+
callback = options;
766+
options = {};
767+
}
764768
validateUint32(fd, 'fd');
765-
const req = new FSReqWrap();
769+
const req = new FSReqWrap(options.bigint);
766770
req.oncomplete = makeStatsCallback(callback);
767-
binding.fstat(fd, req);
771+
binding.fstat(fd, options.bigint, req);
768772
}
769773

770-
function lstat(path, callback) {
774+
function lstat(path, options, callback) {
775+
if (arguments.length < 3) {
776+
callback = options;
777+
options = {};
778+
}
771779
callback = makeStatsCallback(callback);
772780
path = getPathFromURL(path);
773781
validatePath(path);
774-
const req = new FSReqWrap();
782+
const req = new FSReqWrap(options.bigint);
775783
req.oncomplete = callback;
776-
binding.lstat(pathModule.toNamespacedPath(path), req);
784+
binding.lstat(pathModule.toNamespacedPath(path), options.bigint, req);
777785
}
778786

779-
function stat(path, callback) {
787+
function stat(path, options, callback) {
788+
if (arguments.length < 3) {
789+
callback = options;
790+
options = {};
791+
}
780792
callback = makeStatsCallback(callback);
781793
path = getPathFromURL(path);
782794
validatePath(path);
783-
const req = new FSReqWrap();
795+
const req = new FSReqWrap(options.bigint);
784796
req.oncomplete = callback;
785-
binding.stat(pathModule.toNamespacedPath(path), req);
797+
binding.stat(pathModule.toNamespacedPath(path), options.bigint, req);
786798
}
787799

788-
function fstatSync(fd) {
800+
function fstatSync(fd, options = {}) {
789801
validateUint32(fd, 'fd');
790802
const ctx = { fd };
791-
const stats = binding.fstat(fd, undefined, ctx);
803+
const stats = binding.fstat(fd, options.bigint, undefined, ctx);
792804
handleErrorFromBinding(ctx);
793805
return getStatsFromBinding(stats);
794806
}
795807

796-
function lstatSync(path) {
808+
function lstatSync(path, options = {}) {
797809
path = getPathFromURL(path);
798810
validatePath(path);
799811
const ctx = { path };
800812
const stats = binding.lstat(pathModule.toNamespacedPath(path),
801-
undefined, ctx);
813+
options.bigint, undefined, ctx);
802814
handleErrorFromBinding(ctx);
803815
return getStatsFromBinding(stats);
804816
}
805817

806-
function statSync(path) {
818+
function statSync(path, options = {}) {
807819
path = getPathFromURL(path);
808820
validatePath(path);
809821
const ctx = { path };
810822
const stats = binding.stat(pathModule.toNamespacedPath(path),
811-
undefined, ctx);
823+
options.bigint, undefined, ctx);
812824
handleErrorFromBinding(ctx);
813825
return getStatsFromBinding(stats);
814826
}
@@ -1264,7 +1276,7 @@ function watchFile(filename, options, listener) {
12641276
if (stat === undefined) {
12651277
if (!watchers)
12661278
watchers = require('internal/fs/watchers');
1267-
stat = new watchers.StatWatcher();
1279+
stat = new watchers.StatWatcher(options.bigint);
12681280
stat.start(filename, options.persistent, options.interval);
12691281
statWatchers.set(filename, stat);
12701282
}
@@ -1379,7 +1391,7 @@ function realpathSync(p, options) {
13791391
// On windows, check that the root exists. On unix there is no need.
13801392
if (isWindows && !knownHard[base]) {
13811393
const ctx = { path: base };
1382-
binding.lstat(pathModule.toNamespacedPath(base), undefined, ctx);
1394+
binding.lstat(pathModule.toNamespacedPath(base), false, undefined, ctx);
13831395
handleErrorFromBinding(ctx);
13841396
knownHard[base] = true;
13851397
}
@@ -1421,7 +1433,7 @@ function realpathSync(p, options) {
14211433

14221434
const baseLong = pathModule.toNamespacedPath(base);
14231435
const ctx = { path: base };
1424-
const stats = binding.lstat(baseLong, undefined, ctx);
1436+
const stats = binding.lstat(baseLong, false, undefined, ctx);
14251437
handleErrorFromBinding(ctx);
14261438

14271439
if (!isFileType(stats, S_IFLNK)) {
@@ -1444,7 +1456,7 @@ function realpathSync(p, options) {
14441456
}
14451457
if (linkTarget === null) {
14461458
const ctx = { path: base };
1447-
binding.stat(baseLong, undefined, ctx);
1459+
binding.stat(baseLong, false, undefined, ctx);
14481460
handleErrorFromBinding(ctx);
14491461
linkTarget = binding.readlink(baseLong, undefined, undefined, ctx);
14501462
handleErrorFromBinding(ctx);
@@ -1465,7 +1477,7 @@ function realpathSync(p, options) {
14651477
// On windows, check that the root exists. On unix there is no need.
14661478
if (isWindows && !knownHard[base]) {
14671479
const ctx = { path: base };
1468-
binding.lstat(pathModule.toNamespacedPath(base), undefined, ctx);
1480+
binding.lstat(pathModule.toNamespacedPath(base), false, undefined, ctx);
14691481
handleErrorFromBinding(ctx);
14701482
knownHard[base] = true;
14711483
}
Collapse file

‎lib/internal/fs/promises.js‎

Copy file name to clipboardExpand all lines: lib/internal/fs/promises.js
+9-10Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ class FileHandle {
8181
return readFile(this, options);
8282
}
8383

84-
stat() {
85-
return fstat(this);
84+
stat(options) {
85+
return fstat(this, options);
8686
}
8787

8888
truncate(len = 0) {
@@ -106,7 +106,6 @@ class FileHandle {
106106
}
107107
}
108108

109-
110109
function validateFileHandle(handle) {
111110
if (!(handle instanceof FileHandle))
112111
throw new ERR_INVALID_ARG_TYPE('filehandle', 'FileHandle', handle);
@@ -127,7 +126,7 @@ async function writeFileHandle(filehandle, data, options) {
127126
}
128127

129128
async function readFileHandle(filehandle, options) {
130-
const statFields = await binding.fstat(filehandle.fd, kUsePromises);
129+
const statFields = await binding.fstat(filehandle.fd, false, kUsePromises);
131130

132131
let size;
133132
if ((statFields[1/* mode */] & S_IFMT) === S_IFREG) {
@@ -318,25 +317,25 @@ async function symlink(target, path, type_) {
318317
kUsePromises);
319318
}
320319

321-
async function fstat(handle) {
320+
async function fstat(handle, options = { bigint: false }) {
322321
validateFileHandle(handle);
323-
const result = await binding.fstat(handle.fd, kUsePromises);
322+
const result = await binding.fstat(handle.fd, options.bigint, kUsePromises);
324323
return getStatsFromBinding(result);
325324
}
326325

327-
async function lstat(path) {
326+
async function lstat(path, options = { bigint: false }) {
328327
path = getPathFromURL(path);
329328
validatePath(path);
330329
const result = await binding.lstat(pathModule.toNamespacedPath(path),
331-
kUsePromises);
330+
options.bigint, kUsePromises);
332331
return getStatsFromBinding(result);
333332
}
334333

335-
async function stat(path) {
334+
async function stat(path, options = { bigint: false }) {
336335
path = getPathFromURL(path);
337336
validatePath(path);
338337
const result = await binding.stat(pathModule.toNamespacedPath(path),
339-
kUsePromises);
338+
options.bigint, kUsePromises);
340339
return getStatsFromBinding(result);
341340
}
342341

Collapse file

‎lib/internal/fs/utils.js‎

Copy file name to clipboardExpand all lines: lib/internal/fs/utils.js
+12-4Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ function preprocessSymlinkDestination(path, type, linkPath) {
114114
}
115115

116116
function dateFromNumeric(num) {
117-
return new Date(num + 0.5);
117+
return new Date(Number(num) + 0.5);
118118
}
119119

120120
// Constructor for file stats.
@@ -155,7 +155,15 @@ function Stats(
155155
}
156156

157157
Stats.prototype._checkModeProperty = function(property) {
158-
return ((this.mode & S_IFMT) === property);
158+
if (isWindows && (property === S_IFIFO || property === S_IFBLK ||
159+
property === S_IFSOCK)) {
160+
return false; // Some types are not available on Windows
161+
}
162+
if (typeof this.mode === 'bigint') { // eslint-disable-line valid-typeof
163+
// eslint-disable-next-line no-undef
164+
return (this.mode & BigInt(S_IFMT)) === BigInt(property);
165+
}
166+
return (this.mode & S_IFMT) === property;
159167
};
160168

161169
Stats.prototype.isDirectory = function() {
@@ -189,9 +197,9 @@ Stats.prototype.isSocket = function() {
189197
function getStatsFromBinding(stats, offset = 0) {
190198
return new Stats(stats[0 + offset], stats[1 + offset], stats[2 + offset],
191199
stats[3 + offset], stats[4 + offset], stats[5 + offset],
192-
stats[6 + offset] < 0 ? undefined : stats[6 + offset],
200+
isWindows ? undefined : stats[6 + offset], // blksize
193201
stats[7 + offset], stats[8 + offset],
194-
stats[9 + offset] < 0 ? undefined : stats[9 + offset],
202+
isWindows ? undefined : stats[9 + offset], // blocks
195203
stats[10 + offset], stats[11 + offset],
196204
stats[12 + offset], stats[13 + offset]);
197205
}
Collapse file

‎lib/internal/fs/watchers.js‎

Copy file name to clipboardExpand all lines: lib/internal/fs/watchers.js
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ function emitStop(self) {
2121
self.emit('stop');
2222
}
2323

24-
function StatWatcher() {
24+
function StatWatcher(bigint) {
2525
EventEmitter.call(this);
2626

27-
this._handle = new _StatWatcher();
27+
this._handle = new _StatWatcher(bigint);
2828

2929
// uv_fs_poll is a little more powerful than ev_stat but we curb it for
3030
// the sake of backwards compatibility
Collapse file

‎src/env-inl.h‎

Copy file name to clipboardExpand all lines: src/env-inl.h
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,11 @@ Environment::fs_stats_field_array() {
546546
return &fs_stats_field_array_;
547547
}
548548

549+
inline AliasedBuffer<uint64_t, v8::BigUint64Array>*
550+
Environment::fs_stats_field_bigint_array() {
551+
return &fs_stats_field_bigint_array_;
552+
}
553+
549554
inline std::vector<std::unique_ptr<fs::FileHandleReadWrap>>&
550555
Environment::file_handle_read_wrap_freelist() {
551556
return file_handle_read_wrap_freelist_;
Collapse file

‎src/env.cc‎

Copy file name to clipboardExpand all lines: src/env.cc
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ Environment::Environment(IsolateData* isolate_data,
116116
#endif
117117
http_parser_buffer_(nullptr),
118118
fs_stats_field_array_(isolate_, kFsStatsFieldsLength * 2),
119+
fs_stats_field_bigint_array_(isolate_, kFsStatsFieldsLength * 2),
119120
context_(context->GetIsolate(), context) {
120121
// We'll be creating new objects so make sure we've entered the context.
121122
v8::HandleScope handle_scope(isolate());
Collapse file

‎src/env.h‎

Copy file name to clipboardExpand all lines: src/env.h
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,8 @@ class Environment {
694694
void set_debug_categories(const std::string& cats, bool enabled);
695695

696696
inline AliasedBuffer<double, v8::Float64Array>* fs_stats_field_array();
697+
inline AliasedBuffer<uint64_t, v8::BigUint64Array>*
698+
fs_stats_field_bigint_array();
697699

698700
// stat fields contains twice the number of entries because `fs.StatWatcher`
699701
// needs room to store data for *two* `fs.Stats` instances.
@@ -914,6 +916,7 @@ class Environment {
914916
bool debug_enabled_[static_cast<int>(DebugCategory::CATEGORY_COUNT)] = {0};
915917

916918
AliasedBuffer<double, v8::Float64Array> fs_stats_field_array_;
919+
AliasedBuffer<uint64_t, v8::BigUint64Array> fs_stats_field_bigint_array_;
917920

918921
std::vector<std::unique_ptr<fs::FileHandleReadWrap>>
919922
file_handle_read_wrap_freelist_;

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.