@@ -1280,42 +1280,23 @@ inline void PlatformInit() {
1280
1280
#endif // _WIN32
1281
1281
}
1282
1282
1283
- void ProcessArgv (std::vector<std::string>* args,
1284
- std::vector<std::string>* exec_args,
1285
- bool is_env) {
1283
+ int ProcessGlobalArgs (std::vector<std::string>* args,
1284
+ std::vector<std::string>* exec_args,
1285
+ std::vector<std::string>* errors,
1286
+ bool is_env) {
1286
1287
// Parse a few arguments which are specific to Node.
1287
1288
std::vector<std::string> v8_args;
1288
- std::vector<std::string> errors{};
1289
1289
1290
- {
1291
- // TODO(addaleax): The mutex here should ideally be held during the
1292
- // entire function, but that doesn't play well with the exit() calls below.
1293
- Mutex::ScopedLock lock (per_process::cli_options_mutex);
1294
- options_parser::PerProcessOptionsParser::instance.Parse (
1295
- args,
1296
- exec_args,
1297
- &v8_args,
1298
- per_process::cli_options.get (),
1299
- is_env ? kAllowedInEnvironment : kDisallowedInEnvironment ,
1300
- &errors);
1301
- }
1302
-
1303
- if (!errors.empty ()) {
1304
- for (auto const & error : errors) {
1305
- fprintf (stderr, " %s: %s\n " , args->at (0 ).c_str (), error.c_str ());
1306
- }
1307
- exit (9 );
1308
- }
1290
+ Mutex::ScopedLock lock (per_process::cli_options_mutex);
1291
+ options_parser::PerProcessOptionsParser::instance.Parse (
1292
+ args,
1293
+ exec_args,
1294
+ &v8_args,
1295
+ per_process::cli_options.get (),
1296
+ is_env ? kAllowedInEnvironment : kDisallowedInEnvironment ,
1297
+ errors);
1309
1298
1310
- if (per_process::cli_options->print_version ) {
1311
- printf (" %s\n " , NODE_VERSION);
1312
- exit (0 );
1313
- }
1314
-
1315
- if (per_process::cli_options->print_v8_help ) {
1316
- V8::SetFlagsFromString (" --help" , 6 );
1317
- exit (0 );
1318
- }
1299
+ if (!errors->empty ()) return 9 ;
1319
1300
1320
1301
for (const std::string& cve : per_process::cli_options->security_reverts )
1321
1302
Revert (cve.c_str ());
@@ -1355,19 +1336,17 @@ void ProcessArgv(std::vector<std::string>* args,
1355
1336
}
1356
1337
1357
1338
// Anything that's still in v8_argv is not a V8 or a node option.
1358
- for (size_t i = 1 ; i < v8_args_as_char_ptr.size (); i++) {
1359
- fprintf (stderr, " %s: bad option: %s\n " ,
1360
- args->at (0 ).c_str (), v8_args_as_char_ptr[i]);
1361
- }
1339
+ for (size_t i = 1 ; i < v8_args_as_char_ptr.size (); i++)
1340
+ errors->push_back (" bad option: " + std::string (v8_args_as_char_ptr[i]));
1362
1341
1363
- if (v8_args_as_char_ptr.size () > 1 ) {
1364
- exit (9 );
1365
- }
1366
- }
1342
+ if (v8_args_as_char_ptr.size () > 1 ) return 9 ;
1367
1343
1344
+ return 0 ;
1345
+ }
1368
1346
1369
- void Init (std::vector<std::string>* argv,
1370
- std::vector<std::string>* exec_argv) {
1347
+ int Init (std::vector<std::string>* argv,
1348
+ std::vector<std::string>* exec_argv,
1349
+ std::vector<std::string>* errors) {
1371
1350
// Initialize prog_start_time to get relative uptime.
1372
1351
per_process::prog_start_time = static_cast <double >(uv_now (uv_default_loop ()));
1373
1352
@@ -1428,11 +1407,13 @@ void Init(std::vector<std::string>* argv,
1428
1407
std::vector<std::string> env_argv = SplitString (" x " + node_options, ' ' );
1429
1408
env_argv[0 ] = argv->at (0 );
1430
1409
1431
- ProcessArgv (&env_argv, nullptr , true );
1410
+ const int exit_code = ProcessGlobalArgs (&env_argv, nullptr , errors, true );
1411
+ if (exit_code != 0 ) return exit_code;
1432
1412
}
1433
1413
#endif
1434
1414
1435
- ProcessArgv (argv, exec_argv, false );
1415
+ const int exit_code = ProcessGlobalArgs (argv, exec_argv, errors, false );
1416
+ if (exit_code != 0 ) return exit_code;
1436
1417
1437
1418
// Set the process.title immediately after processing argv if --title is set.
1438
1419
if (!per_process::cli_options->title .empty ())
@@ -1446,11 +1427,9 @@ void Init(std::vector<std::string>* argv,
1446
1427
// Initialize ICU.
1447
1428
// If icu_data_dir is empty here, it will load the 'minimal' data.
1448
1429
if (!i18n::InitializeICUDirectory (per_process::cli_options->icu_data_dir )) {
1449
- fprintf (stderr,
1450
- " %s: could not initialize ICU "
1451
- " (check NODE_ICU_DATA or --icu-data-dir parameters)\n " ,
1452
- argv->at (0 ).c_str ());
1453
- exit (9 );
1430
+ errors->push_back (" could not initialize ICU "
1431
+ " (check NODE_ICU_DATA or --icu-data-dir parameters)\n " );
1432
+ return 9 ;
1454
1433
}
1455
1434
per_process::metadata.versions .InitializeIntlVersions ();
1456
1435
#endif
@@ -1459,6 +1438,7 @@ void Init(std::vector<std::string>* argv,
1459
1438
// otherwise embedders using node::Init to initialize everything will not be
1460
1439
// able to set it and native modules will not load for them.
1461
1440
node_is_initialized = true ;
1441
+ return 0 ;
1462
1442
}
1463
1443
1464
1444
// TODO(addaleax): Deprecate and eventually remove this.
@@ -1468,8 +1448,25 @@ void Init(int* argc,
1468
1448
const char *** exec_argv) {
1469
1449
std::vector<std::string> argv_ (argv, argv + *argc); // NOLINT
1470
1450
std::vector<std::string> exec_argv_;
1451
+ std::vector<std::string> errors;
1452
+
1453
+ // This (approximately) duplicates some logic that has been moved to
1454
+ // node::Start(), with the difference that here we explicitly call `exit()`.
1455
+ int exit_code = Init (&argv_, &exec_argv_, &errors);
1471
1456
1472
- Init (&argv_, &exec_argv_);
1457
+ for (const std::string& error : errors)
1458
+ fprintf (stderr, " %s: %s\n " , argv_.at (0 ).c_str (), error.c_str ());
1459
+ if (exit_code != 0 ) exit (exit_code);
1460
+
1461
+ if (per_process::cli_options->print_version ) {
1462
+ printf (" %s\n " , NODE_VERSION);
1463
+ exit (0 );
1464
+ }
1465
+
1466
+ if (per_process::cli_options->print_v8_help ) {
1467
+ V8::SetFlagsFromString (" --help" , 6 ); // Doesn't return.
1468
+ UNREACHABLE ();
1469
+ }
1473
1470
1474
1471
*argc = argv_.size ();
1475
1472
*exec_argc = exec_argv_.size ();
@@ -1786,6 +1783,16 @@ inline int Start(uv_loop_t* event_loop,
1786
1783
if (isolate == nullptr )
1787
1784
return 12 ; // Signal internal error.
1788
1785
1786
+ if (per_process::cli_options->print_version ) {
1787
+ printf (" %s\n " , NODE_VERSION);
1788
+ return 0 ;
1789
+ }
1790
+
1791
+ if (per_process::cli_options->print_v8_help ) {
1792
+ V8::SetFlagsFromString (" --help" , 6 ); // Doesn't return.
1793
+ UNREACHABLE ();
1794
+ }
1795
+
1789
1796
{
1790
1797
Mutex::ScopedLock scoped_lock (per_process::main_isolate_mutex);
1791
1798
CHECK_NULL (per_process::main_isolate);
@@ -1845,8 +1852,14 @@ int Start(int argc, char** argv) {
1845
1852
1846
1853
std::vector<std::string> args (argv, argv + argc);
1847
1854
std::vector<std::string> exec_args;
1855
+ std::vector<std::string> errors;
1848
1856
// This needs to run *before* V8::Initialize().
1849
- Init (&args, &exec_args);
1857
+ {
1858
+ const int exit_code = Init (&args, &exec_args, &errors);
1859
+ for (const std::string& error : errors)
1860
+ fprintf (stderr, " %s: %s\n " , args.at (0 ).c_str (), error.c_str ());
1861
+ if (exit_code != 0 ) return exit_code;
1862
+ }
1850
1863
1851
1864
#if HAVE_OPENSSL
1852
1865
{
0 commit comments