@@ -1151,42 +1151,23 @@ inline void PlatformInit() {
1151
1151
#endif // _WIN32
1152
1152
}
1153
1153
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) {
1157
1158
// Parse a few arguments which are specific to Node.
1158
1159
std::vector<std::string> v8_args;
1159
- std::vector<std::string> errors{};
1160
1160
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);
1180
1169
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 ;
1190
1171
1191
1172
for (const std::string& cve : per_process::cli_options->security_reverts )
1192
1173
Revert (cve.c_str ());
@@ -1226,19 +1207,17 @@ void ProcessArgv(std::vector<std::string>* args,
1226
1207
}
1227
1208
1228
1209
// 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]));
1233
1212
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 ;
1238
1214
1215
+ return 0 ;
1216
+ }
1239
1217
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) {
1242
1221
// Initialize prog_start_time to get relative uptime.
1243
1222
per_process::prog_start_time = static_cast <double >(uv_now (uv_default_loop ()));
1244
1223
@@ -1299,11 +1278,13 @@ void Init(std::vector<std::string>* argv,
1299
1278
std::vector<std::string> env_argv = SplitString (" x " + node_options, ' ' );
1300
1279
env_argv[0 ] = argv->at (0 );
1301
1280
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;
1303
1283
}
1304
1284
#endif
1305
1285
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;
1307
1288
1308
1289
// Set the process.title immediately after processing argv if --title is set.
1309
1290
if (!per_process::cli_options->title .empty ())
@@ -1317,11 +1298,9 @@ void Init(std::vector<std::string>* argv,
1317
1298
// Initialize ICU.
1318
1299
// If icu_data_dir is empty here, it will load the 'minimal' data.
1319
1300
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 ;
1325
1304
}
1326
1305
per_process::metadata.versions .InitializeIntlVersions ();
1327
1306
#endif
@@ -1330,6 +1309,7 @@ void Init(std::vector<std::string>* argv,
1330
1309
// otherwise embedders using node::Init to initialize everything will not be
1331
1310
// able to set it and native modules will not load for them.
1332
1311
node_is_initialized = true ;
1312
+ return 0 ;
1333
1313
}
1334
1314
1335
1315
// TODO(addaleax): Deprecate and eventually remove this.
@@ -1339,8 +1319,25 @@ void Init(int* argc,
1339
1319
const char *** exec_argv) {
1340
1320
std::vector<std::string> argv_ (argv, argv + *argc); // NOLINT
1341
1321
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);
1342
1327
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
+ }
1344
1341
1345
1342
*argc = argv_.size ();
1346
1343
*exec_argc = exec_argv_.size ();
@@ -1657,6 +1654,16 @@ inline int Start(uv_loop_t* event_loop,
1657
1654
if (isolate == nullptr )
1658
1655
return 12 ; // Signal internal error.
1659
1656
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
+
1660
1667
{
1661
1668
Mutex::ScopedLock scoped_lock (per_process::main_isolate_mutex);
1662
1669
CHECK_NULL (per_process::main_isolate);
@@ -1716,8 +1723,14 @@ int Start(int argc, char** argv) {
1716
1723
1717
1724
std::vector<std::string> args (argv, argv + argc);
1718
1725
std::vector<std::string> exec_args;
1726
+ std::vector<std::string> errors;
1719
1727
// 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
+ }
1721
1734
1722
1735
#if HAVE_OPENSSL
1723
1736
{
0 commit comments