Skip to content

Commit 3b72788

Browse files
zcbenzmhdawson
authored andcommitted
src: add flags for controlling process behavior
PR-URL: #40339 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Michael Dawson <midawson@redhat.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Shelley Vohr <shelley.vohr@gmail.com> Reviewed-By: Minwoo Jung <nodecorelab@gmail.com>
1 parent 4cf5563 commit 3b72788

File tree

3 files changed

+88
-50
lines changed

3 files changed

+88
-50
lines changed

src/node.cc

+62-46
Original file line numberDiff line numberDiff line change
@@ -843,6 +843,14 @@ static std::atomic_bool init_called{false};
843843
int InitializeNodeWithArgs(std::vector<std::string>* argv,
844844
std::vector<std::string>* exec_argv,
845845
std::vector<std::string>* errors) {
846+
return InitializeNodeWithArgs(argv, exec_argv, errors,
847+
ProcessFlags::kNoFlags);
848+
}
849+
850+
int InitializeNodeWithArgs(std::vector<std::string>* argv,
851+
std::vector<std::string>* exec_argv,
852+
std::vector<std::string>* errors,
853+
ProcessFlags::Flags flags) {
846854
// Make sure InitializeNodeWithArgs() is called only once.
847855
CHECK(!init_called.exchange(true));
848856

@@ -853,7 +861,8 @@ int InitializeNodeWithArgs(std::vector<std::string>* argv,
853861
binding::RegisterBuiltinModules();
854862

855863
// Make inherited handles noninheritable.
856-
uv_disable_stdio_inheritance();
864+
if (!(flags & ProcessFlags::kEnableStdioInheritance))
865+
uv_disable_stdio_inheritance();
857866

858867
// Cache the original command line to be
859868
// used in diagnostic reports.
@@ -869,67 +878,73 @@ int InitializeNodeWithArgs(std::vector<std::string>* argv,
869878
HandleEnvOptions(per_process::cli_options->per_isolate->per_env);
870879

871880
#if !defined(NODE_WITHOUT_NODE_OPTIONS)
872-
std::string node_options;
881+
if (!(flags & ProcessFlags::kDisableNodeOptionsEnv)) {
882+
std::string node_options;
873883

874-
if (credentials::SafeGetenv("NODE_OPTIONS", &node_options)) {
875-
std::vector<std::string> env_argv =
876-
ParseNodeOptionsEnvVar(node_options, errors);
884+
if (credentials::SafeGetenv("NODE_OPTIONS", &node_options)) {
885+
std::vector<std::string> env_argv =
886+
ParseNodeOptionsEnvVar(node_options, errors);
877887

878-
if (!errors->empty()) return 9;
888+
if (!errors->empty()) return 9;
879889

880-
// [0] is expected to be the program name, fill it in from the real argv.
881-
env_argv.insert(env_argv.begin(), argv->at(0));
890+
// [0] is expected to be the program name, fill it in from the real argv.
891+
env_argv.insert(env_argv.begin(), argv->at(0));
882892

883-
const int exit_code = ProcessGlobalArgs(&env_argv,
884-
nullptr,
885-
errors,
886-
kAllowedInEnvironment);
887-
if (exit_code != 0) return exit_code;
893+
const int exit_code = ProcessGlobalArgs(&env_argv,
894+
nullptr,
895+
errors,
896+
kAllowedInEnvironment);
897+
if (exit_code != 0) return exit_code;
898+
}
888899
}
889900
#endif
890901

891-
const int exit_code = ProcessGlobalArgs(argv,
892-
exec_argv,
893-
errors,
894-
kDisallowedInEnvironment);
895-
if (exit_code != 0) return exit_code;
902+
if (!(flags & ProcessFlags::kDisableCLIOptions)) {
903+
const int exit_code = ProcessGlobalArgs(argv,
904+
exec_argv,
905+
errors,
906+
kDisallowedInEnvironment);
907+
if (exit_code != 0) return exit_code;
908+
}
896909

897910
// Set the process.title immediately after processing argv if --title is set.
898911
if (!per_process::cli_options->title.empty())
899912
uv_set_process_title(per_process::cli_options->title.c_str());
900913

901914
#if defined(NODE_HAVE_I18N_SUPPORT)
902-
// If the parameter isn't given, use the env variable.
903-
if (per_process::cli_options->icu_data_dir.empty())
904-
credentials::SafeGetenv("NODE_ICU_DATA",
905-
&per_process::cli_options->icu_data_dir);
915+
if (!(flags & ProcessFlags::kNoICU)) {
916+
// If the parameter isn't given, use the env variable.
917+
if (per_process::cli_options->icu_data_dir.empty())
918+
credentials::SafeGetenv("NODE_ICU_DATA",
919+
&per_process::cli_options->icu_data_dir);
906920

907921
#ifdef NODE_ICU_DEFAULT_DATA_DIR
908-
// If neither the CLI option nor the environment variable was specified,
909-
// fall back to the configured default
910-
if (per_process::cli_options->icu_data_dir.empty()) {
911-
// Check whether the NODE_ICU_DEFAULT_DATA_DIR contains the right data
912-
// file and can be read.
913-
static const char full_path[] =
914-
NODE_ICU_DEFAULT_DATA_DIR "/" U_ICUDATA_NAME ".dat";
915-
916-
FILE* f = fopen(full_path, "rb");
917-
918-
if (f != nullptr) {
919-
fclose(f);
920-
per_process::cli_options->icu_data_dir = NODE_ICU_DEFAULT_DATA_DIR;
922+
// If neither the CLI option nor the environment variable was specified,
923+
// fall back to the configured default
924+
if (per_process::cli_options->icu_data_dir.empty()) {
925+
// Check whether the NODE_ICU_DEFAULT_DATA_DIR contains the right data
926+
// file and can be read.
927+
static const char full_path[] =
928+
NODE_ICU_DEFAULT_DATA_DIR "/" U_ICUDATA_NAME ".dat";
929+
930+
FILE* f = fopen(full_path, "rb");
931+
932+
if (f != nullptr) {
933+
fclose(f);
934+
per_process::cli_options->icu_data_dir = NODE_ICU_DEFAULT_DATA_DIR;
935+
}
921936
}
922-
}
923937
#endif // NODE_ICU_DEFAULT_DATA_DIR
924938

925-
// Initialize ICU.
926-
// If icu_data_dir is empty here, it will load the 'minimal' data.
927-
if (!i18n::InitializeICUDirectory(per_process::cli_options->icu_data_dir)) {
928-
errors->push_back("could not initialize ICU "
929-
"(check NODE_ICU_DATA or --icu-data-dir parameters)\n");
930-
return 9;
939+
// Initialize ICU.
940+
// If icu_data_dir is empty here, it will load the 'minimal' data.
941+
if (!i18n::InitializeICUDirectory(per_process::cli_options->icu_data_dir)) {
942+
errors->push_back("could not initialize ICU "
943+
"(check NODE_ICU_DATA or --icu-data-dir parameters)\n");
944+
return 9;
945+
}
946+
per_process::metadata.versions.InitializeIntlVersions();
931947
}
932-
per_process::metadata.versions.InitializeIntlVersions();
933948

934949
# ifndef __POSIX__
935950
std::string tz;
@@ -956,7 +971,8 @@ InitializationResult InitializeOncePerProcess(int argc, char** argv) {
956971
InitializationResult InitializeOncePerProcess(
957972
int argc,
958973
char** argv,
959-
InitializationSettingsFlags flags) {
974+
InitializationSettingsFlags flags,
975+
ProcessFlags::Flags process_flags) {
960976
uint64_t init_flags = flags;
961977
if (init_flags & kDefaultInitialization) {
962978
init_flags = init_flags | kInitializeV8 | kInitOpenSSL | kRunPlatformInit;
@@ -982,8 +998,8 @@ InitializationResult InitializeOncePerProcess(
982998

983999
// This needs to run *before* V8::Initialize().
9841000
{
985-
result.exit_code =
986-
InitializeNodeWithArgs(&(result.args), &(result.exec_args), &errors);
1001+
result.exit_code = InitializeNodeWithArgs(
1002+
&(result.args), &(result.exec_args), &errors, process_flags);
9871003
for (const std::string& error : errors)
9881004
fprintf(stderr, "%s: %s\n", result.args.at(0).c_str(), error.c_str());
9891005
if (result.exit_code != 0) {

src/node.h

+24-3
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,20 @@ namespace node {
214214
class IsolateData;
215215
class Environment;
216216

217+
namespace ProcessFlags {
218+
enum Flags : uint64_t {
219+
kNoFlags = 0,
220+
// Enable stdio inheritance, which is disabled by default.
221+
kEnableStdioInheritance = 1 << 0,
222+
// Disable reading the NODE_OPTIONS environment variable.
223+
kDisableNodeOptionsEnv = 1 << 1,
224+
// Do not parse CLI options.
225+
kDisableCLIOptions = 1 << 2,
226+
// Do not initialize ICU.
227+
kNoICU = 1 << 3,
228+
};
229+
} // namespace ProcessFlags
230+
217231
// TODO(addaleax): Officially deprecate this and replace it with something
218232
// better suited for a public embedder API.
219233
NODE_EXTERN int Start(int argc, char* argv[]);
@@ -226,9 +240,16 @@ NODE_EXTERN int Stop(Environment* env);
226240
// from argv, fill exec_argv, and possibly add errors resulting from parsing
227241
// the arguments to `errors`. The return value is a suggested exit code for the
228242
// program; If it is 0, then initializing Node.js succeeded.
229-
NODE_EXTERN int InitializeNodeWithArgs(std::vector<std::string>* argv,
230-
std::vector<std::string>* exec_argv,
231-
std::vector<std::string>* errors);
243+
NODE_EXTERN int InitializeNodeWithArgs(
244+
std::vector<std::string>* argv,
245+
std::vector<std::string>* exec_argv,
246+
std::vector<std::string>* errors);
247+
// TODO(zcbenz): Turn above overloaded version into below's default argument.
248+
NODE_EXTERN int InitializeNodeWithArgs(
249+
std::vector<std::string>* argv,
250+
std::vector<std::string>* exec_argv,
251+
std::vector<std::string>* errors,
252+
ProcessFlags::Flags flags);
232253

233254
enum OptionEnvvarSettings {
234255
kAllowedInEnvironment,

src/node_internals.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,8 @@ InitializationResult InitializeOncePerProcess(int argc, char** argv);
324324
InitializationResult InitializeOncePerProcess(
325325
int argc,
326326
char** argv,
327-
InitializationSettingsFlags flags);
327+
InitializationSettingsFlags flags,
328+
ProcessFlags::Flags process_flags = ProcessFlags::kNoFlags);
328329
void TearDownOncePerProcess();
329330
void SetIsolateErrorHandlers(v8::Isolate* isolate, const IsolateSettings& s);
330331
void SetIsolateMiscHandlers(v8::Isolate* isolate, const IsolateSettings& s);

0 commit comments

Comments
 (0)