< prev index next >

src/share/vm/runtime/arguments.cpp

Print this page

        

*** 109,119 **** SystemProperty *Arguments::_java_library_path = NULL; SystemProperty *Arguments::_java_home = NULL; SystemProperty *Arguments::_java_class_path = NULL; SystemProperty *Arguments::_jdk_boot_class_path_append = NULL; ! GrowableArray<ModuleXPatchPath*> *Arguments::_xpatchprefix = NULL; PathString *Arguments::_system_boot_class_path = NULL; char* Arguments::_ext_dirs = NULL; // Check if head of 'option' matches 'name', and sets 'tail' to the remaining --- 109,119 ---- SystemProperty *Arguments::_java_library_path = NULL; SystemProperty *Arguments::_java_home = NULL; SystemProperty *Arguments::_java_class_path = NULL; SystemProperty *Arguments::_jdk_boot_class_path_append = NULL; ! GrowableArray<ModulePatchPath*> *Arguments::_patch_mod_prefix = NULL; PathString *Arguments::_system_boot_class_path = NULL; char* Arguments::_ext_dirs = NULL; // Check if head of 'option' matches 'name', and sets 'tail' to the remaining
*** 138,147 **** --- 138,224 ---- } else { return false; } } + #define MODULE_PROPERTY_PREFIX "jdk.module" + #define MODULE_PROPERTY_PREFIX_LEN 10 + #define ADDEXPORTS "addexports" + #define ADDEXPORTS_LEN 10 + #define ADDREADS "addreads" + #define ADDREADS_LEN 8 + #define PATCH "patch" + #define PATCH_LEN 5 + #define ADDMODS "addmods" + #define ADDMODS_LEN 7 + #define LIMITMODS "limitmods" + #define LIMITMODS_LEN 9 + #define PATH "path" + #define PATH_LEN 4 + #define UPGRADE_PATH "upgrade.path" + #define UPGRADE_PATH_LEN 12 + + // Return TRUE if option matches property.<digits> or matches property.<digits>=. + static bool is_matching_numbered_property(const char* option, const char* property, size_t len) { + if (strncmp(option, property, len) == 0) { + // Check for digits. + const char* sptr = option + len; + if (isdigit(*sptr)) { // Make sure next char is a digit. + while (isdigit(*sptr)) { + sptr++; + if (*sptr == '=' || *sptr == '\0') { + return true; + } + } + } + } + return false; + } + + // Return TRUE if option matches property or matches property=. + static bool is_matching_property(const char* option, const char* property, size_t len) { + return (strncmp(option, property, len) == 0) && (option[len] == '=' || option[len] == '\0'); + } + + // Return true if option_end is the name of a module-related java property + // with "-Djdk.module." removed. + static bool is_internal_module_property_end(const char* option_end) { + // For the repeating properties such as (-Djdk.module.patch.0 + // -Djdk.module.patch.1, etc) return true for "<property_name>.<digit>[=]". + if (is_matching_numbered_property(option_end, ADDEXPORTS ".", ADDEXPORTS_LEN + 1) || + is_matching_numbered_property(option_end, ADDREADS ".", ADDREADS_LEN + 1) || + is_matching_numbered_property(option_end, PATCH ".", PATCH_LEN + 1)) { + return true; + } + return (is_matching_property(option_end, ADDMODS, ADDMODS_LEN) || + is_matching_property(option_end, LIMITMODS, LIMITMODS_LEN)); + } + + // Return true if the option is one of the module-related java properties + // that can only be set using the proper module-related option. + static bool is_module_property(const JavaVMOption *option) { + if (strncmp(option->optionString, "-D" MODULE_PROPERTY_PREFIX ".", MODULE_PROPERTY_PREFIX_LEN + 3) == 0) { + const char* option_end = option->optionString + MODULE_PROPERTY_PREFIX_LEN + 3; + return (is_internal_module_property_end(option_end) || + is_matching_property(option_end, PATH, PATH_LEN) || + is_matching_property(option_end, UPGRADE_PATH, UPGRADE_PATH_LEN)); + } + return false; + } + + // Return true if the option is one of the module-related java properties + // that can only be set using the proper module-related option and cannot + // be read by jvmti. + // It's expected that the caller removed the leading "-D" from 'option'. + bool Arguments::is_internal_module_property(const char* option) { + assert((strncmp(option, "-D", 2) != 0), "Unexpected leading -D"); + if (strncmp(option, MODULE_PROPERTY_PREFIX ".", MODULE_PROPERTY_PREFIX_LEN + 1) == 0) { + return is_internal_module_property_end(option + MODULE_PROPERTY_PREFIX_LEN + 1); + } + return false; + } + // Return true if any of the strings in null-terminated array 'names' matches. // If tail_allowed is true, then the tail must begin with a colon; otherwise, // the option must match exactly. static bool match_option(const JavaVMOption* option, const char** names, const char** tail, bool tail_allowed) {
*** 1197,1207 **** const char* Arguments::get_property(const char* key) { return PropertyList_get_value(system_properties(), key); } ! bool Arguments::add_property(const char* prop) { const char* eq = strchr(prop, '='); const char* key; const char* value = ""; if (eq == NULL) { --- 1274,1284 ---- const char* Arguments::get_property(const char* key) { return PropertyList_get_value(system_properties(), key); } ! bool Arguments::add_property(const char* prop, PropertyWriteable writeable, PropertyInternal internal) { const char* eq = strchr(prop, '='); const char* key; const char* value = ""; if (eq == NULL) {
*** 1227,1237 **** strcmp(key, "sun.java.launcher.pid") == 0) { // sun.java.launcher.is_altjvm and sun.java.launcher.pid property are // private and are processed in process_sun_java_launcher_properties(); // the sun.java.launcher property is passed on to the java application } else if (strcmp(key, "sun.boot.library.path") == 0) { ! PropertyList_unique_add(&_system_properties, key, value, true); } else { if (strcmp(key, "sun.java.command") == 0) { char *old_java_command = _java_command; _java_command = os::strdup_check_oom(value, mtArguments); if (old_java_command != NULL) { --- 1304,1316 ---- strcmp(key, "sun.java.launcher.pid") == 0) { // sun.java.launcher.is_altjvm and sun.java.launcher.pid property are // private and are processed in process_sun_java_launcher_properties(); // the sun.java.launcher property is passed on to the java application } else if (strcmp(key, "sun.boot.library.path") == 0) { ! // append is true, writable is true, internal is false ! PropertyList_unique_add(&_system_properties, key, value, AppendProperty, ! WriteableProperty, ExternalProperty); } else { if (strcmp(key, "sun.java.command") == 0) { char *old_java_command = _java_command; _java_command = os::strdup_check_oom(value, mtArguments); if (old_java_command != NULL) {
*** 1247,1257 **** os::free((void *)old_java_vendor_url_bug); } } // Create new property and add at the end of the list ! PropertyList_unique_add(&_system_properties, key, value); } if (key != prop) { // SystemProperty copy passed value, thus free previously allocated // memory --- 1326,1336 ---- os::free((void *)old_java_vendor_url_bug); } } // Create new property and add at the end of the list ! PropertyList_unique_add(&_system_properties, key, value, AddProperty, writeable, internal); } if (key != prop) { // SystemProperty copy passed value, thus free previously allocated // memory
*** 1259,1271 **** } return true; } ! // sets or adds a module name to the jdk.launcher.addmods property bool Arguments::append_to_addmods_property(const char* module_name) { ! const char* key = "jdk.launcher.addmods"; const char* old_value = Arguments::get_property(key); size_t buf_len = strlen(key) + strlen(module_name) + 2; if (old_value != NULL) { buf_len += strlen(old_value) + 1; } --- 1338,1350 ---- } return true; } ! // sets or adds a module name to the jdk.module.addmods property bool Arguments::append_to_addmods_property(const char* module_name) { ! const char* key = "jdk.module.addmods"; const char* old_value = Arguments::get_property(key); size_t buf_len = strlen(key) + strlen(module_name) + 2; if (old_value != NULL) { buf_len += strlen(old_value) + 1; }
*** 1276,1303 **** if (old_value == NULL) { jio_snprintf(new_value, buf_len, "%s=%s", key, module_name); } else { jio_snprintf(new_value, buf_len, "%s=%s,%s", key, old_value, module_name); } ! bool added = add_property(new_value); FreeHeap(new_value); return added; } #if INCLUDE_CDS void Arguments::check_unsupported_dumping_properties() { assert(DumpSharedSpaces, "this function is only used with -Xshare:dump"); const char* unsupported_properties[5] = { "jdk.module.main", "jdk.module.path", ! "jdk.upgrade.module.path", ! "jdk.launcher.addmods", ! "jdk.launcher.limitmods" }; const char* unsupported_options[5] = { "-m", ! "-modulepath", ! "-upgrademodulepath", ! "-addmods", ! "-limitmods" }; SystemProperty* sp = system_properties(); while (sp != NULL) { for (int i = 0; i < 5; i++) { if (strcmp(sp->key(), unsupported_properties[i]) == 0) { vm_exit_during_initialization( --- 1355,1382 ---- if (old_value == NULL) { jio_snprintf(new_value, buf_len, "%s=%s", key, module_name); } else { jio_snprintf(new_value, buf_len, "%s=%s,%s", key, old_value, module_name); } ! bool added = add_property(new_value, UnwriteableProperty, InternalProperty); FreeHeap(new_value); return added; } #if INCLUDE_CDS void Arguments::check_unsupported_dumping_properties() { assert(DumpSharedSpaces, "this function is only used with -Xshare:dump"); const char* unsupported_properties[5] = { "jdk.module.main", "jdk.module.path", ! "jdk.module.upgrade.path", ! "jdk.module.addmods", ! "jdk.module.limitmods" }; const char* unsupported_options[5] = { "-m", ! "--module-path", ! "--upgrade-module-path", ! "--add-modules", ! "--limit-modules" }; SystemProperty* sp = system_properties(); while (sp != NULL) { for (int i = 0; i < 5; i++) { if (strcmp(sp->key(), unsupported_properties[i]) == 0) { vm_exit_during_initialization(
*** 1320,1330 **** _mode = mode; // Ensure Agent_OnLoad has the correct initial values. // This may not be the final mode; mode may change later in onload phase. PropertyList_unique_add(&_system_properties, "java.vm.info", ! VM_Version::vm_info_string(), false); UseInterpreter = true; UseCompiler = true; UseLoopCounter = true; --- 1399,1409 ---- _mode = mode; // Ensure Agent_OnLoad has the correct initial values. // This may not be the final mode; mode may change later in onload phase. PropertyList_unique_add(&_system_properties, "java.vm.info", ! VM_Version::vm_info_string(), AddProperty, UnwriteableProperty, ExternalProperty); UseInterpreter = true; UseCompiler = true; UseLoopCounter = true;
*** 2518,2527 **** --- 2597,2641 ---- } } return false; } + unsigned int addreads_count = 0; + unsigned int addexports_count = 0; + unsigned int patch_mod_count = 0; + const char* add_modules_value = NULL; + + bool Arguments::create_property(const char* prop_name, const char* prop_value, PropertyInternal internal) { + size_t prop_len = strlen(prop_name) + strlen(prop_value) + 2; + char* property = AllocateHeap(prop_len, mtArguments); + int ret = jio_snprintf(property, prop_len, "%s=%s", prop_name, prop_value); + if (ret < 0 || ret >= (int)prop_len) { + FreeHeap(property); + return false; + } + bool added = add_property(property, UnwriteableProperty, internal); + FreeHeap(property); + return added; + } + + bool Arguments::create_numbered_property(const char* prop_base_name, const char* prop_value, unsigned int count) { + // Make sure count is < 1,000. Otherwise, memory allocation will be too small. + if (count < 1000) { + size_t prop_len = strlen(prop_base_name) + strlen(prop_value) + 5; + char* property = AllocateHeap(prop_len, mtArguments); + int ret = jio_snprintf(property, prop_len, "%s.%d=%s", prop_base_name, count, prop_value); + if (ret < 0 || ret >= (int)prop_len) { + FreeHeap(property); + return false; + } + bool added = add_property(property, UnwriteableProperty, InternalProperty); + FreeHeap(property); + return added; + } + return false; + } + Arguments::ArgsRange Arguments::parse_memory_size(const char* s, julong* long_arg, julong min_size) { if (!atojulong(s, long_arg)) return arg_unreadable; return check_memory_size(*long_arg, min_size);
*** 2530,2540 **** // Parse JavaVMInitArgs structure jint Arguments::parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args, const JavaVMInitArgs *java_options_args, const JavaVMInitArgs *cmd_line_args) { ! bool xpatch_javabase = false; // Save default settings for some mode flags Arguments::_AlwaysCompileLoopMethods = AlwaysCompileLoopMethods; Arguments::_UseOnStackReplacement = UseOnStackReplacement; Arguments::_ClipInlining = ClipInlining; --- 2644,2654 ---- // Parse JavaVMInitArgs structure jint Arguments::parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args, const JavaVMInitArgs *java_options_args, const JavaVMInitArgs *cmd_line_args) { ! bool patch_mod_javabase = false; // Save default settings for some mode flags Arguments::_AlwaysCompileLoopMethods = AlwaysCompileLoopMethods; Arguments::_UseOnStackReplacement = UseOnStackReplacement; Arguments::_ClipInlining = ClipInlining;
*** 2547,2570 **** // Setup flags for mixed which is the default set_mode_flags(_mixed); // Parse args structure generated from JAVA_TOOL_OPTIONS environment // variable (if present). ! jint result = parse_each_vm_init_arg(java_tool_options_args, &xpatch_javabase, Flag::ENVIRON_VAR); if (result != JNI_OK) { return result; } // Parse args structure generated from the command line flags. ! result = parse_each_vm_init_arg(cmd_line_args, &xpatch_javabase, Flag::COMMAND_LINE); if (result != JNI_OK) { return result; } // Parse args structure generated from the _JAVA_OPTIONS environment // variable (if present) (mimics classic VM) ! result = parse_each_vm_init_arg(java_options_args, &xpatch_javabase, Flag::ENVIRON_VAR); if (result != JNI_OK) { return result; } // Do final processing now that all arguments have been parsed --- 2661,2684 ---- // Setup flags for mixed which is the default set_mode_flags(_mixed); // Parse args structure generated from JAVA_TOOL_OPTIONS environment // variable (if present). ! jint result = parse_each_vm_init_arg(java_tool_options_args, &patch_mod_javabase, Flag::ENVIRON_VAR); if (result != JNI_OK) { return result; } // Parse args structure generated from the command line flags. ! result = parse_each_vm_init_arg(cmd_line_args, &patch_mod_javabase, Flag::COMMAND_LINE); if (result != JNI_OK) { return result; } // Parse args structure generated from the _JAVA_OPTIONS environment // variable (if present) (mimics classic VM) ! result = parse_each_vm_init_arg(java_options_args, &patch_mod_javabase, Flag::ENVIRON_VAR); if (result != JNI_OK) { return result; } // Do final processing now that all arguments have been parsed
*** 2619,2629 **** } return false; } ! jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* xpatch_javabase, Flag::Flags origin) { // For match_option to return remaining or value part of option string const char* tail; // iterate over arguments for (int index = 0; index < args->nOptions; index++) { --- 2733,2771 ---- } return false; } ! int Arguments::process_patch_mod_option(const char* patch_mod_tail, bool* patch_mod_javabase) { ! // --patch-module=<module>=<file>(<pathsep><file>)* ! assert(patch_mod_tail != NULL, "Unexpected NULL patch-module value"); ! // Find the equal sign between the module name and the path specification ! const char* module_equal = strchr(patch_mod_tail, '='); ! if (module_equal == NULL) { ! jio_fprintf(defaultStream::output_stream(), "Missing '=' in --patch-module specification\n"); ! return JNI_ERR; ! } else { ! // Pick out the module name ! size_t module_len = module_equal - patch_mod_tail; ! char* module_name = NEW_C_HEAP_ARRAY_RETURN_NULL(char, module_len+1, mtArguments); ! if (module_name != NULL) { ! memcpy(module_name, patch_mod_tail, module_len); ! *(module_name + module_len) = '\0'; ! // The path piece begins one past the module_equal sign ! add_patch_mod_prefix(module_name, module_equal + 1, patch_mod_javabase); ! FREE_C_HEAP_ARRAY(char, module_name); ! if (!create_numbered_property("jdk.module.patch", patch_mod_tail, patch_mod_count++)) { ! return JNI_ENOMEM; ! } ! } else { ! return JNI_ENOMEM; ! } ! } ! return JNI_OK; ! } ! ! jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_mod_javabase, Flag::Flags origin) { // For match_option to return remaining or value part of option string const char* tail; // iterate over arguments for (int index = 0; index < args->nOptions; index++) {
*** 2704,2713 **** --- 2846,2883 ---- return JNI_ERR; } #endif // !INCLUDE_JVMTI add_init_library(name, options); } + } else if (match_option(option, "--add-reads=", &tail)) { + if (!create_numbered_property("jdk.module.addreads", tail, addreads_count++)) { + return JNI_ENOMEM; + } + } else if (match_option(option, "--add-exports=", &tail)) { + if (!create_numbered_property("jdk.module.addexports", tail, addexports_count++)) { + return JNI_ENOMEM; + } + } else if (match_option(option, "--add-modules=", &tail)) { + add_modules_value = tail; + } else if (match_option(option, "--limit-modules=", &tail)) { + if (!create_property("jdk.module.limitmods", tail, InternalProperty)) { + return JNI_ENOMEM; + } + } else if (match_option(option, "--module-path=", &tail)) { + if (!create_property("jdk.module.path", tail, ExternalProperty)) { + return JNI_ENOMEM; + } + } else if (match_option(option, "--upgrade-module-path=", &tail)) { + if (!create_property("jdk.module.upgrade.path", tail, ExternalProperty)) { + return JNI_ENOMEM; + } + } else if (match_option(option, "--patch-module=", &tail)) { + // --patch-module=<module>=<file>(<pathsep><file>)* + int res = process_patch_mod_option(tail, patch_mod_javabase); + if (res != JNI_OK) { + return res; + } // -agentlib and -agentpath } else if (match_option(option, "-agentlib:", &tail) || (is_absolute_path = match_option(option, "-agentpath:", &tail))) { if(tail != NULL) { const char* pos = strchr(tail, '=');
*** 2995,3004 **** --- 3165,3179 ---- // abort if -Djava.ext.dirs is set jio_fprintf(defaultStream::output_stream(), "-Djava.ext.dirs=%s is not supported. Use -classpath instead.\n", value); return JNI_EINVAL; } + // Silently ignore module related properties. They must be set using the modules + // options. For example: use "--add-modules java.sql", not "-Djdk.module.addmods=java.sql" + if (is_module_property(option)) { + continue; + } if (!add_property(tail)) { return JNI_ENOMEM; } // Out of the box management support
*** 3015,3051 **** jio_fprintf(defaultStream::output_stream(), "-Dcom.sun.management is not supported in this VM.\n"); return JNI_ERR; #endif } - if (match_option(option, "-Djdk.launcher.patch.", &tail)) { - // -Djdk.launcher.patch.#=<module>=<file>(<pathsep><file>)* - // The number, #, specified will be increasing with each -Xpatch - // specified on the command line. - // Pick up module name, following the -D property's equal sign. - const char* property_equal = strchr(tail, '='); - if (property_equal == NULL) { - jio_fprintf(defaultStream::output_stream(), "Missing '=' in -Xpatch specification\n"); - return JNI_ERR; - } else { - // Find the equal sign between the module name and the path specification - const char* module_equal = strchr(property_equal + 1, '='); - if (module_equal == NULL) { - jio_fprintf(defaultStream::output_stream(), "Bad value for -Xpatch, no module name specified\n"); - return JNI_ERR; - } else { - // Pick out the module name, in between the two equal signs - size_t module_len = module_equal - property_equal - 1; - char* module_name = NEW_C_HEAP_ARRAY(char, module_len+1, mtArguments); - memcpy(module_name, property_equal + 1, module_len); - *(module_name + module_len) = '\0'; - // The path piece begins one past the module_equal sign - Arguments::add_xpatchprefix(module_name, module_equal + 1, xpatch_javabase); - FREE_C_HEAP_ARRAY(char, module_name); - } - } - } // -Xint } else if (match_option(option, "-Xint")) { set_mode_flags(_int); // -Xmixed } else if (match_option(option, "-Xmixed")) { --- 3190,3199 ----
*** 3301,3329 **** #endif // LINUX fix_appclasspath(); return JNI_OK; } ! void Arguments::add_xpatchprefix(const char* module_name, const char* path, bool* xpatch_javabase) { ! // For java.base check for duplicate -Xpatch options being specified on the command line. // This check is only required for java.base, all other duplicate module specifications // will be checked during module system initialization. The module system initialization // will throw an ExceptionInInitializerError if this situation occurs. if (strcmp(module_name, "java.base") == 0) { ! if (*xpatch_javabase) { ! vm_exit_during_initialization("Cannot specify java.base more than once to -Xpatch"); } else { ! *xpatch_javabase = true; } } ! // Create GrowableArray lazily, only if -Xpatch has been specified ! if (_xpatchprefix == NULL) { ! _xpatchprefix = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<ModuleXPatchPath*>(10, true); } ! _xpatchprefix->push(new ModuleXPatchPath(module_name, path)); } // Set property jdk.boot.class.path.append to the contents of the bootclasspath // that follows either the jimage file or exploded module directories. The // property will contain -Xbootclasspath/a and/or jvmti appended additions. --- 3449,3477 ---- #endif // LINUX fix_appclasspath(); return JNI_OK; } ! void Arguments::add_patch_mod_prefix(const char* module_name, const char* path, bool* patch_mod_javabase) { ! // For java.base check for duplicate --patch-module options being specified on the command line. // This check is only required for java.base, all other duplicate module specifications // will be checked during module system initialization. The module system initialization // will throw an ExceptionInInitializerError if this situation occurs. if (strcmp(module_name, "java.base") == 0) { ! if (*patch_mod_javabase) { ! vm_exit_during_initialization("Cannot specify java.base more than once to --patch-module"); } else { ! *patch_mod_javabase = true; } } ! // Create GrowableArray lazily, only if --patch-module has been specified ! if (_patch_mod_prefix == NULL) { ! _patch_mod_prefix = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<ModulePatchPath*>(10, true); } ! _patch_mod_prefix->push(new ModulePatchPath(module_name, path)); } // Set property jdk.boot.class.path.append to the contents of the bootclasspath // that follows either the jimage file or exploded module directories. The // property will contain -Xbootclasspath/a and/or jvmti appended additions.
*** 3456,3465 **** --- 3604,3620 ---- "Use -classpath instead.\n."); os::closedir(dir); return JNI_ERR; } + // Append the value of the last --add-modules option specified on the command line. + // This needs to be done here, to prevent overwriting possible values written + // to the jdk.module.addmods property by -javaagent and other options. + if (add_modules_value != NULL) { + append_to_addmods_property(add_modules_value); + } + Arguments::set_bootclassloader_append_index(((int)strlen(Arguments::get_sysclasspath()))+1); // This must be done after all arguments have been processed. // java_compiler() true means set to "NONE" or empty. if (java_compiler() && !xdebug_mode()) {
*** 3812,3824 **** return status; } void Arguments::set_shared_spaces_flags() { if (DumpSharedSpaces) { ! if (Arguments::get_xpatchprefix() != NULL) { vm_exit_during_initialization( ! "Cannot use the following option when dumping the shared archive", "-Xpatch"); } if (RequireSharedSpaces) { warning("Cannot dump shared archive while using shared archive"); } --- 3967,3979 ---- return status; } void Arguments::set_shared_spaces_flags() { if (DumpSharedSpaces) { ! if (Arguments::get_patch_mod_prefix() != NULL) { vm_exit_during_initialization( ! "Cannot use the following option when dumping the shared archive: --patch-module"); } if (RequireSharedSpaces) { warning("Cannot dump shared archive while using shared archive"); }
*** 4474,4514 **** } p->set_next(new_p); } } ! void Arguments::PropertyList_add(SystemProperty** plist, const char* k, const char* v) { if (plist == NULL) return; ! SystemProperty* new_p = new SystemProperty(k, v, true); PropertyList_add(plist, new_p); } void Arguments::PropertyList_add(SystemProperty *element) { PropertyList_add(&_system_properties, element); } // This add maintains unique property key in the list. ! void Arguments::PropertyList_unique_add(SystemProperty** plist, const char* k, const char* v, jboolean append) { if (plist == NULL) return; // If property key exist then update with new value. SystemProperty* prop; for (prop = *plist; prop != NULL; prop = prop->next()) { if (strcmp(k, prop->key()) == 0) { ! if (append) { prop->append_value(v); } else { ! prop->set_writeable_value(v); } return; } } ! PropertyList_add(plist, k, v); } // Copies src into buf, replacing "%%" with "%" and "%p" with pid // Returns true if all of the source pointed by src has been copied over to // the destination buffer pointed by buf. Otherwise, returns false. --- 4629,4672 ---- } p->set_next(new_p); } } ! void Arguments::PropertyList_add(SystemProperty** plist, const char* k, const char* v, ! bool writeable, bool internal) { if (plist == NULL) return; ! SystemProperty* new_p = new SystemProperty(k, v, writeable, internal); PropertyList_add(plist, new_p); } void Arguments::PropertyList_add(SystemProperty *element) { PropertyList_add(&_system_properties, element); } // This add maintains unique property key in the list. ! void Arguments::PropertyList_unique_add(SystemProperty** plist, const char* k, const char* v, ! PropertyAppendable append, PropertyWriteable writeable, ! PropertyInternal internal) { if (plist == NULL) return; // If property key exist then update with new value. SystemProperty* prop; for (prop = *plist; prop != NULL; prop = prop->next()) { if (strcmp(k, prop->key()) == 0) { ! if (append == AppendProperty) { prop->append_value(v); } else { ! prop->set_value(v); } return; } } ! PropertyList_add(plist, k, v, writeable == WriteableProperty, internal == InternalProperty); } // Copies src into buf, replacing "%%" with "%" and "%p" with pid // Returns true if all of the source pointed by src has been copied over to // the destination buffer pointed by buf. Otherwise, returns false.
< prev index next >