fs: support BigInt in fs.*stat and fs.watchFile · nodejs/node@04e8f07 · GitHub
Skip to content

Commit 04e8f07

Browse 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

15 files changed

Lines changed: 341 additions & 79 deletions

lib/fs.js

Lines changed: 34 additions & 22 deletions

lib/internal/fs/promises.js

Lines 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

lib/internal/fs/utils.js

Lines 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
}

lib/internal/fs/watchers.js

Lines 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

src/env-inl.h

Lines 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_;

src/env.cc

Lines 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());

src/env.h

Lines changed: 3 additions & 0 deletions

0 commit comments

Comments
 (0)