< prev index next >

src/share/vm/logging/logConfiguration.cpp

Print this page
rev 11857 : [mq]: 8157948

@@ -105,52 +105,75 @@
     delete _outputs[i];
   }
   FREE_C_HEAP_ARRAY(LogOutput*, _outputs);
 }
 
-size_t LogConfiguration::find_output(const char* name) {
-  for (size_t i = 0; i < _n_outputs; i++) {
-    if (strcmp(_outputs[i]->name(), name) == 0) {
-      return i;
-    }
-  }
-  return SIZE_MAX;
-}
-
-LogOutput* LogConfiguration::new_output(char* name, const char* options, outputStream* errstream) {
-  const char* type;
-  char* equals_pos = strchr(name, '=');
-  if (equals_pos == NULL) {
-    type = "file";
-  } else {
-    *equals_pos = '\0';
-    type = name;
-    name = equals_pos + 1;
+// Normalizes the given LogOutput name to type=name form.
+static bool normalize_output_name(const char* full_name, char* buffer, size_t len, outputStream* errstream) {
+  const char* start_quote = strchr(full_name, '"');
+  const char* equals = strchr(full_name, '=');
+  const bool quoted = start_quote != NULL;
+  const bool is_stdout_or_stderr = (strcmp(full_name, "stdout") == 0 || strcmp(full_name, "stderr") == 0);
+
+  // ignore equals sign within quotes
+  if (quoted && equals > start_quote) {
+    equals = NULL;
+  }
+
+  const char* prefix = "";
+  size_t prefix_len = 0;
+  const char* name = full_name;
+  if (equals != NULL) {
+    // split on equals sign
+    name = equals + 1;
+    prefix = full_name;
+    prefix_len = equals - full_name + 1;
+  } else if (!is_stdout_or_stderr) {
+    prefix = "file=";
+    prefix_len = strlen(prefix);
   }
+  size_t name_len = strlen(name);
 
-  // Check if name is quoted, and if so, strip the quotes
-  char* quote = strchr(name, '"');
-  if (quote != NULL) {
-    char* end_quote = strchr(name + 1, '"');
+  if (quoted) {
+    const char* end_quote = strchr(start_quote + 1, '"');
     if (end_quote == NULL) {
       errstream->print_cr("Output name has opening quote but is missing a terminating quote.");
-      return NULL;
-    } else if (quote != name || end_quote[1] != '\0') {
+      return false;
+    }
+    if (start_quote != name || end_quote[1] != '\0') {
       errstream->print_cr("Output name can not be partially quoted."
                           " Either surround the whole name with quotation marks,"
                           " or do not use quotation marks at all.");
-      return NULL;
+      return false;
     }
+    // strip start and end quote
     name++;
-    *end_quote = '\0';
+    name_len -= 2;
   }
 
+  int ret = jio_snprintf(buffer, len, "%.*s%.*s", prefix_len, prefix, name_len, name);
+  assert(ret > 0, "buffer issue");
+  return true;
+}
+
+size_t LogConfiguration::find_output(const char* name) {
+  for (size_t i = 0; i < _n_outputs; i++) {
+    if (strcmp(_outputs[i]->name(), name) == 0) {
+      return i;
+    }
+  }
+  return SIZE_MAX;
+}
+
+LogOutput* LogConfiguration::new_output(const char* name,
+                                        const char* options,
+                                        outputStream* errstream) {
   LogOutput* output;
-  if (strcmp(type, "file") == 0) {
+  if (strncmp(name, "file=", strlen("file=")) == 0) {
     output = new LogFileOutput(name);
   } else {
-    errstream->print_cr("Unsupported log output type.");
+    errstream->print_cr("Unsupported log output type: %s", name);
     return NULL;
   }
 
   bool success = output->initialize(options, errstream);
   if (!success) {

@@ -362,29 +385,39 @@
     return false;
   }
 
   ConfigurationLock cl;
   size_t idx;
-  if (outputstr[0] == '#') {
-    int ret = sscanf(outputstr+1, SIZE_FORMAT, &idx);
+  if (outputstr[0] == '#') { // Output specified using index
+    int ret = sscanf(outputstr + 1, SIZE_FORMAT, &idx);
     if (ret != 1 || idx >= _n_outputs) {
       errstream->print_cr("Invalid output index '%s'", outputstr);
       return false;
     }
-  } else {
-    idx = find_output(outputstr);
-    if (idx == SIZE_MAX) {
-      char* tmp = os::strdup_check_oom(outputstr, mtLogging);
-      LogOutput* output = new_output(tmp, output_options, errstream);
-      os::free(tmp);
-      if (output == NULL) {
+  } else { // Output specified using name
+    // Normalize the name, stripping quotes and ensures it includes type prefix
+    size_t len = strlen(outputstr) + strlen("file=") + 1;
+    char* normalized = NEW_C_HEAP_ARRAY(char, len, mtLogging);
+    if (!normalize_output_name(outputstr, normalized, len, errstream)) {
         return false;
       }
+
+    idx = find_output(normalized);
+    if (idx == SIZE_MAX) {
+      // Attempt to create and add the output
+      LogOutput* output = new_output(normalized, output_options, errstream);
+      if (output != NULL) {
       idx = add_output(output);
+      }
     } else if (output_options != NULL && strlen(output_options) > 0) {
       errstream->print_cr("Output options for existing outputs are ignored.");
     }
+
+    FREE_C_HEAP_ARRAY(char, normalized);
+    if (idx == SIZE_MAX) {
+      return false;
+    }
   }
   configure_output(idx, expr, decorators);
   notify_update_listeners();
   return true;
 }
< prev index next >