Skip to content

Commit 8c2d159

Browse files
authored
Merge branch 'main' into fix-49848
2 parents c34ec8e + f16f41c commit 8c2d159

10 files changed

Lines changed: 154 additions & 30 deletions

File tree

benchmark/fs/readFileSync.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,21 @@ const fs = require('fs');
66
const bench = common.createBenchmark(main, {
77
encoding: ['undefined', 'utf8'],
88
path: ['existing', 'non-existing'],
9-
n: [60e1],
9+
hasFileDescriptor: ['true', 'false'],
10+
n: [1e4],
1011
});
1112

12-
function main({ n, encoding, path }) {
13+
function main({ n, encoding, path, hasFileDescriptor }) {
1314
const enc = encoding === 'undefined' ? undefined : encoding;
14-
const file = path === 'existing' ? __filename : '/tmp/not-found';
15+
let file;
16+
let shouldClose = false;
17+
18+
if (hasFileDescriptor === 'true') {
19+
shouldClose = path === 'existing';
20+
file = path === 'existing' ? fs.openSync(__filename) : -1;
21+
} else {
22+
file = path === 'existing' ? __filename : '/tmp/not-found';
23+
}
1524
bench.start();
1625
for (let i = 0; i < n; ++i) {
1726
try {
@@ -21,4 +30,7 @@ function main({ n, encoding, path }) {
2130
}
2231
}
2332
bench.end(n);
33+
if (shouldClose) {
34+
fs.closeSync(file);
35+
}
2436
}

common.gypi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636

3737
# Reset this number to 0 on major V8 upgrades.
3838
# Increment by one for each non-official patch applied to deps/v8.
39-
'v8_embedder_string': '-node.17',
39+
'v8_embedder_string': '-node.18',
4040

4141
##### V8 defaults for Node.js #####
4242

deps/v8/src/flags/flags.cc

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <cstdlib>
1111
#include <cstring>
1212
#include <iomanip>
13+
#include <set>
1314
#include <sstream>
1415

1516
#include "src/base/functional.h"
@@ -103,7 +104,12 @@ struct Flag {
103104
const char* cmt_; // A comment about the flags purpose.
104105
bool owns_ptr_; // Does the flag own its string value?
105106
SetBy set_by_ = SetBy::kDefault;
107+
// Name of the flag implying this flag, if any.
106108
const char* implied_by_ = nullptr;
109+
#ifdef DEBUG
110+
// Pointer to the flag implying this flag, if any.
111+
const Flag* implied_by_ptr_ = nullptr;
112+
#endif
107113

108114
FlagType type() const { return type_; }
109115

@@ -113,6 +119,17 @@ struct Flag {
113119

114120
bool PointsTo(const void* ptr) const { return valptr_ == ptr; }
115121

122+
#ifdef DEBUG
123+
bool ImpliedBy(const void* ptr) const {
124+
const Flag* current = this->implied_by_ptr_;
125+
while (current != nullptr) {
126+
if (current->PointsTo(ptr)) return true;
127+
current = current->implied_by_ptr_;
128+
}
129+
return false;
130+
}
131+
#endif
132+
116133
bool bool_variable() const { return GetValue<TYPE_BOOL, bool>(); }
117134

118135
void set_bool_variable(bool value, SetBy set_by) {
@@ -333,6 +350,15 @@ struct Flag {
333350
if (IsAnyImplication(new_set_by)) {
334351
DCHECK_NOT_NULL(implied_by);
335352
implied_by_ = implied_by;
353+
#ifdef DEBUG
354+
// This only works when implied_by is a flag_name or !flag_name, but it
355+
// can also be a condition e.g. flag_name > 3. Since this is only used for
356+
// checks in DEBUG mode, we will just ignore the more complex conditions
357+
// for now - that will just lead to a nullptr which won't be followed.
358+
implied_by_ptr_ = static_cast<Flag*>(
359+
FindFlagByName(implied_by[0] == '!' ? implied_by + 1 : implied_by));
360+
DCHECK_NE(implied_by_ptr_, this);
361+
#endif
336362
}
337363
return change_flag;
338364
}
@@ -534,15 +560,70 @@ uint32_t ComputeFlagListHash() {
534560
std::ostringstream modified_args_as_string;
535561
if (COMPRESS_POINTERS_BOOL) modified_args_as_string << "ptr-compr";
536562
if (DEBUG_BOOL) modified_args_as_string << "debug";
563+
564+
#ifdef DEBUG
565+
// These two sets are used to check that we don't leave out any flags
566+
// implied by --predictable in the list below.
567+
std::set<const char*> flags_implied_by_predictable;
568+
std::set<const char*> flags_ignored_because_of_predictable;
569+
#endif
570+
537571
for (const Flag& flag : flags) {
538572
if (flag.IsDefault()) continue;
573+
#ifdef DEBUG
574+
if (flag.ImpliedBy(&v8_flags.predictable)) {
575+
flags_implied_by_predictable.insert(flag.name());
576+
}
577+
#endif
539578
// We want to be able to flip --profile-deserialization without
540579
// causing the code cache to get invalidated by this hash.
541580
if (flag.PointsTo(&v8_flags.profile_deserialization)) continue;
542-
// Skip v8_flags.random_seed to allow predictable code caching.
581+
// Skip v8_flags.random_seed and v8_flags.predictable to allow predictable
582+
// code caching.
543583
if (flag.PointsTo(&v8_flags.random_seed)) continue;
584+
if (flag.PointsTo(&v8_flags.predictable)) continue;
585+
586+
// The following flags are implied by --predictable (some negated).
587+
if (flag.PointsTo(&v8_flags.concurrent_sparkplug) ||
588+
flag.PointsTo(&v8_flags.concurrent_recompilation) ||
589+
#ifdef V8_ENABLE_MAGLEV
590+
flag.PointsTo(&v8_flags.maglev_deopt_data_on_background) ||
591+
flag.PointsTo(&v8_flags.maglev_build_code_on_background) ||
592+
#endif
593+
flag.PointsTo(&v8_flags.parallel_scavenge) ||
594+
flag.PointsTo(&v8_flags.concurrent_marking) ||
595+
flag.PointsTo(&v8_flags.concurrent_array_buffer_sweeping) ||
596+
flag.PointsTo(&v8_flags.parallel_marking) ||
597+
flag.PointsTo(&v8_flags.concurrent_sweeping) ||
598+
flag.PointsTo(&v8_flags.parallel_compaction) ||
599+
flag.PointsTo(&v8_flags.parallel_pointer_update) ||
600+
flag.PointsTo(&v8_flags.memory_reducer) ||
601+
flag.PointsTo(&v8_flags.cppheap_concurrent_marking) ||
602+
flag.PointsTo(&v8_flags.cppheap_incremental_marking) ||
603+
flag.PointsTo(&v8_flags.single_threaded_gc)) {
604+
#ifdef DEBUG
605+
if (flag.ImpliedBy(&v8_flags.predictable)) {
606+
flags_ignored_because_of_predictable.insert(flag.name());
607+
}
608+
#endif
609+
continue;
610+
}
544611
modified_args_as_string << flag;
545612
}
613+
614+
#ifdef DEBUG
615+
for (const char* name : flags_implied_by_predictable) {
616+
if (flags_ignored_because_of_predictable.find(name) ==
617+
flags_ignored_because_of_predictable.end()) {
618+
PrintF(
619+
"%s should be added to the list of "
620+
"flags_ignored_because_of_predictable\n",
621+
name);
622+
UNREACHABLE();
623+
}
624+
}
625+
#endif
626+
546627
std::string args(modified_args_as_string.str());
547628
// Generate a hash that is not 0.
548629
uint32_t hash = static_cast<uint32_t>(base::hash_range(

doc/api/deprecations.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3414,6 +3414,20 @@ Type: Documentation-only
34143414
The [`util.toUSVString()`][] API is deprecated. Please use
34153415
[`String.prototype.toWellFormed`][] instead.
34163416

3417+
### DEP0176: `fs.F_OK`, `fs.R_OK`, `fs.W_OK`, `fs.X_OK`
3418+
3419+
<!-- YAML
3420+
changes:
3421+
- version: REPLACEME
3422+
pr-url: https://github.com/nodejs/node/pull/49683
3423+
description: Documentation-only deprecation.
3424+
-->
3425+
3426+
Type: Documentation-only
3427+
3428+
`F_OK`, `R_OK`, `W_OK` and `X_OK` getters exposed directly on `node:fs` are
3429+
deprecated. Get them from `fs.constants` or `fs.promises.constants` instead.
3430+
34173431
[NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
34183432
[RFC 6066]: https://tools.ietf.org/html/rfc6066#section-3
34193433
[RFC 8247 Section 2.4]: https://www.rfc-editor.org/rfc/rfc8247#section-2.4

doc/api/fs.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1830,6 +1830,10 @@ concurrent modifications on the same file or data corruption may occur.
18301830
<!-- YAML
18311831
added: v0.11.15
18321832
changes:
1833+
- version: REPLACEME
1834+
pr-url: https://github.com/nodejs/node/pull/49683
1835+
description: The constants `fs.F_OK`, `fs.R_OK`, `fs.W_OK` and `fs.X_OK`
1836+
which were present directly on `fs` are deprecated.
18331837
- version: v18.0.0
18341838
pr-url: https://github.com/nodejs/node/pull/41678
18351839
description: Passing an invalid callback to the `callback` argument

lib/fs.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -437,13 +437,11 @@ function tryReadSync(fd, isUserFd, buffer, pos, len) {
437437
function readFileSync(path, options) {
438438
options = getOptions(options, { flag: 'r' });
439439

440-
const isUserFd = isFd(path); // File descriptor ownership
441-
442-
// TODO(@anonrig): Do not handle file descriptor ownership for now.
443-
if (!isUserFd && (options.encoding === 'utf8' || options.encoding === 'utf-8')) {
440+
if (options.encoding === 'utf8' || options.encoding === 'utf-8') {
444441
return syncFs.readFileUtf8(path, options.flag);
445442
}
446443

444+
const isUserFd = isFd(path); // File descriptor ownership
447445
const fd = isUserFd ? path : fs.openSync(path, options.flag, 0o666);
448446

449447
const stats = tryStatSync(fd, isUserFd);

lib/internal/fs/sync.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const {
99
getStatFsFromBinding,
1010
getValidatedFd,
1111
} = require('internal/fs/utils');
12-
const { parseFileMode } = require('internal/validators');
12+
const { parseFileMode, isInt32 } = require('internal/validators');
1313

1414
const binding = internalBinding('fs');
1515

@@ -19,7 +19,9 @@ const binding = internalBinding('fs');
1919
* @return {string}
2020
*/
2121
function readFileUtf8(path, flag) {
22-
path = pathModule.toNamespacedPath(getValidatedPath(path));
22+
if (!isInt32(path)) {
23+
path = pathModule.toNamespacedPath(getValidatedPath(path));
24+
}
2325
return binding.readFileUtf8(path, stringToFlags(flag));
2426
}
2527

src/node_file.cc

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2155,7 +2155,7 @@ static void OpenSync(const FunctionCallbackInfo<Value>& args) {
21552155
uv_fs_t req;
21562156
auto make = OnScopeLeave([&req]() { uv_fs_req_cleanup(&req); });
21572157
FS_SYNC_TRACE_BEGIN(open);
2158-
int err = uv_fs_open(nullptr, &req, *path, flags, mode, nullptr);
2158+
auto err = uv_fs_open(nullptr, &req, *path, flags, mode, nullptr);
21592159
FS_SYNC_TRACE_END(open);
21602160
if (err < 0) {
21612161
return env->ThrowUVException(err, "open", nullptr, path.out());
@@ -2546,30 +2546,41 @@ static void ReadFileUtf8(const FunctionCallbackInfo<Value>& args) {
25462546

25472547
CHECK_GE(args.Length(), 2);
25482548

2549-
BufferValue path(env->isolate(), args[0]);
2550-
CHECK_NOT_NULL(*path);
2551-
25522549
CHECK(args[1]->IsInt32());
25532550
const int flags = args[1].As<Int32>()->Value();
25542551

2555-
if (CheckOpenPermissions(env, path, flags).IsNothing()) return;
2556-
2552+
uv_file file;
25572553
uv_fs_t req;
2558-
auto defer_req_cleanup = OnScopeLeave([&req]() { uv_fs_req_cleanup(&req); });
25592554

2560-
FS_SYNC_TRACE_BEGIN(open);
2561-
uv_file file = uv_fs_open(nullptr, &req, *path, flags, 438, nullptr);
2562-
FS_SYNC_TRACE_END(open);
2563-
if (req.result < 0) {
2564-
// req will be cleaned up by scope leave.
2565-
return env->ThrowUVException(req.result, "open", nullptr, path.out());
2555+
bool is_fd = args[0]->IsInt32();
2556+
2557+
// Check for file descriptor
2558+
if (is_fd) {
2559+
file = args[0].As<Int32>()->Value();
2560+
} else {
2561+
BufferValue path(env->isolate(), args[0]);
2562+
CHECK_NOT_NULL(*path);
2563+
if (CheckOpenPermissions(env, path, flags).IsNothing()) return;
2564+
2565+
FS_SYNC_TRACE_BEGIN(open);
2566+
file = uv_fs_open(nullptr, &req, *path, flags, O_RDONLY, nullptr);
2567+
FS_SYNC_TRACE_END(open);
2568+
if (req.result < 0) {
2569+
uv_fs_req_cleanup(&req);
2570+
// req will be cleaned up by scope leave.
2571+
return env->ThrowUVException(req.result, "open", nullptr, path.out());
2572+
}
25662573
}
25672574

2568-
auto defer_close = OnScopeLeave([file]() {
2569-
uv_fs_t close_req;
2570-
CHECK_EQ(0, uv_fs_close(nullptr, &close_req, file, nullptr));
2571-
uv_fs_req_cleanup(&close_req);
2575+
auto defer_close = OnScopeLeave([file, is_fd, &req]() {
2576+
if (!is_fd) {
2577+
FS_SYNC_TRACE_BEGIN(close);
2578+
CHECK_EQ(0, uv_fs_close(nullptr, &req, file, nullptr));
2579+
FS_SYNC_TRACE_END(close);
2580+
}
2581+
uv_fs_req_cleanup(&req);
25722582
});
2583+
25732584
std::string result{};
25742585
char buffer[8192];
25752586
uv_buf_t buf = uv_buf_init(buffer, sizeof(buffer));
@@ -2580,7 +2591,7 @@ static void ReadFileUtf8(const FunctionCallbackInfo<Value>& args) {
25802591
if (req.result < 0) {
25812592
FS_SYNC_TRACE_END(read);
25822593
// req will be cleaned up by scope leave.
2583-
return env->ThrowUVException(req.result, "read", nullptr, path.out());
2594+
return env->ThrowUVException(req.result, "read", nullptr);
25842595
}
25852596
if (r <= 0) {
25862597
break;

test/parallel/parallel.status

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ prefix parallel
55
# sample-test : PASS,FLAKY
66

77
[true] # This section applies to all platforms
8+
# https://github.com/nodejs/node/issues/49853
9+
test-runner-output: PASS,FLAKY
810

911
[$system==win32]
1012
# https://github.com/nodejs/node/issues/41206

test/parallel/test-trace-events-bootstrap.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ if (process.argv[2] === 'child') {
3232
const file = tmpdir.resolve('node_trace.1.log');
3333

3434
assert(fs.existsSync(file));
35-
fs.readFile(file, common.mustCall((err, data) => {
35+
fs.readFile(file, common.mustSucceed((data) => {
3636
const traces = JSON.parse(data.toString()).traceEvents
3737
.filter((trace) => trace.cat !== '__metadata');
3838
traces.forEach((trace) => {

0 commit comments

Comments
 (0)