diff options
-rw-r--r-- | SConstruct | 5 | ||||
-rw-r--r-- | src/mongo/SConscript | 396 | ||||
-rw-r--r-- | src/mongo/db/fts/unicode/SConscript | 2 | ||||
-rw-r--r-- | src/mongo/db/mongod.cpp | 52 | ||||
-rw-r--r-- | src/mongo/db/mongod.manifest.in (renamed from src/mongo/db/db.manifest.in) | 0 | ||||
-rw-r--r-- | src/mongo/db/mongod.rc (renamed from src/mongo/db/db.rc) | 2 | ||||
-rw-r--r-- | src/mongo/db/mongod_initializers.cpp | 31 | ||||
-rw-r--r-- | src/mongo/db/mongod_main.cpp (renamed from src/mongo/db/db.cpp) | 25 | ||||
-rw-r--r-- | src/mongo/db/mongod_main.h | 34 | ||||
-rw-r--r-- | src/mongo/db/storage/SConscript | 10 | ||||
-rw-r--r-- | src/mongo/db/storage/wiredtiger/SConscript | 7 | ||||
-rw-r--r-- | src/mongo/dbtests/SConscript | 23 | ||||
-rw-r--r-- | src/mongo/s/mongos.cpp | 50 | ||||
-rw-r--r-- | src/mongo/s/mongos.manifest.in (renamed from src/mongo/s/server.manifest.in) | 0 | ||||
-rw-r--r-- | src/mongo/s/mongos.rc (renamed from src/mongo/s/server.rc) | 2 | ||||
-rw-r--r-- | src/mongo/s/mongos_main.cpp (renamed from src/mongo/s/server.cpp) | 22 | ||||
-rw-r--r-- | src/mongo/s/mongos_main.h | 36 | ||||
-rw-r--r-- | src/mongo/shell/SConscript | 23 | ||||
-rw-r--r-- | src/mongo/shell/mongo.cpp | 45 | ||||
-rw-r--r-- | src/mongo/shell/mongo.manifest.in (renamed from src/mongo/shell/shell.manifest.in) | 0 | ||||
-rw-r--r-- | src/mongo/shell/mongo.rc (renamed from src/mongo/shell/shell.rc) | 2 | ||||
-rw-r--r-- | src/mongo/shell/mongo_main.cpp (renamed from src/mongo/shell/dbshell.cpp) | 737 | ||||
-rw-r--r-- | src/mongo/shell/mongo_main.h | 34 | ||||
-rw-r--r-- | src/mongo/shell/shell_utils.cpp | 3 | ||||
-rw-r--r-- | src/mongo/util/SConscript | 7 |
25 files changed, 1010 insertions, 538 deletions
diff --git a/SConstruct b/SConstruct index e30b9336789..3c7193ab776 100644 --- a/SConstruct +++ b/SConstruct @@ -230,11 +230,6 @@ add_option('noshell', nargs=0, ) -add_option('safeshell', - help="don't let shell scripts run programs (still, don't run untrusted scripts)", - nargs=0, -) - add_option('dbg', choices=['on', 'off'], const='on', diff --git a/src/mongo/SConscript b/src/mongo/SConscript index 346879db8b6..80447a02e6a 100644 --- a/src/mongo/SConscript +++ b/src/mongo/SConscript @@ -336,7 +336,7 @@ env.Library( if env.TargetOSIs('windows'): generatedDbManifest = env.Substfile( - 'db/db.manifest.in', + 'db/mongod.manifest.in', SUBST_DICT=[ ('@mongo_version_major@', version_parts[0]), ('@mongo_version_minor@', version_parts[1]), @@ -346,16 +346,45 @@ if env.TargetOSIs('windows'): ]) env.Alias('generated-sources', generatedDbManifest) - env.Depends("db/db.res", generatedDbManifest) + env.Depends("db/mongod.res", generatedDbManifest) mongod = env.Program( target="mongod", source=[ - 'db/db.cpp', - 'db/logical_session_cache_factory_mongod.cpp', - 'db/read_write_concern_defaults_cache_lookup_mongod.cpp', - ] + env.WindowsResourceFile("db/db.rc"), + 'db/mongod.cpp' + ] + env.WindowsResourceFile("db/mongod.rc"), + LIBDEPS=[ + # NOTE: Do not add new libdeps (public or private) here unless + # required by the linker to satisfy symbol dependencies from + # the files listed above in `sources`. If you need to add a + # library to inject a static or mongo initializer to mongod, + # please add that library as a private libdep of + # mongod_initializers. + 'base', + 'mongod_main', + 'util/quick_exit', + ], + AIB_COMPONENT="mongod", + AIB_COMPONENTS_EXTRA=[ + "core", + "default", + "dist", + "dist-test", + "servers", + "integration-tests", + ], +) + +env.Library( + target="mongod_initializers", + source=[ + # NOTE: If you add an additional source file here, please delete + # the file db/mongod_initializers.cpp. + "db/mongod_initializers.cpp", + ], LIBDEPS_PRIVATE=[ + # NOTE: If you need to add a static or mongo initializer to mongod startup, + # please add that library here, as a private library dependency. '$BUILD_DIR/third_party/shim_snappy', 'base', 'db/auth/auth_op_observer', @@ -473,14 +502,90 @@ mongod = env.Program( 'util/version_impl', 'watchdog/watchdog_mongod', ], - AIB_COMPONENT="mongod", - AIB_COMPONENTS_EXTRA=[ - "core", - "default", - "dist", - "dist-test", - "servers", - "integration-tests", + LIBDEPS=[ + # NOTE: This list must remain empty. Please only add to LIBDEPS_PRIVATE + ], +) + +env.Library( + target="mongod_main", + source=[ + 'db/mongod_main.cpp', + 'db/logical_session_cache_factory_mongod.cpp', + 'db/read_write_concern_defaults_cache_lookup_mongod.cpp', + ], + LIBDEPS_PRIVATE=[ + # NOTE: Do not add new libdeps (public or private) here unless + # required by the linker to satisfy symbol dependencies from + # the files listed above in `sources`. If you need to add a + # library to inject a static or mongo initializer to mongod, + # please add that library as a private libdep of + # mongod_initializers. + 'base', + 'client/clientdriver_minimal', + 'db/auth/auth_op_observer', + 'db/catalog/catalog_impl', + 'db/catalog/collection', + 'db/catalog/health_log', + 'db/commands/mongod', + 'db/concurrency/flow_control_ticketholder', + 'db/concurrency/lock_manager', + 'db/free_mon/free_mon_mongod', + 'db/ftdc/ftdc_mongod', + 'db/index/index_access_method_factory', + 'db/index/index_access_methods', + 'db/index_builds_coordinator_mongod', + 'db/initialize_server_security_state', + 'db/initialize_snmp', + 'db/keys_collection_client_direct', + 'db/kill_sessions', + 'db/kill_sessions_local', + 'db/log_process_details', + 'db/logical_clock', + 'db/mirror_maestro', + 'db/mongod_options', + 'db/op_observer', + 'db/periodic_runner_job_abort_expired_transactions', + 'db/pipeline/process_interface/mongod_process_interface_factory', + 'db/repair_database_and_check_version', + 'db/repl/drop_pending_collection_reaper', + 'db/repl/repl_coordinator_impl', + 'db/repl/replication_recovery', + 'db/repl/serveronly_repl', + 'db/repl/storage_interface_impl', + 'db/repl/topology_coordinator', + 'db/s/op_observer_sharding_impl', + 'db/s/sessions_collection_config_server', + 'db/s/sharding_runtime_d', + 'db/serverinit', + 'db/service_context_d', + 'db/service_liaison_mongod', + 'db/sessions_collection_rs', + 'db/sessions_collection_standalone', + 'db/startup_warnings_mongod', + 'db/storage/backup_cursor_hooks', + 'db/storage/flow_control', + 'db/storage/flow_control_parameters', + 'db/storage/storage_control', + 'db/storage/storage_engine_common', + 'db/system_index', + 'db/ttl_d', + 'mongod_initializers', + 's/grid', + 's/sessions_collection_sharded', + 's/sessions_collection_sharded', + 'scripting/scripting', + 'transport/service_entry_point', + 'transport/transport_layer_manager', + 'util/cmdline_utils/cmdline_utils', + 'util/concurrency/thread_pool', + 'util/latch_analyzer' if get_option('use-diagnostic-latches') == 'on' else [], + 'util/net/ssl_manager', + 'util/signal_handlers', + 'watchdog/watchdog_mongod', + ], + LIBDEPS=[ + # NOTE: This list must remain empty. Please only add to LIBDEPS_PRIVATE ], ) @@ -491,7 +596,7 @@ if not hygienic: if env.TargetOSIs('windows'): generatedServerManifest = env.Substfile( - 's/server.manifest.in', + 's/mongos.manifest.in', SUBST_DICT=[ ('@mongo_version_major@', version_parts[0]), ('@mongo_version_minor@', version_parts[1]), @@ -501,7 +606,7 @@ if env.TargetOSIs('windows'): ]) env.Alias('generated-sources', generatedServerManifest) - env.Depends("s/server.res", generatedServerManifest) + env.Depends("s/mongos.res", generatedServerManifest) mongotrafficreader = env.Program( @@ -524,19 +629,39 @@ if not hygienic: mongos = env.Program( target='mongos', source=[ - "db/read_write_concern_defaults_cache_lookup_mongos.cpp", + 's/mongos.cpp', + ] + env.WindowsResourceFile("s/mongos.rc"), + LIBDEPS=[ + # NOTE: Do not add new libdeps (public or private) here unless + # required by the linker to satisfy symbol dependencies from + # the files listed above in `sources`. If you need to add a + # library to inject a static or mongo initializer to mongos, + # please add that library as a private libdep of + # mongos_initializers. + 'base', + 'mongos_main', + 'util/quick_exit' + ], + AIB_COMPONENT="mongos", + AIB_COMPONENTS_EXTRA=[ + "core", + "dist", + "dist-test", + "servers", + "integration-tests", + ], +) + +env.Library( + target='mongos_initializers', + source=[ 's/cluster_cursor_stats.cpp', - 's/mongos_options.cpp', - 's/mongos_options_init.cpp', - env.Idlc('s/mongos_options.idl')[0], 's/router_transactions_server_status.cpp', 's/s_sharding_server_status.cpp', - 's/server.cpp', - 's/service_entry_point_mongos.cpp', - 's/sharding_uptime_reporter.cpp', - 's/version_mongos.cpp', - ] + env.WindowsResourceFile("s/server.rc"), - LIBDEPS=[ + ], + LIBDEPS_PRIVATE=[ + # NOTE: If you need to add a static or mongo initializer to mongos startup, + # please add that library here, as a private library dependency. 'db/audit', 'db/auth/authmongos', 'db/commands/server_status', @@ -576,76 +701,81 @@ mongos = env.Program( 'util/latch_analyzer' if get_option('use-diagnostic-latches') == 'on' else [], 'util/net/ssl_options_server' if get_option('ssl') == 'on' else '', 'util/ntservice', + 'util/options_parser/options_parser', + 'util/options_parser/options_parser_init', 'util/version_impl', ], + LIBDEPS=[ + # NOTE: This list must remain empty. Please only add to LIBDEPS_PRIVATE + ], +) + +env.Library( + target='mongos_main', + source=[ + 'db/read_write_concern_defaults_cache_lookup_mongos.cpp', + 's/mongos_main.cpp', + 's/mongos_options.cpp', + 's/mongos_options_init.cpp', + env.Idlc('s/mongos_options.idl')[0], + 's/service_entry_point_mongos.cpp', + 's/sharding_uptime_reporter.cpp', + 's/version_mongos.cpp', + ], LIBDEPS_PRIVATE=[ - 'util/options_parser/options_parser_init', - 'util/options_parser/options_parser', + # NOTE: Do not add new libdeps (public or private) here unless + # required by the linker to satisfy symbol dependencies from + # the files listed above in `sources`. If you need to add a + # library to inject a static or mongo initializer to mongos, + # please add that library as a private libdep of + # mongos_initializers. + 'db/audit', + 'db/auth/authmongos', + 'db/ftdc/ftdc_mongos', + 'db/initialize_server_security_state', + 'db/log_process_details', + 'db/read_write_concern_defaults', + 'db/serverinit', + 'db/service_liaison_mongos', + 'db/session_catalog', + 'db/startup_warnings_common', + 'mongos_initializers', + 's/client/sharding_client', + 's/cluster_last_error_info', + 's/commands/cluster_commands', + 's/committed_optime_metadata_hook', + 's/common_s', + 's/mongos_topology_coordinator', + 's/query/cluster_cursor_cleanup_job', + 's/sessions_collection_sharded', + 's/sharding_egress_metadata_hook_for_mongos', + 's/sharding_initialization', + 's/sharding_router_api', + 'transport/service_entry_point', + 'transport/transport_layer_manager', + 'util/latch_analyzer' if get_option('use-diagnostic-latches') == 'on' else [], + 'util/net/ssl_manager', + 'util/periodic_runner_factory', + 'util/signal_handlers', + ], + LIBDEPS=[ + # NOTE: This list must remain empty. Please only add to LIBDEPS_PRIVATE ], - AIB_COMPONENT="mongos", - AIB_COMPONENTS_EXTRA=[ - "core", - "dist", - "dist-test", - "servers", - "integration-tests", - ] ) + if not hygienic: env.Install('#/', mongos) -env.Library("linenoise_utf8", - source=[ - "shell/linenoise_utf8.cpp", - ]) - # --- shell --- if not has_option('noshell') and usemozjs: - shell_core_env = env.Clone() - if has_option("safeshell"): - shell_core_env.Append(CPPDEFINES=["MONGO_SAFE_SHELL"]) - shell_core_env.Library("shell_core", - source=[ - "shell/linenoise.cpp", - "shell/mk_wcwidth.cpp" - ], - LIBDEPS=[ - 'client/clientdriver_network', - 'db/catalog/index_key_validate', - 'db/logical_session_id_helpers', - 'db/mongohasher', - 'db/query/command_request_response', - 'db/query/query_request', - 'db/server_options_core', - 'db/traffic_reader', - 'linenoise_utf8', - 'rpc/protocol', - 'scripting/scripting', - 'shell/benchrun', - 'shell/mongojs', - 'shell/shell_utils', - 'transport/message_compressor', - 'transport/transport_layer_manager', - 'util/net/network', - 'util/options_parser/options_parser_init', - 'util/password', - 'util/processinfo', - 'util/signal_handlers', - 'util/version_impl', - 'executor/thread_pool_task_executor', - 'executor/network_interface_thread_pool', - 'executor/network_interface_factory' - ], - ) - shellEnv = env.Clone() if env.TargetOSIs('windows'): shellEnv.Append(LIBS=["winmm.lib"]) generatedMongoManifest = shellEnv.Substfile( - 'shell/shell.manifest.in', + 'shell/mongo.manifest.in', SUBST_DICT=[ ('@mongo_version_major@', version_parts[0]), ('@mongo_version_minor@', version_parts[1]), @@ -654,31 +784,22 @@ if not has_option('noshell') and usemozjs: ('@mongo_version_extra_str@', version_extra), ]) shellEnv.Alias('generated-sources', generatedMongoManifest) - shellEnv.Depends("shell/shell.res", generatedMongoManifest) + shellEnv.Depends("shell/mongo.res", generatedMongoManifest) mongo_shell = shellEnv.Program( - "mongo", - [ - "shell/dbshell.cpp", - "shell/mongodbcr.cpp", - "shell/shell_options_init.cpp", - ] + env.WindowsResourceFile("shell/shell.rc"), + target="mongo", + source=[ + "shell/mongo.cpp", + ] + env.WindowsResourceFile("shell/mongo.rc"), LIBDEPS=[ - "$BUILD_DIR/third_party/shim_pcrecpp", - "shell_core", - "db/server_options_core", - "client/clientdriver_network", - "shell/kms_shell" if get_option('ssl') == 'on' else '', - "shell/encrypted_dbclient" if get_option('ssl') == 'on' else '', - "$BUILD_DIR/mongo/util/password", - '$BUILD_DIR/mongo/db/storage/duplicate_key_error_info', - "$BUILD_DIR/mongo/db/views/resolved_view", - ], - LIBDEPS_PRIVATE=[ - 'shell/shell_options_register', - 'transport/message_compressor_options_client', - "$BUILD_DIR/mongo/client/connection_string", - '$BUILD_DIR/mongo/util/net/ssl_options_client' if get_option('ssl') == 'on' else '', + # NOTE: Do not add new libdeps (public or private) here unless + # required by the linker to satisfy symbol dependencies from + # the files listed above in `sources`. If you need to add a + # library to inject a static or mongo initializer to mongo, + # please add that library as a private libdep of + # mongo_initializers. + 'base', + 'mongo_main', ], AIB_COMPONENT="mongo", AIB_COMPONENTS_EXTRA=[ @@ -690,6 +811,79 @@ if not has_option('noshell') and usemozjs: ], ) + env.Library( + target="mongo_initializers", + source=[ + "shell/mongodbcr.cpp", + "shell/shell_options_init.cpp", + ], + LIBDEPS_PRIVATE=[ + # NOTE: If you need to add a static or mongo initializer to mongo startup, + # please add that library here, as a private library dependency. + "$BUILD_DIR/third_party/shim_pcrecpp", + "client/clientdriver_network", + "client/connection_string", + "db/catalog/index_key_validate", + "db/logical_session_id_helpers", + "db/mongohasher", + "db/query/command_request_response", + "db/query/query_request", + "db/server_options_core", + "db/storage/duplicate_key_error_info", + "db/traffic_reader", + "db/views/resolved_view", + "executor/network_interface_factory", + "executor/network_interface_thread_pool", + "executor/thread_pool_task_executor", + "rpc/protocol", + "scripting/scripting", + "shell/benchrun", + "shell/encrypted_dbclient" if get_option('ssl') == 'on' else '', + "shell/kms_shell" if get_option('ssl') == 'on' else '', + "shell/mongojs", + "shell/shell_options_register", + "shell/shell_utils", + "transport/message_compressor", + "transport/message_compressor_options_client", + "transport/transport_layer_manager", + "util/net/network", + "util/net/ssl_options_client" if get_option('ssl') == 'on' else '', + "util/options_parser/options_parser_init", + "util/password", + "util/processinfo", + "util/signal_handlers", + "util/version_impl", + ], + LIBDEPS=[ + # NOTE: This list must remain empty. Please only add to LIBDEPS_PRIVATE + ], + + ) + + env.Library( + target="mongo_main", + source=[ + "shell/mongo_main.cpp", + ], + LIBDEPS_PRIVATE=[ + # NOTE: Do not add new libdeps (public or private) here unless + # required by the linker to satisfy symbol dependencies from + # the files listed above in `sources`. If you need to add a + # library to inject a static or mongo initializer to mongo, + # please add that library as a private libdep of + # mongo_initializers. + "mongo_initializers", + "shell/linenoise", + "shell/shell_utils", + "transport/transport_layer", + "util/net/ssl_manager", + "util/signal_handlers", + ], + LIBDEPS=[ + # NOTE: This list must remain empty. Please only add to LIBDEPS_PRIVATE + ], + ) + if not hygienic: shellEnv.Install( '#/', mongo_shell ) else: diff --git a/src/mongo/db/fts/unicode/SConscript b/src/mongo/db/fts/unicode/SConscript index 85f71077606..2b783364d64 100644 --- a/src/mongo/db/fts/unicode/SConscript +++ b/src/mongo/db/fts/unicode/SConscript @@ -48,7 +48,7 @@ env.Library( ], LIBDEPS=[ '$BUILD_DIR/mongo/base', - '$BUILD_DIR/mongo/linenoise_utf8', + '$BUILD_DIR/mongo/shell/linenoise_utf8', ] ) diff --git a/src/mongo/db/mongod.cpp b/src/mongo/db/mongod.cpp new file mode 100644 index 00000000000..3fd8f53c106 --- /dev/null +++ b/src/mongo/db/mongod.cpp @@ -0,0 +1,52 @@ +/** + * Copyright (C) 2020-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#include "mongo/platform/basic.h" + +#include "mongo/db/mongod_main.h" +#include "mongo/util/quick_exit.h" +#include "mongo/util/text.h" + +#if defined(_WIN32) +// In Windows, wmain() is an alternate entry point for main(), and receives the same parameters +// as main() but encoded in Windows Unicode (UTF-16); "wide" 16-bit wchar_t characters. The +// WindowsCommandLine object converts these wide character strings to a UTF-8 coded equivalent +// and makes them available through the argv() and envp() members. This enables mongoDbMain() +// to process UTF-8 encoded arguments and environment variables without regard to platform. +int wmain(int argc, wchar_t* argvW[], wchar_t* envpW[]) { + mongo::WindowsCommandLine wcl(argc, argvW, envpW); + int exitCode = mongo::mongod_main(argc, wcl.argv(), wcl.envp()); + mongo::quickExit(exitCode); +} +#else +int main(int argc, char* argv[], char** envp) { + int exitCode = mongo::mongod_main(argc, argv, envp); + mongo::quickExit(exitCode); +} +#endif diff --git a/src/mongo/db/db.manifest.in b/src/mongo/db/mongod.manifest.in index ea9d02d9a83..ea9d02d9a83 100644 --- a/src/mongo/db/db.manifest.in +++ b/src/mongo/db/mongod.manifest.in diff --git a/src/mongo/db/db.rc b/src/mongo/db/mongod.rc index 343ea2d7642..c2fbc5c9751 100644 --- a/src/mongo/db/db.rc +++ b/src/mongo/db/mongod.rc @@ -53,4 +53,4 @@ BEGIN END END -CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "mongo/db/db.manifest" +CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "mongo/db/mongod.manifest" diff --git a/src/mongo/db/mongod_initializers.cpp b/src/mongo/db/mongod_initializers.cpp new file mode 100644 index 00000000000..854bf218172 --- /dev/null +++ b/src/mongo/db/mongod_initializers.cpp @@ -0,0 +1,31 @@ +/** + * Copyright (C) 2020-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +// This file intentionally blank. mongod_initializers.cpp exists only to provide +// a compilable source file for systems which cannot produce a library with no sources. diff --git a/src/mongo/db/db.cpp b/src/mongo/db/mongod_main.cpp index bc4554893f6..759df7503c3 100644 --- a/src/mongo/db/db.cpp +++ b/src/mongo/db/mongod_main.cpp @@ -31,6 +31,8 @@ #include "mongo/platform/basic.h" +#include "mongo/db/mongod_main.h" + #include <boost/filesystem/operations.hpp> #include <boost/optional.hpp> #include <fstream> @@ -1262,7 +1264,9 @@ void shutdownTask(const ShutdownTaskArgs& shutdownArgs) { #endif } -int mongoDbMain(int argc, char* argv[], char** envp) { +} // namespace + +int mongod_main(int argc, char* argv[], char** envp) { ThreadSafetyContext::getThreadSafetyContext()->forbidMultiThreading(); registerShutdownTask(shutdownTask); @@ -1339,23 +1343,4 @@ int mongoDbMain(int argc, char* argv[], char** envp) { return 0; } -} // namespace } // namespace mongo - -#if defined(_WIN32) -// In Windows, wmain() is an alternate entry point for main(), and receives the same parameters -// as main() but encoded in Windows Unicode (UTF-16); "wide" 16-bit wchar_t characters. The -// WindowsCommandLine object converts these wide character strings to a UTF-8 coded equivalent -// and makes them available through the argv() and envp() members. This enables mongoDbMain() -// to process UTF-8 encoded arguments and environment variables without regard to platform. -int wmain(int argc, wchar_t* argvW[], wchar_t* envpW[]) { - mongo::WindowsCommandLine wcl(argc, argvW, envpW); - int exitCode = mongo::mongoDbMain(argc, wcl.argv(), wcl.envp()); - mongo::quickExit(exitCode); -} -#else -int main(int argc, char* argv[], char** envp) { - int exitCode = mongo::mongoDbMain(argc, argv, envp); - mongo::quickExit(exitCode); -} -#endif diff --git a/src/mongo/db/mongod_main.h b/src/mongo/db/mongod_main.h new file mode 100644 index 00000000000..0e5a8e06383 --- /dev/null +++ b/src/mongo/db/mongod_main.h @@ -0,0 +1,34 @@ +/** + * Copyright (C) 2020-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +namespace mongo { + +int mongod_main(int argc, char* argv[], char** envp); + +} // namespace mongo diff --git a/src/mongo/db/storage/SConscript b/src/mongo/db/storage/SConscript index e32b8ba329a..4d5f1ef273b 100644 --- a/src/mongo/db/storage/SConscript +++ b/src/mongo/db/storage/SConscript @@ -186,9 +186,9 @@ env.Library( ], LIBDEPS= ['$BUILD_DIR/mongo/base', '$BUILD_DIR/mongo/db/service_context'], - PROGDEPS_DEPENDENTS=[ - '$BUILD_DIR/mongo/mongod', - '$BUILD_DIR/mongo/mongos', + LIBDEPS_DEPENDENTS=[ + '$BUILD_DIR/mongo/mongod_initializers', + '$BUILD_DIR/mongo/mongos_initializers', ], ) @@ -201,8 +201,8 @@ env.Library( '$BUILD_DIR/mongo/base', '$BUILD_DIR/mongo/db/service_context', ], - PROGDEPS_DEPENDENTS=[ - '$BUILD_DIR/mongo/mongod', + LIBDEPS_DEPENDENTS=[ + '$BUILD_DIR/mongo/mongod_initializers', ], ) diff --git a/src/mongo/db/storage/wiredtiger/SConscript b/src/mongo/db/storage/wiredtiger/SConscript index 79bc99ec83a..d679a2ed6b9 100644 --- a/src/mongo/db/storage/wiredtiger/SConscript +++ b/src/mongo/db/storage/wiredtiger/SConscript @@ -18,10 +18,11 @@ env.Library( ], LIBDEPS= ['$BUILD_DIR/mongo/base', '$BUILD_DIR/mongo/db/service_context'], - PROGDEPS_DEPENDENTS=[ - '$BUILD_DIR/mongo/mongod', - '$BUILD_DIR/mongo/mongos', + LIBDEPS_DEPENDENTS=[ + '$BUILD_DIR/mongo/mongod_initializers', + '$BUILD_DIR/mongo/mongos_initializers', ], + ) if wiredtiger: diff --git a/src/mongo/dbtests/SConscript b/src/mongo/dbtests/SConscript index c220ba2b041..3337f065559 100644 --- a/src/mongo/dbtests/SConscript +++ b/src/mongo/dbtests/SConscript @@ -129,10 +129,12 @@ if not has_option('noshell') and usemozjs: ], LIBDEPS=[ "$BUILD_DIR/mongo/bson/mutable/mutable_bson_test_utils", + "$BUILD_DIR/mongo/client/clientdriver_network", "$BUILD_DIR/mongo/client/replica_set_monitor_protocol_test_util", "$BUILD_DIR/mongo/db/auth/authmongod", "$BUILD_DIR/mongo/db/bson/dotted_path_support", "$BUILD_DIR/mongo/db/catalog/collection_validation", + "$BUILD_DIR/mongo/db/catalog/index_key_validate", "$BUILD_DIR/mongo/db/catalog/multi_index_block", "$BUILD_DIR/mongo/db/catalog_raii", "$BUILD_DIR/mongo/db/commands/mongod", @@ -142,10 +144,13 @@ if not has_option('noshell') and usemozjs: "$BUILD_DIR/mongo/db/index/index_access_methods", "$BUILD_DIR/mongo/db/index/index_build_interceptor", "$BUILD_DIR/mongo/db/logical_clock", + "$BUILD_DIR/mongo/db/logical_session_id_helpers", "$BUILD_DIR/mongo/db/logical_time_metadata_hook", + "$BUILD_DIR/mongo/db/mongohasher", "$BUILD_DIR/mongo/db/query/collation/collator_interface_mock", "$BUILD_DIR/mongo/db/query/command_request_response", "$BUILD_DIR/mongo/db/query/query_planner_test_lib", + "$BUILD_DIR/mongo/db/query/query_request", "$BUILD_DIR/mongo/db/query/query_test_service_context", "$BUILD_DIR/mongo/db/query_exec", "$BUILD_DIR/mongo/db/repl/drop_pending_collection_reaper", @@ -158,20 +163,34 @@ if not has_option('noshell') and usemozjs: "$BUILD_DIR/mongo/db/repl/storage_interface_impl", "$BUILD_DIR/mongo/db/repl/timestamp_block", "$BUILD_DIR/mongo/db/s/op_observer_sharding_impl", + "$BUILD_DIR/mongo/db/server_options_core", "$BUILD_DIR/mongo/db/sessions_collection_standalone", "$BUILD_DIR/mongo/db/storage/biggie/storage_biggie", "$BUILD_DIR/mongo/db/storage/durable_catalog_impl", "$BUILD_DIR/mongo/db/storage/ephemeral_for_test/storage_ephemeral_for_test", - "$BUILD_DIR/mongo/db/storage/storage_engine_impl", "$BUILD_DIR/mongo/db/storage/storage_debug_util", + "$BUILD_DIR/mongo/db/storage/storage_engine_impl", "$BUILD_DIR/mongo/db/storage/wiredtiger/storage_wiredtiger" if wiredtiger else [], + "$BUILD_DIR/mongo/db/traffic_reader", "$BUILD_DIR/mongo/db/transaction", - "$BUILD_DIR/mongo/shell_core", + "$BUILD_DIR/mongo/executor/network_interface_factory", + "$BUILD_DIR/mongo/executor/network_interface_thread_pool", + "$BUILD_DIR/mongo/executor/thread_pool_task_executor", + "$BUILD_DIR/mongo/rpc/protocol", + "$BUILD_DIR/mongo/scripting/scripting", + "$BUILD_DIR/mongo/shell/benchrun", + "$BUILD_DIR/mongo/shell/mongojs", + "$BUILD_DIR/mongo/shell/shell_utils", + "$BUILD_DIR/mongo/transport/message_compressor", "$BUILD_DIR/mongo/transport/message_compressor_options_server", "$BUILD_DIR/mongo/transport/transport_layer_manager", "$BUILD_DIR/mongo/util/clock_source_mock", "$BUILD_DIR/mongo/util/net/network", + "$BUILD_DIR/mongo/util/options_parser/options_parser_init", + "$BUILD_DIR/mongo/util/password", + "$BUILD_DIR/mongo/util/processinfo", "$BUILD_DIR/mongo/util/progress_meter", + "$BUILD_DIR/mongo/util/signal_handlers", "$BUILD_DIR/mongo/util/version_impl", "mocklib", "testframework", diff --git a/src/mongo/s/mongos.cpp b/src/mongo/s/mongos.cpp new file mode 100644 index 00000000000..d9cc1790464 --- /dev/null +++ b/src/mongo/s/mongos.cpp @@ -0,0 +1,50 @@ +/** + * Copyright (C) 2020-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#include "mongo/platform/basic.h" + +#include "mongo/s/mongos_main.h" +#include "mongo/util/exit.h" +#include "mongo/util/text.h" + +#if defined(_WIN32) +// In Windows, wmain() is an alternate entry point for main(), and receives the same parameters +// as main() but encoded in Windows Unicode (UTF-16); "wide" 16-bit wchar_t characters. The +// WindowsCommandLine object converts these wide character strings to a UTF-8 coded equivalent +// and makes them available through the argv() and envp() members. This enables mongoSMain() +// to process UTF-8 encoded arguments and environment variables without regard to platform. +int wmain(int argc, wchar_t* argvW[], wchar_t* envpW[]) { + mongo::WindowsCommandLine wcl(argc, argvW, envpW); + mongo::exitCleanly(mongo::mongos_main(argc, wcl.argv(), wcl.envp())); +} +#else +int main(int argc, char* argv[], char** envp) { + mongo::exitCleanly(mongo::mongos_main(argc, argv, envp)); +} +#endif diff --git a/src/mongo/s/server.manifest.in b/src/mongo/s/mongos.manifest.in index cec56019b5e..cec56019b5e 100644 --- a/src/mongo/s/server.manifest.in +++ b/src/mongo/s/mongos.manifest.in diff --git a/src/mongo/s/server.rc b/src/mongo/s/mongos.rc index 8677f261e16..fbc7c08c4f9 100644 --- a/src/mongo/s/server.rc +++ b/src/mongo/s/mongos.rc @@ -53,4 +53,4 @@ BEGIN END END -CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "mongo/s/server.manifest" +CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "mongo/s/mongos.manifest" diff --git a/src/mongo/s/server.cpp b/src/mongo/s/mongos_main.cpp index cf86f70a63d..6894950f899 100644 --- a/src/mongo/s/server.cpp +++ b/src/mongo/s/mongos_main.cpp @@ -31,6 +31,8 @@ #include "mongo/platform/basic.h" +#include "mongo/s/mongos_main.h" + #include <boost/optional.hpp> #include <memory> @@ -883,7 +885,6 @@ ExitCode main(ServiceContext* serviceContext) { return runMongosServer(serviceContext); } -namespace { MONGO_INITIALIZER_GENERAL(ForkServer, ("EndStartupOptionHandling"), ("default")) (InitializerContext* context) { forkServerOrDie(); @@ -913,7 +914,7 @@ MONGO_INITIALIZER_GENERAL(setSSLManagerType, MONGO_NO_PREREQUISITES, ("SSLManage } // namespace -ExitCode mongoSMain(int argc, char* argv[], char** envp) { +ExitCode mongos_main(int argc, char* argv[], char** envp) { setMongos(); if (argc < 1) @@ -985,21 +986,4 @@ ExitCode mongoSMain(int argc, char* argv[], char** envp) { } } -} // namespace } // namespace mongo - -#if defined(_WIN32) -// In Windows, wmain() is an alternate entry point for main(), and receives the same parameters -// as main() but encoded in Windows Unicode (UTF-16); "wide" 16-bit wchar_t characters. The -// WindowsCommandLine object converts these wide character strings to a UTF-8 coded equivalent -// and makes them available through the argv() and envp() members. This enables mongoSMain() -// to process UTF-8 encoded arguments and environment variables without regard to platform. -int wmain(int argc, wchar_t* argvW[], wchar_t* envpW[]) { - mongo::WindowsCommandLine wcl(argc, argvW, envpW); - mongo::exitCleanly(mongo::mongoSMain(argc, wcl.argv(), wcl.envp())); -} -#else -int main(int argc, char* argv[], char** envp) { - mongo::exitCleanly(mongo::mongoSMain(argc, argv, envp)); -} -#endif diff --git a/src/mongo/s/mongos_main.h b/src/mongo/s/mongos_main.h new file mode 100644 index 00000000000..e68edc33563 --- /dev/null +++ b/src/mongo/s/mongos_main.h @@ -0,0 +1,36 @@ +/** + * Copyright (C) 2020-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#include "mongo/util/exit_code.h" + +namespace mongo { + +ExitCode mongos_main(int argc, char* argv[], char** envp); + +} // namespace mongo diff --git a/src/mongo/shell/SConscript b/src/mongo/shell/SConscript index 21dd85b2b9b..bdf17c86167 100644 --- a/src/mongo/shell/SConscript +++ b/src/mongo/shell/SConscript @@ -165,8 +165,8 @@ env.Library( "kms_shell.cpp", ], LIBDEPS_PRIVATE=[ - '$BUILD_DIR/mongo/shell_core', 'kms', + 'shell_utils', ], ) @@ -190,6 +190,27 @@ scriptingEnv.Library( ], ) +env.Library( + target="linenoise_utf8", + source=[ + "linenoise_utf8.cpp", + ], +) + +env.Library( + target="linenoise", + source=[ + "linenoise.cpp", + "mk_wcwidth.cpp" + ], + LIBDEPS=[ + '$BUILD_DIR/mongo/base', + ], + LIBDEPS_PRIVATE=[ + "linenoise_utf8", + ], +) + env.CppUnitTest( target='shell_test', source=[ diff --git a/src/mongo/shell/mongo.cpp b/src/mongo/shell/mongo.cpp new file mode 100644 index 00000000000..e6e0b199951 --- /dev/null +++ b/src/mongo/shell/mongo.cpp @@ -0,0 +1,45 @@ +/** + * Copyright (C) 2020-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#include "mongo/platform/basic.h" + +#include "mongo/shell/mongo_main.h" +#include "mongo/util/quick_exit.h" +#include "mongo/util/text.h" + +#ifdef _WIN32 +int wmain(int argc, wchar_t* argvW[], wchar_t* envpW[]) { + mongo::WindowsCommandLine wcl(argc, argvW, envpW); + mongo::quickExit(mongo::mongo_main(argc, wcl.argv(), wcl.envp())); +} +#else // #ifdef _WIN32 +int main(int argc, char* argv[], char** envp) { + mongo::quickExit(mongo::mongo_main(argc, argv, envp)); +} +#endif // #ifdef _WIN32 diff --git a/src/mongo/shell/shell.manifest.in b/src/mongo/shell/mongo.manifest.in index 2f5ee512ee0..2f5ee512ee0 100644 --- a/src/mongo/shell/shell.manifest.in +++ b/src/mongo/shell/mongo.manifest.in diff --git a/src/mongo/shell/shell.rc b/src/mongo/shell/mongo.rc index b5e67185eb6..fe63acd0e3d 100644 --- a/src/mongo/shell/shell.rc +++ b/src/mongo/shell/mongo.rc @@ -53,4 +53,4 @@ BEGIN END END -CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "mongo/shell/shell.manifest" +CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "mongo/shell/mongo.manifest" diff --git a/src/mongo/shell/dbshell.cpp b/src/mongo/shell/mongo_main.cpp index 2a4fd0b761f..a7051081d3f 100644 --- a/src/mongo/shell/dbshell.cpp +++ b/src/mongo/shell/mongo_main.cpp @@ -31,6 +31,8 @@ #include "mongo/platform/basic.h" +#include "mongo/shell/mongo_main.h" + #include <boost/core/null_deleter.hpp> #include <boost/filesystem/operations.hpp> #include <boost/log/attributes/value_extraction.hpp> @@ -98,13 +100,14 @@ #endif using namespace std::literals::string_literals; -using namespace mongo; + +namespace mongo { +namespace { bool gotInterrupted = false; bool inMultiLine = false; static AtomicWord<bool> atPrompt(false); // can eval before getting to prompt -namespace { const std::string kDefaultMongoHost = "127.0.0.1"s; const std::string kDefaultMongoPort = "27017"s; const std::string kDefaultMongoURL = "mongodb://"s + kDefaultMongoHost + ":"s + kDefaultMongoPort; @@ -213,10 +216,6 @@ public: } }; -} // namespace - -namespace mongo { - enum ShellExitCode : int { kDBException = 1, kInputFileError = -3, @@ -227,7 +226,6 @@ enum ShellExitCode : int { }; Scope* shellMainScope; -} // namespace mongo bool isSessionTimedOut() { static Date_t previousCommandTime = Date_t::now(); @@ -697,7 +695,6 @@ static void edit(const std::string& whatToEdit) { } } -namespace { bool mechanismRequiresPassword(const MongoURI& uri) { if (const auto authMechanisms = uri.getOption("authMechanism")) { constexpr std::array<StringData, 3> passwordlessMechanisms{ @@ -711,465 +708,461 @@ bool mechanismRequiresPassword(const MongoURI& uri) { } return true; } + } // namespace -int _main(int argc, char* argv[], char** envp) { - registerShutdownTask([] { - // NOTE: This function may be called at any time. It must not - // depend on the prior execution of mongo initializers or the - // existence of threads. - ::killOps(); - ::shellHistoryDone(); - }); +int mongo_main(int argc, char* argv[], char** envp) { - setupSignalHandlers(); - setupSignals(); + try { + + registerShutdownTask([] { + // NOTE: This function may be called at any time. It must not + // depend on the prior execution of mongo initializers or the + // existence of threads. + killOps(); + shellHistoryDone(); + }); - // Log to stdout for any early logging before we re-configure the logger - auto& lv2Manager = logv2::LogManager::global(); - logv2::LogDomainGlobal::ConfigurationOptions lv2Config; - uassertStatusOK(lv2Manager.getGlobalDomainInternal().configure(lv2Config)); + setupSignalHandlers(); + setupSignals(); - mongo::shell_utils::RecordMyLocation(argv[0]); + // Log to stdout for any early logging before we re-configure the logger + auto& lv2Manager = logv2::LogManager::global(); + logv2::LogDomainGlobal::ConfigurationOptions lv2Config; + uassertStatusOK(lv2Manager.getGlobalDomainInternal().configure(lv2Config)); - mongo::runGlobalInitializersOrDie(argc, argv, envp); - setGlobalServiceContext(ServiceContext::make()); - // TODO This should use a TransportLayerManager or TransportLayerFactory - auto serviceContext = getGlobalServiceContext(); + mongo::shell_utils::RecordMyLocation(argv[0]); - OCSPManager::get()->startThreadPool(); + mongo::runGlobalInitializersOrDie(argc, argv, envp); + setGlobalServiceContext(ServiceContext::make()); + // TODO This should use a TransportLayerManager or TransportLayerFactory + auto serviceContext = getGlobalServiceContext(); - transport::TransportLayerASIO::Options opts; - opts.enableIPv6 = shellGlobalParams.enableIPv6; - opts.mode = transport::TransportLayerASIO::Options::kEgress; + OCSPManager::get()->startThreadPool(); - serviceContext->setTransportLayer( - std::make_unique<transport::TransportLayerASIO>(opts, nullptr)); - auto tlPtr = serviceContext->getTransportLayer(); - uassertStatusOK(tlPtr->setup()); - uassertStatusOK(tlPtr->start()); + transport::TransportLayerASIO::Options opts; + opts.enableIPv6 = shellGlobalParams.enableIPv6; + opts.mode = transport::TransportLayerASIO::Options::kEgress; - // hide password from ps output - redactPasswordOptions(argc, argv); + serviceContext->setTransportLayer( + std::make_unique<transport::TransportLayerASIO>(opts, nullptr)); + auto tlPtr = serviceContext->getTransportLayer(); + uassertStatusOK(tlPtr->setup()); + uassertStatusOK(tlPtr->start()); - ErrorExtraInfo::invariantHaveAllParsers(); + // hide password from ps output + redactPasswordOptions(argc, argv); - if (!mongo::serverGlobalParams.quiet.load()) - std::cout << mongoShellVersion(VersionInfoInterface::instance()) << std::endl; + ErrorExtraInfo::invariantHaveAllParsers(); - auto consoleSink = boost::make_shared<boost::log::sinks::synchronous_sink<ShellBackend>>(); - consoleSink->set_filter(logv2::ComponentSettingsFilter(lv2Manager.getGlobalDomain(), - lv2Manager.getGlobalSettings())); - consoleSink->set_formatter(ShellFormatter()); + if (!mongo::serverGlobalParams.quiet.load()) + std::cout << mongoShellVersion(VersionInfoInterface::instance()) << std::endl; - consoleSink->locked_backend()->add_stream( - boost::shared_ptr<std::ostream>(&logv2::Console::out(), boost::null_deleter())); + auto consoleSink = boost::make_shared<boost::log::sinks::synchronous_sink<ShellBackend>>(); + consoleSink->set_filter(logv2::ComponentSettingsFilter(lv2Manager.getGlobalDomain(), + lv2Manager.getGlobalSettings())); + consoleSink->set_formatter(ShellFormatter()); - consoleSink->locked_backend()->auto_flush(); + consoleSink->locked_backend()->add_stream( + boost::shared_ptr<std::ostream>(&logv2::Console::out(), boost::null_deleter())); - // Remove the initial config from above when setting this sink, otherwise we log everything - // twice. - lv2Config.makeDisabled(); - uassertStatusOK(lv2Manager.getGlobalDomainInternal().configure(lv2Config)); + consoleSink->locked_backend()->auto_flush(); - boost::log::core::get()->add_sink(std::move(consoleSink)); + // Remove the initial config from above when setting this sink, otherwise we log everything + // twice. + lv2Config.makeDisabled(); + uassertStatusOK(lv2Manager.getGlobalDomainInternal().configure(lv2Config)); - // Get the URL passed to the shell - std::string& cmdlineURI = shellGlobalParams.url; + boost::log::core::get()->add_sink(std::move(consoleSink)); - // Parse the output of getURIFromArgs which will determine if --host passed in a URI - MongoURI parsedURI; - parsedURI = uassertStatusOK(MongoURI::parse(getURIFromArgs( - cmdlineURI, str::escape(shellGlobalParams.dbhost), str::escape(shellGlobalParams.port)))); + // Get the URL passed to the shell + std::string& cmdlineURI = shellGlobalParams.url; - // TODO: add in all of the relevant shellGlobalParams to parsedURI - parsedURI.setOptionIfNecessary("compressors"s, shellGlobalParams.networkMessageCompressors); - parsedURI.setOptionIfNecessary("authMechanism"s, shellGlobalParams.authenticationMechanism); - parsedURI.setOptionIfNecessary("authSource"s, shellGlobalParams.authenticationDatabase); - parsedURI.setOptionIfNecessary("gssapiServiceName"s, shellGlobalParams.gssapiServiceName); - parsedURI.setOptionIfNecessary("gssapiHostName"s, shellGlobalParams.gssapiHostName); + // Parse the output of getURIFromArgs which will determine if --host passed in a URI + MongoURI parsedURI; + parsedURI = + uassertStatusOK(MongoURI::parse(getURIFromArgs(cmdlineURI, + str::escape(shellGlobalParams.dbhost), + str::escape(shellGlobalParams.port)))); + + // TODO: add in all of the relevant shellGlobalParams to parsedURI + parsedURI.setOptionIfNecessary("compressors"s, shellGlobalParams.networkMessageCompressors); + parsedURI.setOptionIfNecessary("authMechanism"s, shellGlobalParams.authenticationMechanism); + parsedURI.setOptionIfNecessary("authSource"s, shellGlobalParams.authenticationDatabase); + parsedURI.setOptionIfNecessary("gssapiServiceName"s, shellGlobalParams.gssapiServiceName); + parsedURI.setOptionIfNecessary("gssapiHostName"s, shellGlobalParams.gssapiHostName); #ifdef MONGO_CONFIG_SSL - if (!awsIam::saslAwsClientGlobalParams.awsSessionToken.empty()) { - parsedURI.setOptionIfNecessary("authmechanismproperties"s, - std::string("AWS_SESSION_TOKEN:") + - awsIam::saslAwsClientGlobalParams.awsSessionToken); - } + if (!awsIam::saslAwsClientGlobalParams.awsSessionToken.empty()) { + parsedURI.setOptionIfNecessary("authmechanismproperties"s, + std::string("AWS_SESSION_TOKEN:") + + awsIam::saslAwsClientGlobalParams.awsSessionToken); + } #endif - if (const auto authMechanisms = parsedURI.getOption("authMechanism")) { - std::stringstream ss; - ss << "DB.prototype._defaultAuthenticationMechanism = \"" - << str::escape(authMechanisms.get()) << "\";" << std::endl; - mongo::shell_utils::dbConnect += ss.str(); - } + if (const auto authMechanisms = parsedURI.getOption("authMechanism")) { + std::stringstream ss; + ss << "DB.prototype._defaultAuthenticationMechanism = \"" + << str::escape(authMechanisms.get()) << "\";" << std::endl; + mongo::shell_utils::dbConnect += ss.str(); + } - if (const auto gssapiServiveName = parsedURI.getOption("gssapiServiceName")) { - std::stringstream ss; - ss << "DB.prototype._defaultGssapiServiceName = \"" << str::escape(gssapiServiveName.get()) - << "\";" << std::endl; - mongo::shell_utils::dbConnect += ss.str(); - } + if (const auto gssapiServiveName = parsedURI.getOption("gssapiServiceName")) { + std::stringstream ss; + ss << "DB.prototype._defaultGssapiServiceName = \"" + << str::escape(gssapiServiveName.get()) << "\";" << std::endl; + mongo::shell_utils::dbConnect += ss.str(); + } - if (!shellGlobalParams.nodb) { // connect to db - bool usingPassword = !shellGlobalParams.password.empty(); + if (!shellGlobalParams.nodb) { // connect to db + bool usingPassword = !shellGlobalParams.password.empty(); - if (mechanismRequiresPassword(parsedURI) && - (parsedURI.getUser().size() || shellGlobalParams.username.size())) { - usingPassword = true; - } + if (mechanismRequiresPassword(parsedURI) && + (parsedURI.getUser().size() || shellGlobalParams.username.size())) { + usingPassword = true; + } - if (usingPassword && parsedURI.getPassword().empty()) { - if (!shellGlobalParams.password.empty()) { - parsedURI.setPassword(stdx::as_const(shellGlobalParams.password)); - } else { - parsedURI.setPassword(mongo::askPassword()); + if (usingPassword && parsedURI.getPassword().empty()) { + if (!shellGlobalParams.password.empty()) { + parsedURI.setPassword(stdx::as_const(shellGlobalParams.password)); + } else { + parsedURI.setPassword(mongo::askPassword()); + } } - } - if (parsedURI.getUser().empty() && !shellGlobalParams.username.empty()) { - parsedURI.setUser(stdx::as_const(shellGlobalParams.username)); - } + if (parsedURI.getUser().empty() && !shellGlobalParams.username.empty()) { + parsedURI.setUser(stdx::as_const(shellGlobalParams.username)); + } - std::stringstream ss; - if (mongo::serverGlobalParams.quiet.load()) { - ss << "__quiet = true;" << std::endl; - } + std::stringstream ss; + if (mongo::serverGlobalParams.quiet.load()) { + ss << "__quiet = true;" << std::endl; + } - ss << "db = connect( \"" << parsedURI.canonicalizeURIAsString() << "\");" << std::endl; + ss << "db = connect( \"" << parsedURI.canonicalizeURIAsString() << "\");" << std::endl; - if (shellGlobalParams.shouldRetryWrites || parsedURI.getRetryWrites()) { - // If the --retryWrites cmdline argument or retryWrites URI param was specified, then - // replace the global `db` object with a DB object started in a session. The resulting - // Mongo connection checks its _retryWrites property. - ss << "db = db.getMongo().startSession().getDatabase(db.getName());" << std::endl; - } + if (shellGlobalParams.shouldRetryWrites || parsedURI.getRetryWrites()) { + // If the --retryWrites cmdline argument or retryWrites URI param was specified, + // then replace the global `db` object with a DB object started in a session. The + // resulting Mongo connection checks its _retryWrites property. + ss << "db = db.getMongo().startSession().getDatabase(db.getName());" << std::endl; + } - mongo::shell_utils::dbConnect += ss.str(); - } + mongo::shell_utils::dbConnect += ss.str(); + } - mongo::ScriptEngine::setConnectCallback(mongo::shell_utils::onConnect); - mongo::ScriptEngine::setup(); - mongo::getGlobalScriptEngine()->setJSHeapLimitMB(shellGlobalParams.jsHeapLimitMB); - mongo::getGlobalScriptEngine()->setScopeInitCallback(mongo::shell_utils::initScope); - mongo::getGlobalScriptEngine()->enableJIT(!shellGlobalParams.nojit); - mongo::getGlobalScriptEngine()->enableJavaScriptProtection( - shellGlobalParams.javascriptProtection); + mongo::ScriptEngine::setConnectCallback(mongo::shell_utils::onConnect); + mongo::ScriptEngine::setup(); + mongo::getGlobalScriptEngine()->setJSHeapLimitMB(shellGlobalParams.jsHeapLimitMB); + mongo::getGlobalScriptEngine()->setScopeInitCallback(mongo::shell_utils::initScope); + mongo::getGlobalScriptEngine()->enableJIT(!shellGlobalParams.nojit); + mongo::getGlobalScriptEngine()->enableJavaScriptProtection( + shellGlobalParams.javascriptProtection); - auto poolGuard = makeGuard([] { ScriptEngine::dropScopeCache(); }); + auto poolGuard = makeGuard([] { ScriptEngine::dropScopeCache(); }); - std::unique_ptr<mongo::Scope> scope(mongo::getGlobalScriptEngine()->newScope()); - shellMainScope = scope.get(); + std::unique_ptr<mongo::Scope> scope(mongo::getGlobalScriptEngine()->newScope()); + shellMainScope = scope.get(); - if (shellGlobalParams.runShell && !mongo::serverGlobalParams.quiet.load()) - std::cout << "type \"help\" for help" << std::endl; + if (shellGlobalParams.runShell && !mongo::serverGlobalParams.quiet.load()) + std::cout << "type \"help\" for help" << std::endl; - // Load and execute /etc/mongorc.js before starting shell - std::string rcGlobalLocation; + // Load and execute /etc/mongorc.js before starting shell + std::string rcGlobalLocation; #ifndef _WIN32 - rcGlobalLocation = "/etc/mongorc.js"; + rcGlobalLocation = "/etc/mongorc.js"; #else - wchar_t programDataPath[MAX_PATH]; - if (S_OK == SHGetFolderPathW(nullptr, CSIDL_COMMON_APPDATA, nullptr, 0, programDataPath)) { - rcGlobalLocation = str::stream() - << toUtf8String(programDataPath) << "\\MongoDB\\mongorc.js"; - } + wchar_t programDataPath[MAX_PATH]; + if (S_OK == SHGetFolderPathW(nullptr, CSIDL_COMMON_APPDATA, nullptr, 0, programDataPath)) { + rcGlobalLocation = str::stream() + << toUtf8String(programDataPath) << "\\MongoDB\\mongorc.js"; + } #endif - if (!rcGlobalLocation.empty() && ::mongo::shell_utils::fileExists(rcGlobalLocation)) { - if (!scope->execFile(rcGlobalLocation, false, true)) { - std::cout << "The \"" << rcGlobalLocation << "\" file could not be executed" - << std::endl; + if (!rcGlobalLocation.empty() && ::mongo::shell_utils::fileExists(rcGlobalLocation)) { + if (!scope->execFile(rcGlobalLocation, false, true)) { + std::cout << "The \"" << rcGlobalLocation << "\" file could not be executed" + << std::endl; + } } - } - if (!shellGlobalParams.script.empty()) { - mongo::shell_utils::MongoProgramScope s; - if (!scope->exec(shellGlobalParams.script, "(shell eval)", false, true, false)) { - std::cout << "exiting with code " << static_cast<int>(kEvalError) << std::endl; - return kEvalError; + if (!shellGlobalParams.script.empty()) { + mongo::shell_utils::MongoProgramScope s; + if (!scope->exec(shellGlobalParams.script, "(shell eval)", false, true, false)) { + std::cout << "exiting with code " << static_cast<int>(kEvalError) << std::endl; + return kEvalError; + } + scope->exec("shellPrintHelper( __lastres__ );", "(shell2 eval)", true, true, false); } - scope->exec("shellPrintHelper( __lastres__ );", "(shell2 eval)", true, true, false); - } - for (size_t i = 0; i < shellGlobalParams.files.size(); ++i) { - mongo::shell_utils::MongoProgramScope s; + for (size_t i = 0; i < shellGlobalParams.files.size(); ++i) { + mongo::shell_utils::MongoProgramScope s; - if (shellGlobalParams.files.size() > 1) - std::cout << "loading file: " << shellGlobalParams.files[i] << std::endl; + if (shellGlobalParams.files.size() > 1) + std::cout << "loading file: " << shellGlobalParams.files[i] << std::endl; - if (!scope->execFile(shellGlobalParams.files[i], false, true)) { - std::cout << "failed to load: " << shellGlobalParams.files[i] << std::endl; - std::cout << "exiting with code " << static_cast<int>(kInputFileError) << std::endl; - return kInputFileError; - } + if (!scope->execFile(shellGlobalParams.files[i], false, true)) { + std::cout << "failed to load: " << shellGlobalParams.files[i] << std::endl; + std::cout << "exiting with code " << static_cast<int>(kInputFileError) << std::endl; + return kInputFileError; + } - // Check if the process left any running child processes. - std::vector<ProcessId> pids = mongo::shell_utils::getRunningMongoChildProcessIds(); + // Check if the process left any running child processes. + std::vector<ProcessId> pids = mongo::shell_utils::getRunningMongoChildProcessIds(); - if (!pids.empty()) { - std::cout << "terminating the following processes started by " - << shellGlobalParams.files[i] << ": "; - std::copy(pids.begin(), pids.end(), std::ostream_iterator<ProcessId>(std::cout, " ")); - std::cout << std::endl; + if (!pids.empty()) { + std::cout << "terminating the following processes started by " + << shellGlobalParams.files[i] << ": "; + std::copy( + pids.begin(), pids.end(), std::ostream_iterator<ProcessId>(std::cout, " ")); + std::cout << std::endl; - if (mongo::shell_utils::KillMongoProgramInstances() != EXIT_SUCCESS) { - std::cout << "one more more child processes exited with an error during " - << shellGlobalParams.files[i] << std::endl; - std::cout << "exiting with code " << static_cast<int>(kProcessTerminationError) - << std::endl; - return kProcessTerminationError; - } + if (mongo::shell_utils::KillMongoProgramInstances() != EXIT_SUCCESS) { + std::cout << "one more more child processes exited with an error during " + << shellGlobalParams.files[i] << std::endl; + std::cout << "exiting with code " << static_cast<int>(kProcessTerminationError) + << std::endl; + return kProcessTerminationError; + } - bool failIfUnterminatedProcesses = false; - const StringData code = - "function() { return typeof TestData === 'object' && TestData !== null && " - "TestData.hasOwnProperty('failIfUnterminatedProcesses') && " - "TestData.failIfUnterminatedProcesses; }"_sd; - shellMainScope->invokeSafe(code.rawData(), nullptr, nullptr); - failIfUnterminatedProcesses = shellMainScope->getBoolean("__returnValue"); - - if (failIfUnterminatedProcesses) { - std::cout << "exiting with a failure due to unterminated processes, " - "a call to MongoRunner.stopMongod(), ReplSetTest#stopSet(), or " - "ShardingTest#stop() may be missing from the test" - << std::endl; - std::cout << "exiting with code " << static_cast<int>(kUnterminatedProcess) - << std::endl; - return kUnterminatedProcess; + bool failIfUnterminatedProcesses = false; + const StringData code = + "function() { return typeof TestData === 'object' && TestData !== null && " + "TestData.hasOwnProperty('failIfUnterminatedProcesses') && " + "TestData.failIfUnterminatedProcesses; }"_sd; + shellMainScope->invokeSafe(code.rawData(), nullptr, nullptr); + failIfUnterminatedProcesses = shellMainScope->getBoolean("__returnValue"); + + if (failIfUnterminatedProcesses) { + std::cout << "exiting with a failure due to unterminated processes, " + "a call to MongoRunner.stopMongod(), ReplSetTest#stopSet(), or " + "ShardingTest#stop() may be missing from the test" + << std::endl; + std::cout << "exiting with code " << static_cast<int>(kUnterminatedProcess) + << std::endl; + return kUnterminatedProcess; + } } } - } - if (shellGlobalParams.files.size() == 0 && shellGlobalParams.script.empty()) - shellGlobalParams.runShell = true; + if (shellGlobalParams.files.size() == 0 && shellGlobalParams.script.empty()) + shellGlobalParams.runShell = true; - bool lastLineSuccessful = true; - if (shellGlobalParams.runShell) { - mongo::shell_utils::MongoProgramScope s; - // If they specify norc, assume it's not their first time - bool hasMongoRC = shellGlobalParams.norc; - std::string rcLocation; - if (!shellGlobalParams.norc) { + bool lastLineSuccessful = true; + if (shellGlobalParams.runShell) { + mongo::shell_utils::MongoProgramScope s; + // If they specify norc, assume it's not their first time + bool hasMongoRC = shellGlobalParams.norc; + std::string rcLocation; + if (!shellGlobalParams.norc) { #ifndef _WIN32 - if (getenv("HOME") != nullptr) - rcLocation = str::stream() << getenv("HOME") << "/.mongorc.js"; + if (getenv("HOME") != nullptr) + rcLocation = str::stream() << getenv("HOME") << "/.mongorc.js"; #else - if (getenv("HOMEDRIVE") != nullptr && getenv("HOMEPATH") != nullptr) - rcLocation = str::stream() - << toUtf8String(_wgetenv(L"HOMEDRIVE")) << toUtf8String(_wgetenv(L"HOMEPATH")) - << "\\.mongorc.js"; + if (getenv("HOMEDRIVE") != nullptr && getenv("HOMEPATH") != nullptr) + rcLocation = str::stream() + << toUtf8String(_wgetenv(L"HOMEDRIVE")) + << toUtf8String(_wgetenv(L"HOMEPATH")) << "\\.mongorc.js"; #endif - if (!rcLocation.empty() && ::mongo::shell_utils::fileExists(rcLocation)) { - hasMongoRC = true; - if (!scope->execFile(rcLocation, false, true)) { - std::cout - << "The \".mongorc.js\" file located in your home folder could not be " - "executed" - << std::endl; - std::cout << "exiting with code " << static_cast<int>(kMongorcError) - << std::endl; - return kMongorcError; + if (!rcLocation.empty() && ::mongo::shell_utils::fileExists(rcLocation)) { + hasMongoRC = true; + if (!scope->execFile(rcLocation, false, true)) { + std::cout + << "The \".mongorc.js\" file located in your home folder could not be " + "executed" + << std::endl; + std::cout << "exiting with code " << static_cast<int>(kMongorcError) + << std::endl; + return kMongorcError; + } } } - } - if (!hasMongoRC && isatty(fileno(stdin))) { - std::cout - << "Welcome to the MongoDB shell.\n" - "For interactive help, type \"help\".\n" - "For more comprehensive documentation, see\n\thttp://docs.mongodb.org/\n" - "Questions? Try the support group\n\thttp://groups.google.com/group/mongodb-user" - << std::endl; - File f; - f.open(rcLocation.c_str(), false); // Create empty .mongorc.js file - } + if (!hasMongoRC && isatty(fileno(stdin))) { + std::cout + << "Welcome to the MongoDB shell.\n" + "For interactive help, type \"help\".\n" + "For more comprehensive documentation, see\n\thttp://docs.mongodb.org/\n" + "Questions? Try the support " + "group\n\thttp://groups.google.com/group/mongodb-user" + << std::endl; + File f; + f.open(rcLocation.c_str(), false); // Create empty .mongorc.js file + } - if (!shellGlobalParams.nodb && !mongo::serverGlobalParams.quiet.load() && - isatty(fileno(stdin))) { - scope->exec( - "shellHelper( 'show', 'startupWarnings' )", "(shellwarnings)", false, true, false); - - scope->exec( - "shellHelper( 'show', 'freeMonitoring' )", "(freeMonitoring)", false, true, false); - - scope->exec("shellHelper( 'show', 'automationNotices' )", - "(automationnotices)", - false, - true, - false); - - scope->exec("shellHelper( 'show', 'nonGenuineMongoDBCheck' )", - "(nonGenuineMongoDBCheck)", - false, - true, - false); - } + if (!shellGlobalParams.nodb && !mongo::serverGlobalParams.quiet.load() && + isatty(fileno(stdin))) { + scope->exec("shellHelper( 'show', 'startupWarnings' )", + "(shellwarnings)", + false, + true, + false); + + scope->exec("shellHelper( 'show', 'freeMonitoring' )", + "(freeMonitoring)", + false, + true, + false); + + scope->exec("shellHelper( 'show', 'automationNotices' )", + "(automationnotices)", + false, + true, + false); + + scope->exec("shellHelper( 'show', 'nonGenuineMongoDBCheck' )", + "(nonGenuineMongoDBCheck)", + false, + true, + false); + } - shellHistoryInit(); + shellHistoryInit(); - std::string prompt; - int promptType; + std::string prompt; + int promptType; - while (1) { - inMultiLine = false; - gotInterrupted = false; + while (1) { + inMultiLine = false; + gotInterrupted = false; - promptType = scope->type("prompt"); - if (promptType == String) { - prompt = scope->getString("prompt"); - } else if ((promptType == Code) && execPrompt(*scope, "prompt", prompt)) { - } else if (execPrompt(*scope, "defaultPrompt", prompt)) { - } else { - prompt = "> "; - } + promptType = scope->type("prompt"); + if (promptType == String) { + prompt = scope->getString("prompt"); + } else if ((promptType == Code) && execPrompt(*scope, "prompt", prompt)) { + } else if (execPrompt(*scope, "defaultPrompt", prompt)) { + } else { + prompt = "> "; + } - char* line = shellReadline(prompt.c_str()); + char* line = shellReadline(prompt.c_str()); - char* linePtr = line; // can't clobber 'line', we need to free() it later - if (linePtr) { - while (linePtr[0] == ' ') - ++linePtr; - int lineLen = strlen(linePtr); - while (lineLen > 0 && linePtr[lineLen - 1] == ' ') - linePtr[--lineLen] = 0; - } + char* linePtr = line; // can't clobber 'line', we need to free() it later + if (linePtr) { + while (linePtr[0] == ' ') + ++linePtr; + int lineLen = strlen(linePtr); + while (lineLen > 0 && linePtr[lineLen - 1] == ' ') + linePtr[--lineLen] = 0; + } - if (!linePtr || (strlen(linePtr) == 4 && strstr(linePtr, "exit"))) { - if (!mongo::serverGlobalParams.quiet.load()) - std::cout << "bye" << std::endl; - if (line) + if (!linePtr || (strlen(linePtr) == 4 && strstr(linePtr, "exit"))) { + if (!mongo::serverGlobalParams.quiet.load()) + std::cout << "bye" << std::endl; + if (line) + free(line); + break; + } + + std::string code = linePtr; + if (code == "exit" || code == "exit;") { free(line); - break; - } + break; + } - std::string code = linePtr; - if (code == "exit" || code == "exit;") { - free(line); - break; - } + // Support idle session lifetime limits + if (isSessionTimedOut()) { + std::cout << "Idle Connection Timeout: Shell session has expired" << std::endl; + if (line) + free(line); + break; + } - // Support idle session lifetime limits - if (isSessionTimedOut()) { - std::cout << "Idle Connection Timeout: Shell session has expired" << std::endl; - if (line) + if (code == "cls") { free(line); - break; - } - - if (code == "cls") { - free(line); - linenoiseClearScreen(); - continue; - } + linenoiseClearScreen(); + continue; + } - if (code.size() == 0) { - free(line); - continue; - } + if (code.size() == 0) { + free(line); + continue; + } - if (str::startsWith(linePtr, "edit ")) { - shellHistoryAdd(linePtr); + if (str::startsWith(linePtr, "edit ")) { + shellHistoryAdd(linePtr); - const char* s = linePtr + 5; // skip "edit " - while (*s && isspace(*s)) - s++; + const char* s = linePtr + 5; // skip "edit " + while (*s && isspace(*s)) + s++; - edit(s); - free(line); - continue; - } + edit(s); + free(line); + continue; + } - gotInterrupted = false; - code = finishCode(code); - if (gotInterrupted) { - std::cout << std::endl; - free(line); - continue; - } + gotInterrupted = false; + code = finishCode(code); + if (gotInterrupted) { + std::cout << std::endl; + free(line); + continue; + } - if (code.size() == 0) { - free(line); - break; - } + if (code.size() == 0) { + free(line); + break; + } - bool wascmd = false; - { - std::string cmd = linePtr; - std::string::size_type firstSpace; - if ((firstSpace = cmd.find(" ")) != std::string::npos) - cmd = cmd.substr(0, firstSpace); + bool wascmd = false; + { + std::string cmd = linePtr; + std::string::size_type firstSpace; + if ((firstSpace = cmd.find(" ")) != std::string::npos) + cmd = cmd.substr(0, firstSpace); + + if (cmd.find("\"") == std::string::npos) { + try { + lastLineSuccessful = scope->exec( + std::string("__iscmd__ = shellHelper[\"") + cmd + "\"];", + "(shellhelp1)", + false, + true, + true); + if (scope->getBoolean("__iscmd__")) { + lastLineSuccessful = + scope->exec(std::string("shellHelper( \"") + cmd + "\" , \"" + + code.substr(cmd.size()) + "\");", + "(shellhelp2)", + false, + true, + false); + wascmd = true; + } + } catch (std::exception& e) { + std::cout << "error2:" << e.what() << std::endl; + wascmd = true; + lastLineSuccessful = false; + } + } + } - if (cmd.find("\"") == std::string::npos) { + if (!wascmd) { try { lastLineSuccessful = - scope->exec(std::string("__iscmd__ = shellHelper[\"") + cmd + "\"];", - "(shellhelp1)", - false, - true, - true); - if (scope->getBoolean("__iscmd__")) { - lastLineSuccessful = - scope->exec(std::string("shellHelper( \"") + cmd + "\" , \"" + - code.substr(cmd.size()) + "\");", - "(shellhelp2)", - false, - true, - false); - wascmd = true; + scope->exec(code.c_str(), "(shell)", false, true, false); + if (lastLineSuccessful) { + scope->exec( + "shellPrintHelper( __lastres__ );", "(shell2)", true, true, false); } } catch (std::exception& e) { - std::cout << "error2:" << e.what() << std::endl; - wascmd = true; + std::cout << "error:" << e.what() << std::endl; lastLineSuccessful = false; } } - } - if (!wascmd) { - try { - lastLineSuccessful = scope->exec(code.c_str(), "(shell)", false, true, false); - if (lastLineSuccessful) { - scope->exec( - "shellPrintHelper( __lastres__ );", "(shell2)", true, true, false); - } - } catch (std::exception& e) { - std::cout << "error:" << e.what() << std::endl; - lastLineSuccessful = false; - } + shellHistoryAdd(code.c_str()); + free(line); } - shellHistoryAdd(code.c_str()); - free(line); + shellHistoryDone(); } - shellHistoryDone(); - } - - return (lastLineSuccessful ? 0 : 1); -} + return (lastLineSuccessful ? 0 : 1); -#ifdef _WIN32 -int wmain(int argc, wchar_t* argvW[], wchar_t* envpW[]) { - int returnCode; - try { - WindowsCommandLine wcl(argc, argvW, envpW); - returnCode = _main(argc, wcl.argv(), wcl.envp()); - } catch (mongo::DBException& e) { + } catch (DBException& e) { std::cout << "exception: " << e.what() << std::endl; std::cout << "exiting with code " << static_cast<int>(kDBException) << std::endl; - returnCode = kDBException; + return kDBException; } - quickExit(returnCode); } -#else // #ifdef _WIN32 -int main(int argc, char* argv[], char** envp) { - int returnCode; - try { - returnCode = _main(argc, argv, envp); - } catch (mongo::DBException& e) { - std::cout << "exception: " << e.what() << std::endl; - std::cout << "exiting with code " << static_cast<int>(kDBException) << std::endl; - returnCode = kDBException; - } - quickExit(returnCode); -} -#endif // #ifdef _WIN32 + +} // namespace mongo diff --git a/src/mongo/shell/mongo_main.h b/src/mongo/shell/mongo_main.h new file mode 100644 index 00000000000..b16b2ed5203 --- /dev/null +++ b/src/mongo/shell/mongo_main.h @@ -0,0 +1,34 @@ +/** + * Copyright (C) 2020-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +namespace mongo { + +int mongo_main(int argc, char* argv[], char** envp); + +} // namespace mongo diff --git a/src/mongo/shell/shell_utils.cpp b/src/mongo/shell/shell_utils.cpp index 84e4c1ef4fd..ae93862b113 100644 --- a/src/mongo/shell/shell_utils.cpp +++ b/src/mongo/shell/shell_utils.cpp @@ -475,11 +475,8 @@ void installShellUtils(Scope& scope) { scope.injectNative("fileExists", fileExistsJS); scope.injectNative("isInteractive", isInteractive); -#ifndef MONGO_SAFE_SHELL - // can't launch programs installShellUtilsLauncher(scope); installShellUtilsExtended(scope); -#endif } void setEnterpriseShellCallback(EnterpriseShellCallback* callback) { diff --git a/src/mongo/util/SConscript b/src/mongo/util/SConscript index b56fb05fa70..2ec5e638b83 100644 --- a/src/mongo/util/SConscript +++ b/src/mongo/util/SConscript @@ -260,10 +260,11 @@ if env['MONGO_ALLOCATOR'] in ['tcmalloc', 'tcmalloc-experimental']: '$BUILD_DIR/mongo/idl/server_parameter', 'processinfo', ], - PROGDEPS_DEPENDENTS=[ - '$BUILD_DIR/mongo/mongod', - '$BUILD_DIR/mongo/mongos', + LIBDEPS_DEPENDENTS=[ + '$BUILD_DIR/mongo/mongos_initializers', + '$BUILD_DIR/mongo/mongod_initializers', ], + ) env.Library( |