// -*- C++ -*- #include "tao/TAO_Internal.h" #include "tao/TAO_Singleton.h" #include "tao/default_server.h" #include "tao/default_client.h" #include "tao/default_resource.h" #include "tao/IIOP_Factory.h" #include "tao/MCAST_Parser.h" #include "tao/CORBANAME_Parser.h" #include "tao/CORBALOC_Parser.h" #include "tao/FILE_Parser.h" #include "tao/HTTP_Parser.h" #include "tao/DLL_Parser.h" #include "tao/ORB_Core.h" #include "tao/Adapter_Factory.h" #include "tao/Default_Stub_Factory.h" #include "tao/Default_Endpoint_Selector_Factory.h" #include "tao/Default_Thread_Lane_Resources_Manager.h" #include "tao/Default_Collocation_Resolver.h" #include "tao/Codeset_Manager_Factory_Base.h" #include "tao/Codeset_Manager.h" #include "tao/Time_Policy_Manager.h" #include "tao/System_Time_Policy_Strategy.h" #include "tao/HR_Time_Policy_Strategy.h" #include "tao/debug.h" #include "ace/Dynamic_Service.h" #include "ace/Arg_Shifter.h" #include "ace/Argv_Type_Converter.h" #include "ace/ARGV.h" #include "ace/Env_Value_T.h" #include "ace/ACE.h" #include "ace/OS_NS_stdio.h" #include "ace/Static_Object_Lock.h" #include "ace/OS_NS_sys_stat.h" #ifndef TAO_DEFAULT_RESOURCE_FACTORY_ARGS # define TAO_DEFAULT_RESOURCE_FACTORY_ARGS 0 #endif /* !TAO_DEFAULT_RESOURCE_FACTORY_ARGS */ #ifndef TAO_DEFAULT_SERVER_STRATEGY_FACTORY_ARGS # define TAO_DEFAULT_SERVER_STRATEGY_FACTORY_ARGS 0 #endif /* !TAO_DEFAULT_SERVER_STRATEGY_FACTORY_ARGS */ #ifndef TAO_DEFAULT_CLIENT_STRATEGY_FACTORY_ARGS # define TAO_DEFAULT_CLIENT_STRATEGY_FACTORY_ARGS 0 #endif /* !TAO_DEFAULT_RESOURCE_FACTORY_ARGS */ namespace { /** * Parses the supplied command-line arguments to extract any that * apply to the process (globally) * * @brief Modifies the argc to reflect any arguments it has * "consumed" * * When multiple ORBs are being configured, the global options are * only processed for the first ORB loaded. However subsequent ORBs * may be supplied with some of these options, so they need to be * eliminated as though they were processed. For this reason, * this function is called for every ORB, but only the first call * sets apply_values to true * */ int parse_global_args_i (int &argc, ACE_TCHAR **argv, ACE_ARGV &svc_config_argv, bool apply_values); /** * Parses the supplied command-line arguments to extract any that * specify a Service Configurator file (-ORBSvcConf). This is done * separately, because depending on the context, the configuration * file may apply to the process-wide service repository, or to the * orb-specific (private) one. * * @brief Modifies the argc to reflect any arguments it has * "consumed" */ int parse_svcconf_args_i (int &argc, ACE_TCHAR **argv, ACE_ARGV &svc_config_argv); /** * Checks if there is -ORBGestalt option with non-GLOBAL value. * * @brief Modifies the argc to reflect any arguments it has * "consumed" * * If the first ORB has some special configuration and uses non * GLOBAL gestalt then it's expected the this configuration will * not become default for other ORBs created after it. This function * allows to avoid the above situation. */ bool using_global_gestalt_i (int &argc, ACE_TCHAR **argv, bool &skip_service_config_open); /** * Initialize the ACE Service Configurator with the process-global * services (available to any ORB). * * @return @c 0 if successful, @c -1 with @c errno set if failure. * * @note You can provide your program a set of default `svc.conf' * entries by setting @a ignore_default_svc_conf_file to * non-zero and use @c default_svc_conf_entries() before * calling @c open_global_services(). In addition, you can @a * skip_service_config_open altogether, which used to be * important when the ORB is linked in via the * ACE_Service_Config, since the ACE_Service_Config was * non-reentrant. However, the ACE_Service_Config is now * reentrant meaning that it is really no longer necessary to * do so. */ void register_global_services_i (ACE_Service_Gestalt * pcfg); void register_additional_services_i (ACE_Service_Gestalt * pcfg); /** * Parses the supplied command-line arguments to extract any * instance-specific ones. * * @brief Modifies the argc to reflect any arguments it has * "consumed" */ int parse_private_args_i (int &argc, ACE_TCHAR **argv, ACE_ARGV & svc_config_argv, bool & skip_service_config_open, bool & ignore_default_svc_conf_file); /** * Initialize ORB-local (private) ACE Service Configurator * repository. * * @return @c 0 if successful, @c -1 with @c errno set if failure. * */ int open_private_services_i (ACE_Intrusive_Auto_Ptr pcfg, int & argc, ACE_TCHAR **argv, bool skip_service_config_open = false, bool ignore_default_svc_conf_file = false); /** * Number of times open_services() has been called. Incremented by * open_global_services_i(), and decremented by close_services(). * * @note In/decrement operations are atomic. */ long service_open_count = 0; /** * Part of a condition variable, which helps to ensure non-default * ORBs can not proceed with their initialization, until the globaly * required services have been instantiated by the default * ORB. Usually, the first ORB to be created is designated the * default ORB (reference the CORBA spec) */ bool is_ubergestalt_ready = false; char const * resource_factory_args = TAO_DEFAULT_RESOURCE_FACTORY_ARGS; char const * server_strategy_factory_args = TAO_DEFAULT_SERVER_STRATEGY_FACTORY_ARGS; char const * client_strategy_factory_args = TAO_DEFAULT_CLIENT_STRATEGY_FACTORY_ARGS; #if (TAO_NEGOTIATE_CODESETS == 1) bool negotiate_codesets = true; #else bool negotiate_codesets = false; #endif /* TAO_NEGOTIATE_CODESETS */ } // anonymous namespace TAO_BEGIN_VERSIONED_NAMESPACE_DECL #if defined (ACE_HAS_THREADS) /// A little helper class to get around the TAO_Singleton::instance () /// inability to pass default initialization arguments to the /// singleton ctor. class TAO_Ubergestalt_Ready_Condition : public ACE_SYNCH_RECURSIVE_CONDITION { public: static TAO_Ubergestalt_Ready_Condition* instance () { return TAO_Singleton ::instance (); } TAO_Ubergestalt_Ready_Condition () : ACE_SYNCH_RECURSIVE_CONDITION (mutex_) { } private: /// The mutex, associated with the condition. Do not use the ACE /// global mutex, because it causes deadlocks with other threads that /// may be in DLL_Manager::open() ACE_Recursive_Thread_Mutex mutex_; }; #endif // ACE_HAS_THREADS // **************************************************************** /// Note that the argument vector will be corrupted upon return int TAO::ORB::open_global_services (int argc, ACE_TCHAR **argv) { { // Count of the number of (times we did this for all) ORBs. static int orb_init_count = 0; // Using ACE_Static_Object_Lock::instance() precludes ORB_init() // from being called within a static object CTOR. ACE_MT (ACE_GUARD_RETURN (TAO_SYNCH_RECURSIVE_MUTEX, guard, *ACE_Static_Object_Lock::instance (), -1)); // Make sure TAO's singleton manager is initialized. // We need to initialize before TAO_default_environment() is called // since that call instantiates a TAO_TSS_Singleton. if (TAO_Singleton_Manager::instance ()->init () == -1) return -1; // Prevent multiple initializations. if (++orb_init_count > 1) return 0; } // Prevent any other thread from going through ORB initialization before the // uber-gestalt is initialized. ACE_MT (ACE_GUARD_RETURN (TAO_SYNCH_RECURSIVE_MUTEX, guard, TAO_Ubergestalt_Ready_Condition::instance ()->mutex (), -1)); if (TAO_debug_level > 2) { TAOLIB_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO (%P|%t) Initializing the ") ACE_TEXT ("process-wide service context\n"))); } ACE_Service_Gestalt* theone = ACE_Service_Config::global (); ACE_Service_Config_Guard auto_config_guard (theone); // Construct an argument vector specific to the process-wide // (global) Service Configurator instance. // Be certain to copy the program name so that service configurator // has something to skip! ACE_ARGV global_svc_config_argv (true); // only this ctor allows // subsequent use of add()! global_svc_config_argv.add ((argc <= 0 || argv == nullptr) ? ACE_TEXT ("") : argv[0], true); // Will expand the environment variables, if any were used. // Is this a good thing? I guess it provides greater flexibility // for deployment,so let's leave it. Will also quote arguments. ACE_ARGV copyargv (argc, argv, true, true); // Adjust to proper type int tmpargc = copyargv.argc (); // use copied count, not original ACE_Argv_Type_Converter cvtargv (tmpargc, copyargv.argv()); tmpargc = cvtargv.get_argc (); ACE_TCHAR **tmpargv = cvtargv.get_TCHAR_argv (); // Collect global SC parameters. True means "immediately // apply global setting" like debug flag, etc. if (parse_global_args_i (tmpargc, tmpargv, global_svc_config_argv, true) == -1) return -1; bool skip_service_config_open = false; // by default we shouldn't if (using_global_gestalt_i (tmpargc, tmpargv, skip_service_config_open)) { if (parse_svcconf_args_i (tmpargc, tmpargv, global_svc_config_argv) == -1) return -1; } bool ignore_default_svc_conf_file = false; if (parse_private_args_i (tmpargc, tmpargv, global_svc_config_argv, skip_service_config_open, ignore_default_svc_conf_file) == -1) return -1; // register_global_services_i depends on the parsing of at least the // -ORBNegotiateCodesets option, and must be invoked after all the // parsing methods, but still must preceed the opening of other services. register_global_services_i (theone); // Perform the open magic (unless SC::open() has been called already) int global_svc_config_argc = global_svc_config_argv.argc (); int status = open_private_services_i (theone, global_svc_config_argc, global_svc_config_argv.argv (), skip_service_config_open, ignore_default_svc_conf_file); // okay? if (status == -1) { if (errno != ENOENT) { if (TAO_debug_level > 0) { TAOLIB_ERROR ((LM_ERROR, ACE_TEXT ("TAO (%P|%t) - Failed to open process-") ACE_TEXT ("wide service configuration context\n"))); } return -1; } else { if (TAO_debug_level > 4) TAOLIB_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO (%P|%t) - Did not find default ") ACE_TEXT ("svc.conf\n"))); status = 0; } } if (status > 0) { // one or more directives failed, but we don't know which if (TAO_debug_level > 0) { TAOLIB_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO (%P|%t) - process-wide service ") ACE_TEXT ("configuration context had %d failed ") ACE_TEXT ("directives\n"), status)); } } if (TAO_debug_level > 2) TAOLIB_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO (%P|%t) - Completed initializing the ") ACE_TEXT ("process-wide service context\n"))); if (TAO_debug_level > 4) TAOLIB_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO (%P|%t) - Default ORB services initialization begins\n"))); // Load more ORB-related services register_additional_services_i (theone); if (TAO_debug_level > 4) TAOLIB_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO (%P|%t) - Default ORB services initialization completed\n"))); // Notify all other threads that may be waiting, that the global // gestalt has been initialized. is_ubergestalt_ready = true; ACE_MT (if (TAO_Ubergestalt_Ready_Condition::instance ()-> broadcast () == -1) return -1); return 0; } int TAO::ORB::open_services (ACE_Intrusive_Auto_Ptr pcfg, int &argc, ACE_TCHAR **argv) { { ACE_MT (ACE_GUARD_RETURN (TAO_SYNCH_RECURSIVE_MUTEX, guard, TAO_Ubergestalt_Ready_Condition::instance ()->mutex (), -1)); // Wait in line, while the default ORB (which isn't us) completes // initialization of the globaly required service objects if (service_open_count == 1) { if (TAO_debug_level > 4) TAOLIB_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO (%P|%t) - Waiting for the default ") ACE_TEXT ("ORB to complete the global ") ACE_TEXT ("initialization\n"))); ACE_MT (while (!is_ubergestalt_ready) TAO_Ubergestalt_Ready_Condition::instance ()->wait ()); if (TAO_debug_level > 4) TAOLIB_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO (%P|%t) - The default ") ACE_TEXT ("ORB must have completed the global ") ACE_TEXT ("initialization...\n"))); } else { if (TAO_debug_level > 4) TAOLIB_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO (%P|%t) - We are%Cthe default ") ACE_TEXT ("%C ORB ...\n"), (service_open_count == 0) ? " " : " not ", TAO_VERSION)); } ++service_open_count; } // Construct an argument vector specific to the Service Configurator. // Be certain to copy the program name so that service configurator // has something to skip! ACE_ARGV svc_config_argv (true); // only this ctor allows subsequent // use of add()! svc_config_argv.add ((argc <= 0 || argv == nullptr) ? ACE_TEXT ("") : argv[0], true); // Should we skip the ACE_Service_Config::open() method?, // e.g., because of -ORBSkipServiceConfigOpen bool skip_service_config_open = false; bool ignore_default_svc_conf_file = false; // Extract any ORB options from the argument vector. if (parse_private_args_i (argc, argv, svc_config_argv, skip_service_config_open, ignore_default_svc_conf_file) == -1) { return -1; } // Construct an argument vector specific to the process-wide // (global) Service Configurator instance. ACE_ARGV global_svc_config_argv; // Parse any globally applicable arguments, but do not make them effective. // We are effectively purging the command line from them without affecting // the global state - after all, it may be a private (local) configuration // context. int status = parse_global_args_i(argc, argv, global_svc_config_argv, false); if (status == -1 && TAO_debug_level > 0) TAOLIB_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO (%P|%t) - Skipping the process-wide ") ACE_TEXT ("service configuration, service_open_count ") ACE_TEXT ("= %d, status = %d\n"), service_open_count, status)); if (TAO_debug_level > 2) TAOLIB_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO (%P|%t) - Initializing the ") ACE_TEXT ("orb-specific services\n"))); if (parse_svcconf_args_i (argc, argv, svc_config_argv) == -1) return -1; // Not a big deal to call open_private_services_i() again (if it was the global one). The SG::open() would not run if it has already been executed. // only open the private context if it is not also the global context if (pcfg != ACE_Service_Config::global()) { int svc_config_argc = svc_config_argv.argc (); status = open_private_services_i (pcfg, svc_config_argc, svc_config_argv.argv (), skip_service_config_open, ignore_default_svc_conf_file); } if (status == -1) { if (errno != ENOENT) { if (TAO_debug_level > 0) TAOLIB_ERROR ((LM_ERROR, ACE_TEXT ("TAO (%P|%t) - Failed to open ORB-specific ") ACE_TEXT ("service configuration\n"))); return -1; } else { if (TAO_debug_level > 4) TAOLIB_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO (%P|%t) - Did not find default ") ACE_TEXT ("svc.conf\n"))); status = 0; } } if (status > 0) { // one or more directives failed, but we don't know which if (TAO_debug_level > 0) { TAOLIB_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO (%P|%t) - ORB-specific service ") ACE_TEXT ("configuration context had %d failed ") ACE_TEXT ("directives\n"), status)); } } return status; } int TAO::ORB::close_services (ACE_Intrusive_Auto_Ptr pcfg) { ACE_MT (ACE_GUARD_RETURN (TAO_SYNCH_RECURSIVE_MUTEX, guard, *ACE_Static_Object_Lock::instance (), -1)); --service_open_count; int result = 0; if (pcfg != ACE_Service_Config::global()) { result = pcfg->close (); } return result; } void TAO::ORB::default_svc_conf_entries (char const * rf_args, char const * ssf_args, char const * csf_args) { if (rf_args) { resource_factory_args = rf_args; } if (ssf_args) { server_strategy_factory_args = ssf_args; } if (csf_args) { client_strategy_factory_args = csf_args; } } TAO_END_VERSIONED_NAMESPACE_DECL // ----------------------------------------------------- namespace { /// Open services, belonging to the gestalt instance. int open_private_services_i (ACE_Intrusive_Auto_Ptr pcfg, int & argc, ACE_TCHAR ** argv, bool skip_service_config_open, bool ignore_default_svc_conf_file) { if (skip_service_config_open) { return 0; } #if defined (TAO_PLATFORM_SVC_CONF_FILE_NOTSUP) ignore_default_svc_conf_file = true; #endif /* TAO_PLATFORM_SVC_CONF_FILE_NOTSUP */ // Copy command line parameter to allow conversion ACE_Argv_Type_Converter command_line (argc, argv); return pcfg->open (command_line.get_argc (), command_line.get_TCHAR_argv (), nullptr, false, // Don't ignore static services. ignore_default_svc_conf_file); } /// @brief registers all process-wide (global) services, available /// to all ORBs void register_global_services_i (ACE_Service_Gestalt * pcfg) { // This has to be done before intializing the resource // factory. Codesets is a special library since its configuration // is optional and it may be linked statically. if (negotiate_codesets) { TAO_Codeset_Manager_Factory_Base *factory = ACE_Dynamic_Service::instance ( "TAO_Codeset"); if (factory == nullptr || factory->is_default ()) { #if !defined (TAO_AS_STATIC_LIBS) && !(defined (ACE_VXWORKS) && !defined (__RTP__)) // only for dynamic libs, check to see if default factory // and if so, remove it ACE_Service_Config::process_directive ( ACE_REMOVE_SERVICE_DIRECTIVE ("TAO_Codeset")); ACE_Service_Config::process_directive ( ACE_DYNAMIC_VERSIONED_SERVICE_DIRECTIVE ( "TAO_Codeset", "TAO_Codeset", TAO_VERSION, "_make_TAO_Codeset_Manager_Factory", "")); factory = ACE_Dynamic_Service< TAO_Codeset_Manager_Factory_Base >::instance ("TAO_Codeset"); #endif /* !TAO_AS_STATIC_LIBS && !(ACE_VXWORKS && !__RTP__) */ } if (factory == nullptr) { if (TAO_debug_level > 0) { TAOLIB_ERROR ((LM_ERROR, ACE_TEXT ("TAO (%P|%t) - ORB_Core: ") ACE_TEXT ("Unable to initialize ") ACE_TEXT ("Codeset Manager\n"))); } } } pcfg->process_directive ( ace_svc_desc_TAO_Default_Resource_Factory); pcfg->process_directive ( ace_svc_desc_TAO_Default_Client_Strategy_Factory); pcfg->process_directive ( ace_svc_desc_TAO_Default_Server_Strategy_Factory); // Configure the IIOP factory. You do *NOT* need modify this // code to add your own protocol, instead simply add the // following to your svc.conf file: // // dynamic PN_Factory Service_Object * LIB:_make_PN_Protocol_Factory() "" // static Resource_Factory "-ORBProtocolFactory PN_Factory" // // where PN is the name of your protocol and LIB is the base // name of the shared library that implements the protocol. #if defined (TAO_HAS_IIOP) && (TAO_HAS_IIOP != 0) pcfg->process_directive (ace_svc_desc_TAO_IIOP_Protocol_Factory); #endif /* TAO_HAS_IIOP && TAO_HAS_IIOP != 0 */ // add descriptor to list of static objects. #if (TAO_HAS_MCAST_PARSER == 1) pcfg->process_directive (ace_svc_desc_TAO_MCAST_Parser); #endif /* TAO_HAS_MCAST_PARSER == 1 */ #if (TAO_HAS_CORBANAME_PARSER == 1) pcfg->process_directive (ace_svc_desc_TAO_CORBANAME_Parser); #endif /* TAO_HAS_CORBANAME_PARSER == 1 */ #if (TAO_HAS_CORBALOC_PARSER == 1) pcfg->process_directive (ace_svc_desc_TAO_CORBALOC_Parser); #endif /* TAO_HAS_CORBALOC_PARSER == 1 */ #if (TAO_HAS_FILE_PARSER == 1) pcfg->process_directive (ace_svc_desc_TAO_FILE_Parser); #endif /* TAO_HAS_FILE_PARSER == 1 */ #if (TAO_HAS_DDL_PARSER == 1) pcfg->process_directive (ace_svc_desc_TAO_DLL_Parser); #endif /* TAO_HAS_DDL_PARSER == 1 */ #if (TAO_HAS_HTTP_PARSER == 1) pcfg->process_directive (ace_svc_desc_TAO_HTTP_Parser); #endif /* TAO_HAS_HTTP_PARSER */ pcfg->process_directive (ace_svc_desc_TAO_Default_Stub_Factory); pcfg->process_directive ( ace_svc_desc_TAO_Default_Endpoint_Selector_Factory); pcfg->process_directive ( ace_svc_desc_TAO_Default_Thread_Lane_Resources_Manager_Factory); pcfg->process_directive (ace_svc_desc_TAO_Default_Collocation_Resolver); #if (TAO_HAS_TIME_POLICY == 1) pcfg->process_directive (ace_svc_desc_TAO_Time_Policy_Manager); pcfg->process_directive (ace_svc_desc_TAO_System_Time_Policy_Strategy); pcfg->process_directive (ace_svc_desc_TAO_HR_Time_Policy_Strategy); #endif } /* register_global_services_i */ void register_additional_services_i (ACE_Service_Gestalt * pcfg) { // @@ What the heck do these things do and do we need to avoid // calling them if we're not invoking the svc.conf file? // @@ They are needed for platforms that have no file system, // like VxWorks. if (resource_factory_args != nullptr) { pcfg->process_directive( ACE_TEXT_CHAR_TO_TCHAR (resource_factory_args)); } if (client_strategy_factory_args != nullptr) { pcfg->process_directive (ACE_TEXT_CHAR_TO_TCHAR (client_strategy_factory_args)); } if (server_strategy_factory_args != nullptr) { pcfg->process_directive (ACE_TEXT_CHAR_TO_TCHAR (server_strategy_factory_args)); } ACE_Service_Object * const pi_server_loader = ACE_Dynamic_Service::instance ( pcfg, "PI_Server_Loader"); if (pi_server_loader != nullptr) { pi_server_loader->init (0, nullptr); } ACE_Service_Object * const bidir_loader = ACE_Dynamic_Service::instance ( pcfg, "BiDirGIOP_Loader"); if (bidir_loader != nullptr) { bidir_loader->init (0, nullptr); } #if defined (TAO_HAS_ZIOP) && TAO_HAS_ZIOP == 1 ACE_Service_Object * const ziop_loader = ACE_Dynamic_Service::instance ( pcfg, "ZIOP_Loader"); if (ziop_loader != nullptr) { ziop_loader->init (0, nullptr); } #endif ACE_Service_Object * const messaging_loader = ACE_Dynamic_Service::instance ( pcfg, "Messaging_Loader"); if (messaging_loader != nullptr) { messaging_loader->init (0, nullptr); } // Handle RTCORBA library special case. Since RTCORBA needs // its init method call to register several hooks, call it // here if it hasn't already been called. ACE_Service_Object * const rt_loader = ACE_Dynamic_Service::instance ( pcfg, "RT_ORB_Loader"); if (rt_loader != nullptr) { rt_loader->init (0, nullptr); } ACE_Service_Object * const rtscheduler_loader = ACE_Dynamic_Service::instance ( pcfg, "RTScheduler_Loader"); if (rtscheduler_loader != nullptr) { rtscheduler_loader->init (0, nullptr); } ACE_Service_Object * const csd_framework_loader = ACE_Dynamic_Service::instance ( pcfg, "CSD_Framework_Loader"); if (csd_framework_loader != nullptr) { csd_framework_loader->init (0, nullptr); } ACE_Service_Object * const endpoint_policy_loader = ACE_Dynamic_Service::instance ( pcfg, "EndpointPolicy_Initializer"); if (endpoint_policy_loader != nullptr) { endpoint_policy_loader->init (0, nullptr); } ACE_Service_Object * const diffserv_policy_loader = ACE_Dynamic_Service::instance ( pcfg, "DiffservPolicy_Initializer"); if (diffserv_policy_loader != nullptr) { diffserv_policy_loader->init (0, nullptr); } } /* register_additional_services_i */ int parse_svcconf_args_i (int &argc, ACE_TCHAR **argv, ACE_ARGV &svc_config_argv) { // Extract the Service Configurator ORB options from the argument // vector. ACE_Arg_Shifter arg_shifter (argc, argv); while (arg_shifter.is_anything_left ()) { // Can't interpret this argument. Move on to the next argument. if (arg_shifter.cur_arg_strncasecmp (ACE_TEXT ("-ORBSvcConf")) == 0) { const ACE_TCHAR *current_arg = arg_shifter.get_the_parameter (ACE_TEXT ("-ORBSvcConf")); arg_shifter.consume_arg (); // Proceeds only if the configuration file exists. FILE * const conf_file = ACE_OS::fopen (current_arg, ACE_TEXT ("r")); if (nullptr == conf_file) { // Assigning EINVAL to errno to make an exception // thrown. calling code does not throw an exception if // the errno is set to ENOENT for some reason. errno = EINVAL; TAOLIB_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("TAO (%P|%t) - Error, unable to open file <%s>") ACE_TEXT (", referenced by -ORBSvcConf option\n"), current_arg), -1); } else { ACE_OS::fclose (conf_file); } svc_config_argv.add (ACE_TEXT ("-f")); svc_config_argv.add (current_arg, true); } else if (arg_shifter.cur_arg_strncasecmp (ACE_TEXT ("-ORBSvcConfDirective")) == 0) { const ACE_TCHAR *current_arg = arg_shifter.get_the_parameter (ACE_TEXT ("-ORBSvcConfDirective")); // This is used to pass arguments to the Service // Configurator using the "command line" to provide // configuration information rather than using a svc.conf // file. Pass the "-S" to the service configurator. svc_config_argv.add (ACE_TEXT ("-S")); svc_config_argv.add (current_arg, true); // quote args! arg_shifter.consume_arg (); } else { // Any arguments that don't match are ignored so that the // caller can still use them. arg_shifter.ignore_arg (); } } return 0; } /* parse_svcconf_args_i */ int parse_private_args_i (int &argc, ACE_TCHAR **argv, ACE_ARGV &svc_config_argv, bool & skip_service_config_open, bool & ignore_default_svc_conf_file) { // Extract the Service Configurator ORB options from the argument // vector. ACE_Arg_Shifter arg_shifter (argc, argv); while (arg_shifter.is_anything_left ()) { const ACE_TCHAR *current_arg = nullptr; if (0 == arg_shifter.cur_arg_strncasecmp (ACE_TEXT ("-ORBSkipServiceConfigOpen"))) { skip_service_config_open = true; arg_shifter.consume_arg (); } if (0 == arg_shifter.cur_arg_strncasecmp (ACE_TEXT ("-ORBIgnoreDefaultSvcConfFile"))) { ignore_default_svc_conf_file = true; arg_shifter.consume_arg (); } else if (nullptr != (current_arg = arg_shifter.get_the_parameter (ACE_TEXT ("-ORBServiceConfigLoggerKey")))) { svc_config_argv.add (ACE_TEXT ("-k")); svc_config_argv.add (current_arg, true); // quote args! arg_shifter.consume_arg (); } else if (0 == arg_shifter.cur_arg_strncasecmp (ACE_TEXT ("-ORBNegotiateCodesets"))) { // Negotiate codesets must be evaluated prior to calling // register_global_services_i. // Don't consume, the ORB_Core::init will use it again. arg_shifter.ignore_arg(); if (nullptr != (current_arg = arg_shifter.get_current())) negotiate_codesets = (ACE_OS::atoi (current_arg)); arg_shifter.ignore_arg(); } else if (nullptr != (current_arg = arg_shifter.get_the_parameter (ACE_TEXT ("-ORBDebugLevel")))) { // Allowing different ORBs to change the global debug // level may be unexpected, but since this TAO_debug_level = ACE_OS::atoi (current_arg); arg_shifter.consume_arg (); } else { // Can't interpret this argument. Move on to the next // argument. Any arguments that don't match are ignored // so that the caller can still use them. arg_shifter.ignore_arg (); } } return 0; } /* parse_private_args_i */ int parse_global_args_i (int &argc, ACE_TCHAR **argv, ACE_ARGV &svc_config_argv, bool apply_values) { // NOTE: When adding new global arguments, ensure they are only // applied when apply_values is true, but that they are always // consumed, if they need to be consumed. #if defined (TAO_DEBUG) // Make it a little easier to debug programs using this code. if (apply_values) { TAO_debug_level = ACE_Env_Value ("TAO_ORB_DEBUG", 0); if (TAO_debug_level != 0) { if (TAO_debug_level <= 0) { TAO_debug_level = 1; } TAOLIB_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO_debug_level == %d\n"), TAO_debug_level)); } } #endif /* TAO_DEBUG */ // Extract the Service Configurator ORB options from the argument // vector. ACE_Arg_Shifter arg_shifter (argc, argv); while (arg_shifter.is_anything_left ()) { if (0 == arg_shifter.cur_arg_strncasecmp (ACE_TEXT ("-ORBDebug"))) { if (apply_values) { // Later, replace all of these // warning this turns on a daemon. ACE::debug (1); } arg_shifter.consume_arg (); } else if (0 == arg_shifter.cur_arg_strncasecmp (ACE_TEXT ("-ORBDaemon"))) { // Be a daemon. if (apply_values) { svc_config_argv.add (ACE_TEXT("-b")); } arg_shifter.consume_arg (); } // Can't interpret this argument. // Move on to the next argument. else { // Any arguments that don't match are ignored so // that the caller can still use them. arg_shifter.ignore_arg (); } } return 0; } /* parse_global_args_i */ bool using_global_gestalt_i (int &argc, ACE_TCHAR **argv, bool &skip_service_config_open) { bool with_global_gestalt = true; ACE_Arg_Shifter arg_shifter (argc, argv); while (arg_shifter.is_anything_left ()) { if (0 == arg_shifter.cur_arg_strncasecmp (ACE_TEXT ("-ORBGestalt"))) { // Skip -ORBGestalt. This option is necessary in later stages. arg_shifter.ignore_arg (); // This should set current_arg to the value of ORBGestalt option. const ACE_TCHAR *current_arg = arg_shifter.get_current (); if (nullptr != current_arg && ACE_OS::strcasecmp (current_arg, ACE_TEXT("GLOBAL")) != 0) { with_global_gestalt = false; ACE_stat exists; if (ACE_OS::stat (ACE_DEFAULT_SVC_CONF, &exists) == 0) { // In case svc.conf exists and we are asked for a local // gestalt then no matter whether -ORBSvcConf or // -ORBSvcConfDirective are provided or not we ignore them // while setting up a global gestalt. They will be // processed later in a local gestalt. skip_service_config_open = true; } } // Skip anything that goes after -ORBGestalt. arg_shifter.ignore_arg (); } // Can't interpret this argument. // Move on to the next argument. else { // Any arguments that don't match are ignored so // that the caller can still use them. arg_shifter.ignore_arg (); } } return with_global_gestalt; } /* using_global_gestalt_i */ } // anonymous namespace.