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 a162251

Browse filesBrowse files
committed
src: clean up node::Init() wrt embedder scenarios
This makes the STL variant of `node::Init()` a bit more suitable for inclusion in a proper embedder API, as errors or other output are reported to the caller rather than directly being printed, and the process is not exited directly either. PR-URL: #25370 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
1 parent 0095f49 commit a162251
Copy full SHA for a162251

File tree

Expand file treeCollapse file tree

1 file changed

+64
-51
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

1 file changed

+64
-51
lines changed
Open diff view settings
Collapse file

‎src/node.cc‎

Copy file name to clipboardExpand all lines: src/node.cc
+64-51Lines changed: 64 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,42 +1151,23 @@ inline void PlatformInit() {
11511151
#endif // _WIN32
11521152
}
11531153

1154-
void ProcessArgv(std::vector<std::string>* args,
1155-
std::vector<std::string>* exec_args,
1156-
bool is_env) {
1154+
int ProcessGlobalArgs(std::vector<std::string>* args,
1155+
std::vector<std::string>* exec_args,
1156+
std::vector<std::string>* errors,
1157+
bool is_env) {
11571158
// Parse a few arguments which are specific to Node.
11581159
std::vector<std::string> v8_args;
1159-
std::vector<std::string> errors{};
11601160

1161-
{
1162-
// TODO(addaleax): The mutex here should ideally be held during the
1163-
// entire function, but that doesn't play well with the exit() calls below.
1164-
Mutex::ScopedLock lock(per_process::cli_options_mutex);
1165-
options_parser::PerProcessOptionsParser::instance.Parse(
1166-
args,
1167-
exec_args,
1168-
&v8_args,
1169-
per_process::cli_options.get(),
1170-
is_env ? kAllowedInEnvironment : kDisallowedInEnvironment,
1171-
&errors);
1172-
}
1173-
1174-
if (!errors.empty()) {
1175-
for (auto const& error : errors) {
1176-
fprintf(stderr, "%s: %s\n", args->at(0).c_str(), error.c_str());
1177-
}
1178-
exit(9);
1179-
}
1161+
Mutex::ScopedLock lock(per_process::cli_options_mutex);
1162+
options_parser::PerProcessOptionsParser::instance.Parse(
1163+
args,
1164+
exec_args,
1165+
&v8_args,
1166+
per_process::cli_options.get(),
1167+
is_env ? kAllowedInEnvironment : kDisallowedInEnvironment,
1168+
errors);
11801169

1181-
if (per_process::cli_options->print_version) {
1182-
printf("%s\n", NODE_VERSION);
1183-
exit(0);
1184-
}
1185-
1186-
if (per_process::cli_options->print_v8_help) {
1187-
V8::SetFlagsFromString("--help", 6);
1188-
exit(0);
1189-
}
1170+
if (!errors->empty()) return 9;
11901171

11911172
for (const std::string& cve : per_process::cli_options->security_reverts)
11921173
Revert(cve.c_str());
@@ -1226,19 +1207,17 @@ void ProcessArgv(std::vector<std::string>* args,
12261207
}
12271208

12281209
// Anything that's still in v8_argv is not a V8 or a node option.
1229-
for (size_t i = 1; i < v8_args_as_char_ptr.size(); i++) {
1230-
fprintf(stderr, "%s: bad option: %s\n",
1231-
args->at(0).c_str(), v8_args_as_char_ptr[i]);
1232-
}
1210+
for (size_t i = 1; i < v8_args_as_char_ptr.size(); i++)
1211+
errors->push_back("bad option: " + std::string(v8_args_as_char_ptr[i]));
12331212

1234-
if (v8_args_as_char_ptr.size() > 1) {
1235-
exit(9);
1236-
}
1237-
}
1213+
if (v8_args_as_char_ptr.size() > 1) return 9;
12381214

1215+
return 0;
1216+
}
12391217

1240-
void Init(std::vector<std::string>* argv,
1241-
std::vector<std::string>* exec_argv) {
1218+
int Init(std::vector<std::string>* argv,
1219+
std::vector<std::string>* exec_argv,
1220+
std::vector<std::string>* errors) {
12421221
// Initialize prog_start_time to get relative uptime.
12431222
per_process::prog_start_time = static_cast<double>(uv_now(uv_default_loop()));
12441223

@@ -1299,11 +1278,13 @@ void Init(std::vector<std::string>* argv,
12991278
std::vector<std::string> env_argv = SplitString("x " + node_options, ' ');
13001279
env_argv[0] = argv->at(0);
13011280

1302-
ProcessArgv(&env_argv, nullptr, true);
1281+
const int exit_code = ProcessGlobalArgs(&env_argv, nullptr, errors, true);
1282+
if (exit_code != 0) return exit_code;
13031283
}
13041284
#endif
13051285

1306-
ProcessArgv(argv, exec_argv, false);
1286+
const int exit_code = ProcessGlobalArgs(argv, exec_argv, errors, false);
1287+
if (exit_code != 0) return exit_code;
13071288

13081289
// Set the process.title immediately after processing argv if --title is set.
13091290
if (!per_process::cli_options->title.empty())
@@ -1317,11 +1298,9 @@ void Init(std::vector<std::string>* argv,
13171298
// Initialize ICU.
13181299
// If icu_data_dir is empty here, it will load the 'minimal' data.
13191300
if (!i18n::InitializeICUDirectory(per_process::cli_options->icu_data_dir)) {
1320-
fprintf(stderr,
1321-
"%s: could not initialize ICU "
1322-
"(check NODE_ICU_DATA or --icu-data-dir parameters)\n",
1323-
argv->at(0).c_str());
1324-
exit(9);
1301+
errors->push_back("could not initialize ICU "
1302+
"(check NODE_ICU_DATA or --icu-data-dir parameters)\n");
1303+
return 9;
13251304
}
13261305
per_process::metadata.versions.InitializeIntlVersions();
13271306
#endif
@@ -1330,6 +1309,7 @@ void Init(std::vector<std::string>* argv,
13301309
// otherwise embedders using node::Init to initialize everything will not be
13311310
// able to set it and native modules will not load for them.
13321311
node_is_initialized = true;
1312+
return 0;
13331313
}
13341314

13351315
// TODO(addaleax): Deprecate and eventually remove this.
@@ -1339,8 +1319,25 @@ void Init(int* argc,
13391319
const char*** exec_argv) {
13401320
std::vector<std::string> argv_(argv, argv + *argc); // NOLINT
13411321
std::vector<std::string> exec_argv_;
1322+
std::vector<std::string> errors;
1323+
1324+
// This (approximately) duplicates some logic that has been moved to
1325+
// node::Start(), with the difference that here we explicitly call `exit()`.
1326+
int exit_code = Init(&argv_, &exec_argv_, &errors);
13421327

1343-
Init(&argv_, &exec_argv_);
1328+
for (const std::string& error : errors)
1329+
fprintf(stderr, "%s: %s\n", argv_.at(0).c_str(), error.c_str());
1330+
if (exit_code != 0) exit(exit_code);
1331+
1332+
if (per_process::cli_options->print_version) {
1333+
printf("%s\n", NODE_VERSION);
1334+
exit(0);
1335+
}
1336+
1337+
if (per_process::cli_options->print_v8_help) {
1338+
V8::SetFlagsFromString("--help", 6); // Doesn't return.
1339+
UNREACHABLE();
1340+
}
13441341

13451342
*argc = argv_.size();
13461343
*exec_argc = exec_argv_.size();
@@ -1657,6 +1654,16 @@ inline int Start(uv_loop_t* event_loop,
16571654
if (isolate == nullptr)
16581655
return 12; // Signal internal error.
16591656

1657+
if (per_process::cli_options->print_version) {
1658+
printf("%s\n", NODE_VERSION);
1659+
return 0;
1660+
}
1661+
1662+
if (per_process::cli_options->print_v8_help) {
1663+
V8::SetFlagsFromString("--help", 6); // Doesn't return.
1664+
UNREACHABLE();
1665+
}
1666+
16601667
{
16611668
Mutex::ScopedLock scoped_lock(per_process::main_isolate_mutex);
16621669
CHECK_NULL(per_process::main_isolate);
@@ -1716,8 +1723,14 @@ int Start(int argc, char** argv) {
17161723

17171724
std::vector<std::string> args(argv, argv + argc);
17181725
std::vector<std::string> exec_args;
1726+
std::vector<std::string> errors;
17191727
// This needs to run *before* V8::Initialize().
1720-
Init(&args, &exec_args);
1728+
{
1729+
const int exit_code = Init(&args, &exec_args, &errors);
1730+
for (const std::string& error : errors)
1731+
fprintf(stderr, "%s: %s\n", args.at(0).c_str(), error.c_str());
1732+
if (exit_code != 0) return exit_code;
1733+
}
17211734

17221735
#if HAVE_OPENSSL
17231736
{

0 commit comments

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