You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zw...@apache.org on 2018/01/12 16:03:45 UTC

[trafficserver] 04/09: New layout structure with std string & basic string view

This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a commit to branch 7.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit 08a5dccbc7d8ced37fc9cd0ccfaa8ec4b1b55618
Author: Xavier Chi <ch...@gmail.com>
AuthorDate: Tue Aug 8 15:15:45 2017 -0500

    New layout structure with std string & basic string view
    
    (cherry picked from commit 27cec04b9bd345a5fadb3bd505336c41785b7e1b)
    
     Conflicts:
    	cmd/traffic_layout/traffic_layout.cc
    	iocore/cache/Store.cc
    	lib/records/I_RecCore.h
    	lib/records/RecCore.cc
    	lib/ts/I_Layout.h
    	lib/ts/Makefile.am
    	mgmt/ProcessManager.cc
    	proxy/InkAPI.cc
    	proxy/Plugin.cc
    	proxy/logstats.cc
---
 cmd/traffic_cop/traffic_cop.cc           |  46 +++++------
 cmd/traffic_crashlog/traffic_crashlog.cc |   2 +-
 cmd/traffic_layout/traffic_layout.cc     |  30 ++++---
 cmd/traffic_manager/metrics.cc           |   2 +-
 cmd/traffic_manager/traffic_manager.cc   |  39 +++++-----
 iocore/cache/Store.cc                    |  13 ++--
 iocore/net/SSLConfig.cc                  |  10 +--
 lib/cppapi/Transaction.cc                |   4 +-
 lib/records/I_RecCore.h                  |  27 +++----
 lib/records/RecCore.cc                   |  63 ++++++++-------
 lib/ts/I_Layout.h                        |  59 +++++++-------
 lib/ts/Layout.cc                         | 130 +++++++++----------------------
 lib/ts/ink_memory.h                      |  10 +++
 lib/ts/unit-tests/test_layout.cpp        |  89 +++++++++++++++++++++
 mgmt/Alarms.cc                           |   2 +-
 mgmt/FileManager.cc                      |   2 +-
 mgmt/LocalManager.cc                     |  24 +++---
 mgmt/ProcessManager.cc                   |   6 +-
 mgmt/Rollback.cc                         |   4 +-
 mgmt/api/CoreAPIRemote.cc                |   2 +-
 mgmt/api/NetworkUtilsRemote.cc           |   4 +-
 proxy/Crash.cc                           |   2 +-
 proxy/InkAPI.cc                          |  15 ++--
 proxy/Main.cc                            |  36 ++++-----
 proxy/Plugin.cc                          |   3 +-
 proxy/http/remap/RemapConfig.cc          |   2 +-
 proxy/logging/LogConfig.cc               |   2 +-
 proxy/logging/LogStandalone.cc           |   6 +-
 proxy/logstats.cc                        |   8 +-
 29 files changed, 340 insertions(+), 302 deletions(-)

diff --git a/cmd/traffic_cop/traffic_cop.cc b/cmd/traffic_cop/traffic_cop.cc
index 871c7f6..10b9f4f 100644
--- a/cmd/traffic_cop/traffic_cop.cc
+++ b/cmd/traffic_cop/traffic_cop.cc
@@ -546,7 +546,7 @@ ConfigIntFatalError:
   exit(1);
 }
 
-static char *
+static std::string
 config_read_runtime_dir()
 {
   char state_dir[PATH_NAME_MAX];
@@ -556,11 +556,11 @@ config_read_runtime_dir()
   if (strlen(state_dir) > 0) {
     return Layout::get()->relative(state_dir);
   } else {
-    return ats_strdup(Layout::get()->runtimedir);
+    return Layout::get()->runtimedir;
   }
 }
 
-static char *
+static std::string
 config_read_sysconfig_dir()
 {
   char sysconfig_dir[PATH_NAME_MAX];
@@ -570,11 +570,11 @@ config_read_sysconfig_dir()
   if (strlen(sysconfig_dir) > 0) {
     return Layout::get()->relative(sysconfig_dir);
   } else {
-    return ats_strdup(Layout::get()->sysconfdir);
+    return Layout::get()->sysconfdir;
   }
 }
 
-static char *
+static std::string
 config_read_bin_dir()
 {
   char bindir[PATH_NAME_MAX];
@@ -585,11 +585,11 @@ config_read_bin_dir()
   if (strlen(bindir) > 0) {
     return Layout::get()->relative(bindir);
   } else {
-    return ats_strdup(Layout::get()->bindir);
+    return Layout::get()->bindir;
   }
 }
 
-static char *
+static std::string
 config_read_log_dir()
 {
   char logdir[PATH_NAME_MAX];
@@ -599,7 +599,7 @@ config_read_log_dir()
   if (strlen(logdir) > 0) {
     return Layout::get()->relative(logdir);
   } else {
-    return ats_strdup(Layout::get()->logdir);
+    return Layout::get()->logdir;
   }
 }
 
@@ -611,8 +611,8 @@ config_reload_records()
   char log_filename[PATH_NAME_MAX];
   int tmp_int = 3;
 
-  ats_scoped_str bindir;
-  ats_scoped_str logdir;
+  std::string bindir;
+  std::string logdir;
 
   cop_log_trace("Entering %s()\n", __func__);
   // coverity[fs_check_call]
@@ -640,15 +640,15 @@ config_reload_records()
   get_admin_user();
 
   bindir = config_read_bin_dir();
-  if (access(bindir, R_OK) == -1) {
-    cop_log(COP_FATAL, "could not access() \"%s\"\n", (const char *)bindir);
+  if (access(bindir.c_str(), R_OK) == -1) {
+    cop_log(COP_FATAL, "could not access() \"%s\"\n", bindir.c_str());
     cop_log(COP_FATAL, "please set 'proxy.config.bin_path' \n");
     exit(1);
   }
 
   logdir = config_read_log_dir();
-  if (access(logdir, W_OK) == -1) {
-    cop_log(COP_FATAL, "could not access() \"%s\"\n", (const char *)logdir);
+  if (access(logdir.c_str(), W_OK) == -1) {
+    cop_log(COP_FATAL, "could not access() \"%s\"\n", logdir.c_str());
     cop_log(COP_FATAL, "please set 'proxy.config.log.logfile_dir' \n");
     exit(1);
   }
@@ -745,7 +745,7 @@ static void
 spawn_manager()
 {
   char prog[PATH_NAME_MAX];
-  ats_scoped_str bindir(config_read_bin_dir());
+  std::string bindir(config_read_bin_dir());
 
   cop_log_trace("Entering spawn_manager()\n");
 
@@ -1638,8 +1638,8 @@ check(void *arg)
 
     // We do this after the first round of checks, since the first "check" will spawn traffic_manager
     if (!mgmt_init) {
-      ats_scoped_str runtimedir(config_read_runtime_dir());
-      TSInit(runtimedir, static_cast<TSInitOptionT>(TS_MGMT_OPT_NO_EVENTS));
+      std::string runtimedir(config_read_runtime_dir());
+      TSInit(runtimedir.c_str(), static_cast<TSInitOptionT>(TS_MGMT_OPT_NO_EVENTS));
       mgmt_init = true;
 
       // Allow a configurable longer sleep init time
@@ -1762,13 +1762,13 @@ static void
 init_config_file()
 {
   struct stat info;
-  ats_scoped_str config_dir;
+  std::string config_dir;
 
   cop_log_trace("Entering init_config_file()\n");
 
   config_dir = config_read_sysconfig_dir();
-  if (stat(config_dir, &info) < 0) {
-    cop_log(COP_FATAL, "unable to locate config directory '%s'\n", (const char *)config_dir);
+  if (stat(config_dir.c_str(), &info) < 0) {
+    cop_log(COP_FATAL, "unable to locate config directory '%s'\n", config_dir.c_str());
     cop_log(COP_FATAL, " please try setting correct root path in env variable TS_ROOT \n");
     exit(1);
   }
@@ -1777,8 +1777,8 @@ init_config_file()
   if (stat(config_file, &info) < 0) {
     Layout::relative_to(config_file, sizeof(config_file), config_dir, "records.config");
     if (stat(config_file, &info) < 0) {
-      cop_log(COP_FATAL, "unable to locate \"%s/records.config\" or \"%s/records.config.shadow\"\n", (const char *)config_dir,
-              (const char *)config_dir);
+      cop_log(COP_FATAL, "unable to locate \"%s/records.config\" or \"%s/records.config.shadow\"\n", config_dir.c_str(),
+              config_dir.c_str());
       exit(1);
     }
   }
@@ -1802,7 +1802,7 @@ init()
   init_config_file();
   config_reload_records();
 
-  runtime_dir = config_read_runtime_dir();
+  runtime_dir = ats_stringdup(config_read_runtime_dir());
   if (stat(runtime_dir, &info) < 0) {
     cop_log(COP_FATAL, "unable to locate local state directory '%s'\n", runtime_dir);
     cop_log(COP_FATAL, " please try setting correct root path in either env variable TS_ROOT \n");
diff --git a/cmd/traffic_crashlog/traffic_crashlog.cc b/cmd/traffic_crashlog/traffic_crashlog.cc
index faf98dc..54b4755 100644
--- a/cmd/traffic_crashlog/traffic_crashlog.cc
+++ b/cmd/traffic_crashlog/traffic_crashlog.cc
@@ -65,7 +65,7 @@ crashlog_name()
 {
   char filename[64];
   struct tm now = timestamp();
-  ats_scoped_str logdir(RecConfigReadLogDir());
+  std::string logdir(RecConfigReadLogDir());
   ats_scoped_str pathname;
 
   strftime(filename, sizeof(filename), "crash-%Y-%m-%d-%H%M%S.log", &now);
diff --git a/cmd/traffic_layout/traffic_layout.cc b/cmd/traffic_layout/traffic_layout.cc
index cce710b..f48befb 100644
--- a/cmd/traffic_layout/traffic_layout.cc
+++ b/cmd/traffic_layout/traffic_layout.cc
@@ -28,6 +28,8 @@
 #include "I_RecProcess.h"
 #include "RecordsConfig.h"
 
+#include <iostream>
+
 // Command line arguments (parsing)
 struct CommandLineArgs {
   int layout;
@@ -122,18 +124,14 @@ produce_features(bool json)
   }
 }
 
-static void
-print_var(const char *name, char *value, bool json, bool free = true, bool last = false)
+void
+print_var(ts::string_view const &name, ts::string_view const &value, bool json, bool last = false)
 {
-  if (json) {
-    printf(R"(    "%s": "%s"%s)", name, value, last ? "\n" : ",\n");
-  } else {
-    printf("%s: %s\n", name, value);
-  }
-
-  if (free) {
-    ats_free(value);
-  }
+  if (json)
+    printf(R"(    "%.*s": "%.*s"%s)", static_cast<int>(name.size()), name.data(), static_cast<int>(value.size()), value.data(),
+           last ? "\n" : ",\n");
+  else
+    printf("%.*s: %.*s\n", static_cast<int>(name.size()), name.data(), static_cast<int>(value.size()), value.data());
 }
 
 static void
@@ -147,14 +145,14 @@ produce_layout(bool json)
   if (json) {
     printf("{\n");
   }
-  print_var("PREFIX", Layout::get()->prefix, json, false); // Don't free this
+  print_var("PREFIX", Layout::get()->prefix, json);
   print_var("BINDIR", RecConfigReadBinDir(), json);
   print_var("SYSCONFDIR", RecConfigReadConfigDir(), json);
-  print_var("LIBDIR", Layout::get()->libdir, json, false); // Don't free this
+  print_var("LIBDIR", Layout::get()->libdir, json);
   print_var("LOGDIR", RecConfigReadLogDir(), json);
   print_var("RUNTIMEDIR", RecConfigReadRuntimeDir(), json);
-  print_var("PLUGINDIR", RecConfigReadPrefixPath("proxy.config.plugin.plugin_dir"), json);
-  print_var("INCLUDEDIR", Layout::get()->includedir, json, false); // Dont' free this
+  print_var("PLUGINDIR", RecConfigReadPluginDir(), json);
+  print_var("INCLUDEDIR", Layout::get()->includedir, json);
   print_var("SNAPSHOTDIR", RecConfigReadSnapshotDir(), json);
 
   print_var("records.config", RecConfigReadConfigPath(nullptr, REC_CONFIG_FILE), json);
@@ -164,7 +162,7 @@ produce_layout(bool json)
   print_var("storage.config", RecConfigReadConfigPath("proxy.config.cache.storage_filename"), json);
   print_var("hosting.config", RecConfigReadConfigPath("proxy.config.cache.hosting_filename"), json);
   print_var("volume.config", RecConfigReadConfigPath("proxy.config.cache.volume_filename"), json);
-  print_var("ip_allow.config", RecConfigReadConfigPath("proxy.config.cache.ip_allow.filename"), json, true, true);
+  print_var("ip_allow.config", RecConfigReadConfigPath("proxy.config.cache.ip_allow.filename"), json, true);
   if (json) {
     printf("}\n");
   }
diff --git a/cmd/traffic_manager/metrics.cc b/cmd/traffic_manager/metrics.cc
index 88a296f..bdb7e8e 100644
--- a/cmd/traffic_manager/metrics.cc
+++ b/cmd/traffic_manager/metrics.cc
@@ -387,7 +387,7 @@ bool
 metrics_binding_configure(BindingInstance &binding)
 {
   ats_scoped_str sysconfdir(RecConfigReadConfigDir());
-  ats_scoped_str config(Layout::get()->relative_to(sysconfdir, "metrics.config"));
+  ats_scoped_str config(Layout::get()->relative_to(sysconfdir.get(), "metrics.config"));
 
   return binding.require(config.get());
 }
diff --git a/cmd/traffic_manager/traffic_manager.cc b/cmd/traffic_manager/traffic_manager.cc
index d9964f5..f0afcaf 100644
--- a/cmd/traffic_manager/traffic_manager.cc
+++ b/cmd/traffic_manager/traffic_manager.cc
@@ -166,7 +166,7 @@ is_server_idle()
 static void
 check_lockfile()
 {
-  ats_scoped_str rundir(RecConfigReadRuntimeDir());
+  std::string rundir(RecConfigReadRuntimeDir());
   char lockfile[PATH_NAME_MAX];
   int err;
   pid_t holding_pid;
@@ -302,17 +302,17 @@ initSignalHandlers()
 static void
 init_dirs()
 {
-  ats_scoped_str rundir(RecConfigReadRuntimeDir());
-  ats_scoped_str sysconfdir(RecConfigReadConfigDir());
+  std::string rundir(RecConfigReadRuntimeDir());
+  std::string sysconfdir(RecConfigReadConfigDir());
 
-  if (access(sysconfdir, R_OK) == -1) {
-    mgmt_elog(0, "unable to access() config directory '%s': %d, %s\n", (const char *)sysconfdir, errno, strerror(errno));
+  if (access(sysconfdir.c_str(), R_OK) == -1) {
+    mgmt_elog(0, "unable to access() config directory '%s': %d, %s\n", sysconfdir.c_str(), errno, strerror(errno));
     mgmt_elog(0, "please set the 'TS_ROOT' environment variable\n");
     ::exit(1);
   }
 
-  if (access(rundir, R_OK) == -1) {
-    mgmt_elog(0, "unable to access() local state directory '%s': %d, %s\n", (const char *)rundir, errno, strerror(errno));
+  if (access(rundir.c_str(), R_OK) == -1) {
+    mgmt_elog(0, "unable to access() local state directory '%s': %d, %s\n", rundir.c_str(), errno, strerror(errno));
     mgmt_elog(0, "please set 'proxy.config.local_state_dir'\n");
     ::exit(1);
   }
@@ -321,14 +321,14 @@ init_dirs()
 static void
 chdir_root()
 {
-  const char *prefix = Layout::get()->prefix;
+  std::string prefix = Layout::get()->prefix;
 
-  if (chdir(prefix) < 0) {
-    mgmt_elog(0, "unable to change to root directory \"%s\" [%d '%s']\n", prefix, errno, strerror(errno));
+  if (chdir(prefix.c_str()) < 0) {
+    mgmt_elog(0, "unable to change to root directory \"%s\" [%d '%s']\n", prefix.c_str(), errno, strerror(errno));
     mgmt_elog(0, " please set correct path in env variable TS_ROOT \n");
     exit(1);
   } else {
-    mgmt_log("[TrafficManager] using root directory '%s'\n", prefix);
+    mgmt_log("[TrafficManager] using root directory '%s'\n", prefix.c_str());
   }
 }
 
@@ -421,7 +421,7 @@ main(int argc, const char **argv)
 
   // Before accessing file system initialize Layout engine
   Layout::create();
-  mgmt_path = Layout::get()->sysconfdir;
+  mgmt_path = Layout::get()->sysconfdir.c_str();
 
   // Set up the application version info
   appVersionInfo.setup(PACKAGE_NAME, "traffic_manager", PACKAGE_VERSION, __DATE__, __TIME__, BUILD_MACHINE, BUILD_PERSON, "");
@@ -681,9 +681,9 @@ main(int argc, const char **argv)
   Debug("lm", "Created Web Agent thread (%" PRId64 ")", (int64_t)synthThrId);
 
   // Setup the API and event sockets
-  ats_scoped_str rundir(RecConfigReadRuntimeDir());
-  ats_scoped_str apisock(Layout::relative_to(rundir, MGMTAPI_MGMT_SOCKET_NAME));
-  ats_scoped_str eventsock(Layout::relative_to(rundir, MGMTAPI_EVENT_SOCKET_NAME));
+  std::string rundir(RecConfigReadRuntimeDir());
+  std::string apisock(Layout::relative_to(rundir, MGMTAPI_MGMT_SOCKET_NAME));
+  std::string eventsock(Layout::relative_to(rundir, MGMTAPI_EVENT_SOCKET_NAME));
 
   mode_t oldmask = umask(0);
   mode_t newmode = api_socket_is_restricted() ? 00700 : 00777;
@@ -692,17 +692,16 @@ main(int argc, const char **argv)
   int eventapiFD        = -1; // FD for the api and clients to handle event callbacks
   char mgmtapiFailMsg[] = "Traffic server management API service Interface Failed to Initialize.";
 
-  mgmtapiFD = bind_unix_domain_socket(apisock, newmode);
+  mgmtapiFD = bind_unix_domain_socket(apisock.c_str(), newmode);
   if (mgmtapiFD == -1) {
-    mgmt_log("[WebIntrMain] Unable to set up socket for handling management API calls. API socket path = %s\n",
-             (const char *)apisock);
+    mgmt_log("[WebIntrMain] Unable to set up socket for handling management API calls. API socket path = %s\n", apisock.c_str());
     lmgmt->alarm_keeper->signalAlarm(MGMT_ALARM_WEB_ERROR, mgmtapiFailMsg);
   }
 
-  eventapiFD = bind_unix_domain_socket(eventsock, newmode);
+  eventapiFD = bind_unix_domain_socket(eventsock.c_str(), newmode);
   if (eventapiFD == -1) {
     mgmt_log("[WebIntrMain] Unable to set up so for handling management API event calls. Event Socket path: %s\n",
-             (const char *)eventsock);
+             eventsock.c_str());
   }
 
   umask(oldmask);
diff --git a/iocore/cache/Store.cc b/iocore/cache/Store.cc
index 06068ad..16e873c 100644
--- a/iocore/cache/Store.cc
+++ b/iocore/cache/Store.cc
@@ -378,19 +378,18 @@ Store::read_config()
       }
     }
 
-    char *pp = Layout::get()->relative(path);
+    std::string pp = Layout::get()->relative(path);
 
     ns = new Span;
-    Debug("cache_init", "Store::read_config - ns = new Span; ns->init(\"%s\",%" PRId64 "), forced volume=%d%s%s", pp, size,
+    Debug("cache_init", "Store::read_config - ns = new Span; ns->init(\"%s\",%" PRId64 "), forced volume=%d%s%s", pp.c_str(), size,
           volume_num, seed ? " id=" : "", seed ? seed : "");
-    if ((err = ns->init(pp, size))) {
-      RecSignalWarning(REC_SIGNAL_SYSTEM_ERROR, "could not initialize storage \"%s\" [%s]", pp, err);
-      Debug("cache_init", "Store::read_config - could not initialize storage \"%s\" [%s]", pp, err);
+    if ((err = ns->init(pp.c_str(), size))) {
+      RecSignalWarning(REC_SIGNAL_SYSTEM_ERROR, "could not initialize storage \"%s\" [%s]", pp.c_str(), err);
+      Debug("cache_init", "Store::read_config - could not initialize storage \"%s\" [%s]", pp.c_str(), err);
       delete ns;
-      ats_free(pp);
       continue;
     }
-    ats_free(pp);
+
     n_dsstore++;
 
     // Set side values if present.
diff --git a/iocore/net/SSLConfig.cc b/iocore/net/SSLConfig.cc
index 01cc1ba..731e351 100644
--- a/iocore/net/SSLConfig.cc
+++ b/iocore/net/SSLConfig.cc
@@ -141,16 +141,16 @@ set_paths_helper(const char *path, const char *filename, char **final_path, char
 {
   if (final_path) {
     if (path && path[0] != '/') {
-      *final_path = RecConfigReadPrefixPath(nullptr, path);
+      *final_path = ats_stringdup(RecConfigReadPrefixPath(nullptr, path));
     } else if (!path || path[0] == '\0') {
-      *final_path = RecConfigReadConfigDir();
+      *final_path = ats_stringdup(RecConfigReadConfigDir());
     } else {
       *final_path = ats_strdup(path);
     }
   }
 
   if (final_filename) {
-    *final_filename = filename ? Layout::get()->relative_to(path, filename) : nullptr;
+    *final_filename = filename ? ats_stringdup(Layout::get()->relative_to(path, filename)) : nullptr;
   }
 }
 
@@ -176,7 +176,7 @@ SSLConfigParams::initialize()
   REC_ReadConfigInt32(clientCertLevel, "proxy.config.ssl.client.certification_level");
   REC_ReadConfigStringAlloc(cipherSuite, "proxy.config.ssl.server.cipher_suite");
   REC_ReadConfigStringAlloc(client_cipherSuite, "proxy.config.ssl.client.cipher_suite");
-  dhparamsFile = RecConfigReadConfigPath("proxy.config.ssl.server.dhparams_file");
+  dhparamsFile = ats_stringdup(RecConfigReadConfigPath("proxy.config.ssl.server.dhparams_file"));
 
   int options;
   int client_ssl_options = 0;
@@ -249,7 +249,7 @@ SSLConfigParams::initialize()
   set_paths_helper(serverCertRelativePath, nullptr, &serverCertPathOnly, nullptr);
   ats_free(serverCertRelativePath);
 
-  configFilePath = RecConfigReadConfigPath("proxy.config.ssl.server.multicert.filename");
+  configFilePath = ats_stringdup(RecConfigReadConfigPath("proxy.config.ssl.server.multicert.filename"));
   REC_ReadConfigInteger(configExitOnLoadError, "proxy.config.ssl.server.multicert.exit_on_load_fail");
 
   REC_ReadConfigStringAlloc(ssl_server_private_key_path, "proxy.config.ssl.server.private_key.path");
diff --git a/lib/cppapi/Transaction.cc b/lib/cppapi/Transaction.cc
index b7a2703..261bfce 100644
--- a/lib/cppapi/Transaction.cc
+++ b/lib/cppapi/Transaction.cc
@@ -395,9 +395,9 @@ Transaction::getCacheStatus()
 void
 Transaction::redirectTo(std::string const &url)
 {
-  char *s = ats_strdup(url.c_str());
+  std::string s = url;
   // Must re-alloc the string locally because ownership is transferred to the transaction.
-  TSHttpTxnRedirectUrlSet(state_->txn_, s, url.length());
+  TSHttpTxnRedirectUrlSet(state_->txn_, s.c_str(), url.length());
 }
 
 namespace
diff --git a/lib/records/I_RecCore.h b/lib/records/I_RecCore.h
index 52d8d48..ff39339 100644
--- a/lib/records/I_RecCore.h
+++ b/lib/records/I_RecCore.h
@@ -49,36 +49,33 @@ void RecConfigFileInit(void);
 int RecConfigFileParse(const char *path, RecConfigEntryCallback handler, bool inc_version);
 
 // Return a copy of the system's configuration directory, taking proxy.config.config_dir into account. The
-// caller MUST release the result with ats_free().
-char *RecConfigReadConfigDir();
+std::string RecConfigReadConfigDir();
 
 // Return a copy of the system's local state directory, taking proxy.config.local_state_dir into account. The
-// caller MUST release the result with ats_free().
-char *RecConfigReadRuntimeDir();
+std::string RecConfigReadRuntimeDir();
 
 // Return a copy of the system's snapshot directory, taking proxy.config.snapshot_dir into account. The caller
-// MUST release the result with ats_free().
-char *RecConfigReadSnapshotDir();
+std::string RecConfigReadSnapshotDir();
 
 // Return a copy of the system's log directory, taking proxy.config.log.logfile_dir into account. The caller
-// MUST release the result with ats_free().
-char *RecConfigReadLogDir();
+std::string RecConfigReadLogDir();
 
 // Return a copy of the system's bin directory, taking proxy.config.bin_path into account. The caller MUST
-// release the result with ats_free().
-char *RecConfigReadBinDir();
+std::string RecConfigReadBinDir();
+
+// Return a copy of the system's plugin directory, taking proxy.config.plugin.plugin_dir into account. The caller MUST
+std::string RecConfigReadPluginDir();
 
 // Return a copy of a configuration file that is relative to sysconfdir. The relative path to the configuration
 // file is specified in the configuration variable named by "file_variable". If the configuration variable has no
-// value, nullptr is returned. The caller MUST release the result with ats_free().
-char *RecConfigReadConfigPath(const char *file_variable, const char *default_value = nullptr);
+// value, nullptr is returned.
+std::string RecConfigReadConfigPath(const char *file_variable, const char *default_value = nullptr);
 
 // This is the same as RecConfigReadConfigPath, except it makes the paths relative to $PREFIX.
-char *RecConfigReadPrefixPath(const char *file_variable, const char *default_value = nullptr);
+std::string RecConfigReadPrefixPath(const char *file_variable, const char *default_value = nullptr);
 
 // Return a copy of the persistent stats file. This is $RUNTIMEDIR/records.snap.
-// The caller MUST release the result with ats_free().
-char *RecConfigReadPersistentStatsPath();
+std::string RecConfigReadPersistentStatsPath();
 
 // Test whether the named configuration value is overridden by an environment variable. Return either
 // the overridden value, or the original value. Caller MUST NOT free the result.
diff --git a/lib/records/RecCore.cc b/lib/records/RecCore.cc
index 71e5fda..0d5cea2 100644
--- a/lib/records/RecCore.cc
+++ b/lib/records/RecCore.cc
@@ -210,17 +210,14 @@ RecCoreInit(RecModeT mode_type, Diags *_diags)
   }
   // read configs
   if ((mode_type == RECM_SERVER) || (mode_type == RECM_STAND_ALONE)) {
-    ink_mutex_init(&g_rec_config_lock, nullptr);
-    // Import the file into memory; try the following in this order:
-    // ./etc/trafficserver/records.config.shadow
-    // ./records.config.shadow
-    // ./etc/trafficserver/records.config
-    // ./records.config
-    bool file_exists   = true;
-    g_rec_config_fpath = RecConfigReadConfigPath(nullptr, REC_CONFIG_FILE REC_SHADOW_EXT);
+    bool file_exists = true;
+
+    ink_mutex_init(&g_rec_config_lock);
+
+    g_rec_config_fpath = ats_stringdup(RecConfigReadConfigPath(nullptr, REC_CONFIG_FILE REC_SHADOW_EXT));
     if (RecFileExists(g_rec_config_fpath) == REC_ERR_FAIL) {
       ats_free((char *)g_rec_config_fpath);
-      g_rec_config_fpath = RecConfigReadConfigPath(nullptr, REC_CONFIG_FILE);
+      g_rec_config_fpath = ats_stringdup(RecConfigReadConfigPath(nullptr, REC_CONFIG_FILE));
       if (RecFileExists(g_rec_config_fpath) == REC_ERR_FAIL) {
         RecLog(DL_Warning, "Could not find '%s', system will run with defaults\n", REC_CONFIG_FILE);
         file_exists = false;
@@ -1120,10 +1117,11 @@ REC_readString(const char *name, bool *found, bool lock)
   return _tmp;
 }
 
-//-------------------------------------------------------------------------
-// RecConfigReadConfigDir
-//-------------------------------------------------------------------------
-char *
+// RecConfigReadConfigDir. Note that we handle environmental configuration
+// overrides specially here. Normally we would override the configuration
+// variable when we read records.config but to avoid the bootstrapping
+// problem, we make an explicit check here.
+std::string
 RecConfigReadConfigDir()
 {
   char buf[PATH_NAME_MAX];
@@ -1133,14 +1131,14 @@ RecConfigReadConfigDir()
   if (strlen(buf) > 0) {
     return Layout::get()->relative(buf);
   } else {
-    return ats_strdup(Layout::get()->sysconfdir);
+    return Layout::get()->sysconfdir;
   }
 }
 
 //-------------------------------------------------------------------------
 // RecConfigReadRuntimeDir
 //-------------------------------------------------------------------------
-char *
+std::string
 RecConfigReadRuntimeDir()
 {
   char buf[PATH_NAME_MAX];
@@ -1150,14 +1148,14 @@ RecConfigReadRuntimeDir()
   if (strlen(buf) > 0) {
     return Layout::get()->relative(buf);
   } else {
-    return ats_strdup(Layout::get()->runtimedir);
+    return Layout::get()->runtimedir;
   }
 }
 
 //-------------------------------------------------------------------------
 // RecConfigReadLogDir
 //-------------------------------------------------------------------------
-char *
+std::string
 RecConfigReadLogDir()
 {
   char buf[PATH_NAME_MAX];
@@ -1167,14 +1165,14 @@ RecConfigReadLogDir()
   if (strlen(buf) > 0) {
     return Layout::get()->relative(buf);
   } else {
-    return ats_strdup(Layout::get()->logdir);
+    return Layout::get()->logdir;
   }
 }
 
 //-------------------------------------------------------------------------
 // RecConfigReadBinDir
 //-------------------------------------------------------------------------
-char *
+std::string
 RecConfigReadBinDir()
 {
   char buf[PATH_NAME_MAX];
@@ -1184,14 +1182,23 @@ RecConfigReadBinDir()
   if (strlen(buf) > 0) {
     return Layout::get()->relative(buf);
   } else {
-    return ats_strdup(Layout::get()->bindir);
+    return Layout::get()->bindir;
   }
 }
 
 //-------------------------------------------------------------------------
+// RecConfigReadPluginDir
+//-------------------------------------------------------------------------
+std::string
+RecConfigReadPluginDir()
+{
+  return RecConfigReadPrefixPath("proxy.config.plugin.plugin_dir");
+}
+
+//-------------------------------------------------------------------------
 // RecConfigReadSnapshotDir.
 //-------------------------------------------------------------------------
-char *
+std::string
 RecConfigReadSnapshotDir()
 {
   return RecConfigReadConfigPath("proxy.config.snapshot_dir", "snapshots");
@@ -1200,10 +1207,10 @@ RecConfigReadSnapshotDir()
 //-------------------------------------------------------------------------
 // RecConfigReadConfigPath
 //-------------------------------------------------------------------------
-char *
+std::string
 RecConfigReadConfigPath(const char *file_variable, const char *default_value)
 {
-  ats_scoped_str sysconfdir(RecConfigReadConfigDir());
+  std::string sysconfdir(RecConfigReadConfigDir());
 
   // If the file name is in a configuration variable, look it up first ...
   if (file_variable) {
@@ -1221,13 +1228,13 @@ RecConfigReadConfigPath(const char *file_variable, const char *default_value)
     return Layout::get()->relative_to(sysconfdir, default_value);
   }
 
-  return nullptr;
+  return {};
 }
 
 //-------------------------------------------------------------------------
 // RecConfigReadPrefixPath
 //-------------------------------------------------------------------------
-char *
+std::string
 RecConfigReadPrefixPath(const char *file_variable, const char *default_value)
 {
   char buf[PATH_NAME_MAX];
@@ -1246,16 +1253,16 @@ RecConfigReadPrefixPath(const char *file_variable, const char *default_value)
     return Layout::get()->relative_to(Layout::get()->prefix, default_value);
   }
 
-  return nullptr;
+  return {};
 }
 
 //-------------------------------------------------------------------------
 // RecConfigReadPersistentStatsPath
 //-------------------------------------------------------------------------
-char *
+std::string
 RecConfigReadPersistentStatsPath()
 {
-  ats_scoped_str rundir(RecConfigReadRuntimeDir());
+  std::string rundir(RecConfigReadRuntimeDir());
   return Layout::relative_to(rundir, REC_RAW_STATS_FILE);
 }
 
diff --git a/lib/ts/I_Layout.h b/lib/ts/I_Layout.h
index 2be9b19..d23b07a 100644
--- a/lib/ts/I_Layout.h
+++ b/lib/ts/I_Layout.h
@@ -31,67 +31,44 @@
 #ifndef _I_Layout_h
 #define _I_Layout_h
 
+// use std string and string view for layout
+#include <string>
+#include "ts/string_view.h"
+
 /**
   The Layout is a simple place holder for the distribution layout.
 
  */
 struct Layout {
-  char *prefix;
-  char *exec_prefix;
-  char *bindir;
-  char *sbindir;
-  char *sysconfdir;
-  char *datadir;
-  char *includedir;
-  char *libdir;
-  char *libexecdir;
-  char *localstatedir;
-  char *sharedstatedir;
-  char *runtimedir;
-  char *logdir;
-  char *mandir;
-  char *infodir;
-  char *cachedir;
-
-  Layout(const char *prefix = 0);
+  Layout(ts::string_view const _prefix = {});
   ~Layout();
 
   /**
    Return file path relative to Layout->prefix
-   Memory is allocated, so use ats_free() when no longer needed
 
   */
-  char *relative(const char *file);
+  std::string relative(ts::string_view file);
 
   /**
    update the sysconfdir to a test conf dir
-   */
-  void update_sysconfdir(const char *dir);
-
-  /**
-   Return file path relative to Layout->prefix
-   Store the path to buf. The buf should be large eough to store
-   PATH_NAME_MAX characters
 
    */
-  void relative(char *buf, size_t bufsz, const char *file);
+  void update_sysconfdir(ts::string_view dir);
 
   /**
    Return file path relative to dir
-   Memory is allocated, so use ats_free() when no longer needed
    Example usage: Layout::relative_to(default_layout()->sysconfdir, "foo.bar");
 
   */
-  static char *relative_to(const char *dir, const char *file);
+  static std::string relative_to(ts::string_view dir, ts::string_view file);
 
   /**
    Return file path relative to dir
    Store the path to buf. The buf should be large eough to store
-   PATH_NAME_MAX characters
    Example usage: Layout::relative_to(default_layout()->sysconfdir, "foo.bar");
 
   */
-  static void relative_to(char *buf, size_t bufsz, const char *dir, const char *file);
+  static void relative_to(char *buf, size_t bufsz, ts::string_view dir, ts::string_view file);
 
   /**
    Creates a Layout Object with the given prefix.  If no
@@ -99,13 +76,29 @@ struct Layout {
    at the compile time.
 
   */
-  static void create(const char *prefix = 0);
+  static void create(ts::string_view const prefix = {});
 
   /**
    Returns the Layout object created by create_default_layout().
 
   */
   static Layout *get();
+
+  std::string prefix;
+  std::string exec_prefix;
+  std::string bindir;
+  std::string sbindir;
+  std::string sysconfdir;
+  std::string datadir;
+  std::string includedir;
+  std::string libdir;
+  std::string libexecdir;
+  std::string localstatedir;
+  std::string runtimedir;
+  std::string logdir;
+  std::string mandir;
+  std::string infodir;
+  std::string cachedir;
 };
 
 #endif
diff --git a/lib/ts/Layout.cc b/lib/ts/Layout.cc
index 483dcf1..cb3c7d8 100644
--- a/lib/ts/Layout.cc
+++ b/lib/ts/Layout.cc
@@ -41,134 +41,95 @@ Layout::get()
 }
 
 void
-Layout::create(const char *prefix)
+Layout::create(ts::string_view const prefix)
 {
   if (layout == nullptr) {
     layout = new Layout(prefix);
   }
 }
 
-static char *
-layout_relative(const char *root, const char *file)
+static void
+_relative(char *path, size_t buffsz, ts::string_view root, ts::string_view file)
 {
-  char path[PATH_NAME_MAX];
-
-  if (ink_filepath_merge(path, PATH_NAME_MAX, root, file, INK_FILEPATH_TRUENAME)) {
+  if (ink_filepath_merge(path, buffsz, root.data(), file.data(), INK_FILEPATH_TRUENAME)) {
     int err = errno;
     // Log error
     if (err == EACCES) {
-      ink_error("Cannot merge path '%s' above the root '%s'\n", file, root);
+      ink_fatal("Cannot merge path '%s' above the root '%s'\n", file.data(), root.data());
     } else if (err == E2BIG) {
-      ink_error("Exceeding file name length limit of %d characters\n", PATH_NAME_MAX);
+      ink_fatal("Exceeding file name length limit of %d characters\n", PATH_NAME_MAX);
     } else {
       // TODO: Make some pretty errors.
-      ink_error("Cannot merge '%s' with '%s' error=%d\n", file, root, err);
+      ink_fatal("Cannot merge '%s' with '%s' error=%d\n", file.data(), root.data(), err);
     }
-    return nullptr;
   }
-  return ats_strdup(path);
 }
 
-char *
-Layout::relative(const char *file)
+static std::string
+layout_relative(ts::string_view root, ts::string_view file)
 {
-  return layout_relative(prefix, file);
+  char path[PATH_NAME_MAX];
+  std::string ret;
+  _relative(path, PATH_NAME_MAX, root, file);
+  ret = path;
+  return ret;
 }
 
-void
-Layout::relative(char *buf, size_t bufsz, const char *file)
+std::string
+Layout::relative(ts::string_view file)
 {
-  char path[PATH_NAME_MAX];
-
-  if (ink_filepath_merge(path, PATH_NAME_MAX, prefix, file, INK_FILEPATH_TRUENAME)) {
-    int err = errno;
-    // Log error
-    if (err == EACCES) {
-      ink_error("Cannot merge path '%s' above the root '%s'\n", file, prefix);
-    } else if (err == E2BIG) {
-      ink_error("Exceeding file name length limit of %d characters\n", PATH_NAME_MAX);
-    } else {
-      // TODO: Make some pretty errors.
-      ink_error("Cannot merge '%s' with '%s' error=%d\n", file, prefix, err);
-    }
-    return;
-  }
-  size_t path_len = strlen(path) + 1;
-  if (path_len > bufsz) {
-    ink_error("Provided buffer is too small: %zu, required %zu\n", bufsz, path_len);
-  } else {
-    ink_strlcpy(buf, path, bufsz);
-  }
+  return layout_relative(prefix, file);
 }
 
+// for updating the structure sysconfdir
 void
-Layout::update_sysconfdir(const char *dir)
+Layout::update_sysconfdir(ts::string_view dir)
 {
-  if (sysconfdir) {
-    ats_free(sysconfdir);
-  }
-
-  sysconfdir = ats_strdup(dir);
+  sysconfdir.assign(dir.data(), dir.size());
 }
 
-char *
-Layout::relative_to(const char *dir, const char *file)
+std::string
+Layout::relative_to(ts::string_view dir, ts::string_view file)
 {
   return layout_relative(dir, file);
 }
 
 void
-Layout::relative_to(char *buf, size_t bufsz, const char *dir, const char *file)
+Layout::relative_to(char *buf, size_t bufsz, ts::string_view dir, ts::string_view file)
 {
   char path[PATH_NAME_MAX];
 
-  if (ink_filepath_merge(path, PATH_NAME_MAX, dir, file, INK_FILEPATH_TRUENAME)) {
-    int err = errno;
-    // Log error
-    if (err == EACCES) {
-      ink_error("Cannot merge path '%s' above the root '%s'\n", file, dir);
-    } else if (err == E2BIG) {
-      ink_error("Exceeding file name length limit of %d characters\n", PATH_NAME_MAX);
-    } else {
-      // TODO: Make some pretty errors.
-      ink_error("Cannot merge '%s' with '%s' error=%d\n", file, dir, err);
-    }
-    return;
-  }
+  _relative(path, PATH_NAME_MAX, dir, file);
   size_t path_len = strlen(path) + 1;
   if (path_len > bufsz) {
-    ink_error("Provided buffer is too small: %zu, required %zu\n", bufsz, path_len);
+    ink_fatal("Provided buffer is too small: %zu, required %zu\n", bufsz, path_len);
   } else {
     ink_strlcpy(buf, path, bufsz);
   }
 }
 
-Layout::Layout(const char *_prefix)
+Layout::Layout(ts::string_view const _prefix)
 {
-  if (_prefix) {
-    prefix = ats_strdup(_prefix);
+  if (_prefix.size() != 0) {
+    prefix.assign(_prefix.data(), _prefix.size());
   } else {
-    char *env_path;
-    char path[PATH_NAME_MAX];
+    std::string path;
     int len;
-
-    if ((env_path = getenv("TS_ROOT"))) {
-      len = strlen(env_path);
+    if (getenv("TS_ROOT") != nullptr) {
+      std::string env_path(getenv("TS_ROOT"));
+      len = env_path.size();
       if ((len + 1) > PATH_NAME_MAX) {
-        ink_error("TS_ROOT environment variable is too big: %d, max %d\n", len, PATH_NAME_MAX - 1);
-        return;
+        ink_fatal("TS_ROOT environment variable is too big: %d, max %d\n", len, PATH_NAME_MAX - 1);
       }
-      ink_strlcpy(path, env_path, sizeof(path));
-      while (len > 1 && path[len - 1] == '/') {
-        path[len - 1] = '\0';
-        --len;
+      path = env_path;
+      while (path.back() == '/') {
+        path.pop_back();
       }
     } else {
       // Use compile time --prefix
-      ink_strlcpy(path, TS_BUILD_PREFIX, sizeof(path));
+      path = TS_BUILD_PREFIX;
     }
-
-    prefix = ats_strdup(path);
+    prefix = path;
   }
   exec_prefix   = layout_relative(prefix, TS_BUILD_EXEC_PREFIX);
   bindir        = layout_relative(prefix, TS_BUILD_BINDIR);
@@ -188,19 +149,4 @@ Layout::Layout(const char *_prefix)
 
 Layout::~Layout()
 {
-  ats_free(prefix);
-  ats_free(exec_prefix);
-  ats_free(bindir);
-  ats_free(sbindir);
-  ats_free(sysconfdir);
-  ats_free(datadir);
-  ats_free(includedir);
-  ats_free(libdir);
-  ats_free(libexecdir);
-  ats_free(localstatedir);
-  ats_free(runtimedir);
-  ats_free(logdir);
-  ats_free(mandir);
-  ats_free(infodir);
-  ats_free(cachedir);
 }
diff --git a/lib/ts/ink_memory.h b/lib/ts/ink_memory.h
index 4276b2f..b659025 100644
--- a/lib/ts/ink_memory.h
+++ b/lib/ts/ink_memory.h
@@ -122,6 +122,16 @@ static inline size_t __attribute__((const)) ats_pagesize(void)
 char *_xstrdup(const char *str, int length, const char *path);
 
 #define ats_strdup(p) _xstrdup((p), -1, nullptr)
+
+// this is to help with migration to a std::string issue with older code that
+// expects char* being copied. As more code moves to std::string, this can be
+// removed to avoid these extra copies.
+inline char *
+ats_stringdup(std::string const &p)
+{
+  return p.empty() ? nullptr : _xstrdup(p.c_str(), p.size(), nullptr);
+}
+
 #define ats_strndup(p, n) _xstrdup((p), n, nullptr)
 
 #ifdef __cplusplus
diff --git a/lib/ts/unit-tests/test_layout.cpp b/lib/ts/unit-tests/test_layout.cpp
new file mode 100644
index 0000000..59facae
--- /dev/null
+++ b/lib/ts/unit-tests/test_layout.cpp
@@ -0,0 +1,89 @@
+/** @file
+  Test file for layout structure
+  @section license License
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+      http://www.apache.org/licenses/LICENSE-2.0
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#include "catch.hpp"
+
+#include "ts/I_Layout.h"
+#include "ts/ink_platform.h"
+
+std::string
+append_slash(const char *path)
+{
+  std::string ret(path);
+  if (ret.back() != '/')
+    ret.append("/");
+  return ret;
+}
+
+// test cases: [constructor], [env_constructor], [create], [relative], [relative_to], [update_sysconfdir]
+// ======= test for layout ========
+
+TEST_CASE("constructor test", "[constructor]")
+{
+  Layout layout;
+  // test for constructor
+  REQUIRE(layout.prefix == TS_BUILD_PREFIX);
+  REQUIRE(layout.sysconfdir == layout.relative(TS_BUILD_SYSCONFDIR));
+}
+
+TEST_CASE("environment variable constructor test", "[env_constructor]")
+{
+  std::string newpath = append_slash(TS_BUILD_PREFIX) + "env";
+  setenv("TS_ROOT", newpath.c_str(), true);
+
+  Layout layout;
+  REQUIRE(layout.prefix == newpath);
+  REQUIRE(layout.sysconfdir == layout.relative_to(newpath, TS_BUILD_SYSCONFDIR));
+  unsetenv("TS_ROOT");
+}
+
+TEST_CASE("layout create test", "[create]")
+{
+  Layout::create();
+  REQUIRE(Layout::get()->prefix == TS_BUILD_PREFIX);
+  REQUIRE(Layout::get()->sysconfdir == Layout::get()->relative(TS_BUILD_SYSCONFDIR));
+}
+
+// tests below based on the created layout
+TEST_CASE("relative test", "[relative]")
+{
+  // relative (1 argument)
+  ts::string_view sv("file");
+  std::string str1 = append_slash(TS_BUILD_PREFIX) + "file";
+  REQUIRE(Layout::get()->relative(sv) == str1);
+}
+
+TEST_CASE("relative to test", "[relative_to]")
+{
+  // relative to (2 parameters)
+  std::string str1 = append_slash(TS_BUILD_PREFIX) + "file";
+  REQUIRE(Layout::relative_to(Layout::get()->prefix, "file") == str1);
+
+  // relative to (4 parameters)
+  char config_file[PATH_NAME_MAX];
+  Layout::relative_to(config_file, sizeof(config_file), Layout::get()->sysconfdir, "records.config");
+  std::string a = Layout::relative_to(Layout::get()->sysconfdir, "records.config");
+  std::string b = config_file;
+  REQUIRE(a == b);
+}
+
+TEST_CASE("update_sysconfdir test", "[update_sysconfdir]")
+{
+  Layout::get()->update_sysconfdir("/abc");
+  REQUIRE(Layout::get()->sysconfdir == "/abc");
+}
diff --git a/mgmt/Alarms.cc b/mgmt/Alarms.cc
index bf549c0..4cdc2ec 100644
--- a/mgmt/Alarms.cc
+++ b/mgmt/Alarms.cc
@@ -73,7 +73,7 @@ alarm_script_dir()
     return path;
   }
 
-  return RecConfigReadBinDir();
+  return ats_stringdup(RecConfigReadBinDir());
 }
 
 Alarms::Alarms()
diff --git a/mgmt/FileManager.cc b/mgmt/FileManager.cc
index bdbd23c..df92f1b 100644
--- a/mgmt/FileManager.cc
+++ b/mgmt/FileManager.cc
@@ -593,7 +593,7 @@ FileManager::WalkSnaps(ExpandingArray *snapList)
   MFresult r;
 
   // Make sure managedDir is the latest from proxy.config.snapshot_dir.
-  this->managedDir = RecConfigReadSnapshotDir();
+  this->managedDir = ats_stringdup(RecConfigReadSnapshotDir());
 
   ink_mutex_acquire(&accessLock);
 
diff --git a/mgmt/LocalManager.cc b/mgmt/LocalManager.cc
index b27dd7b..7ff715c 100644
--- a/mgmt/LocalManager.cc
+++ b/mgmt/LocalManager.cc
@@ -179,9 +179,9 @@ LocalManager::processRunning()
 LocalManager::LocalManager(bool proxy_on) : BaseManager(), run_proxy(proxy_on), configFiles(nullptr)
 {
   bool found;
-  ats_scoped_str rundir(RecConfigReadRuntimeDir());
-  ats_scoped_str bindir(RecConfigReadBinDir());
-  ats_scoped_str sysconfdir(RecConfigReadConfigDir());
+  std::string rundir(RecConfigReadRuntimeDir());
+  std::string bindir(RecConfigReadBinDir());
+  std::string sysconfdir(RecConfigReadConfigDir());
 
   syslog_facility = 0;
 
@@ -208,8 +208,8 @@ LocalManager::LocalManager(bool proxy_on) : BaseManager(), run_proxy(proxy_on),
   // Get the default IP binding values.
   RecHttpLoadIp("proxy.local.incoming_ip_to_bind", m_inbound_ip4, m_inbound_ip6);
 
-  if (access(sysconfdir, R_OK) == -1) {
-    mgmt_log("[LocalManager::LocalManager] unable to access() directory '%s': %d, %s\n", (const char *)sysconfdir, errno,
+  if (access(sysconfdir.c_str(), R_OK) == -1) {
+    mgmt_log("[LocalManager::LocalManager] unable to access() directory '%s': %d, %s\n", sysconfdir.c_str(), errno,
              strerror(errno));
     mgmt_fatal(0, "[LocalManager::LocalManager] please set the 'TS_ROOT' environment variable\n");
   }
@@ -247,7 +247,7 @@ LocalManager::LocalManager(bool proxy_on) : BaseManager(), run_proxy(proxy_on),
   proxy_options                = nullptr;
 
   // Calculate proxy_binary from the absolute bin_path
-  absolute_proxy_binary = Layout::relative_to(bindir, proxy_binary);
+  absolute_proxy_binary = ats_stringdup(Layout::relative_to(bindir, proxy_binary));
 
   // coverity[fs_check_call]
   if (access(absolute_proxy_binary, R_OK | X_OK) == -1) {
@@ -357,8 +357,8 @@ LocalManager::initCCom(const AppVersionInfo &version, FileManager *configFiles,
 void
 LocalManager::initMgmtProcessServer()
 {
-  ats_scoped_str rundir(RecConfigReadRuntimeDir());
-  ats_scoped_str sockpath(Layout::relative_to(rundir, LM_CONNECTION_SERVER));
+  std::string rundir(RecConfigReadRuntimeDir());
+  std::string sockpath(Layout::relative_to(rundir, LM_CONNECTION_SERVER));
   mode_t oldmask = umask(0);
 
 #if TS_HAS_WCCP
@@ -368,9 +368,9 @@ LocalManager::initMgmtProcessServer()
   }
 #endif
 
-  process_server_sockfd = bind_unix_domain_socket(sockpath, 00700);
+  process_server_sockfd = bind_unix_domain_socket(sockpath.c_str(), 00700);
   if (process_server_sockfd == -1) {
-    mgmt_fatal(errno, "[LocalManager::initMgmtProcessServer] failed to bind socket at %s\n", (const char *)sockpath);
+    mgmt_fatal(errno, "[LocalManager::initMgmtProcessServer] failed to bind socket at %s\n", sockpath.c_str());
   }
 
   umask(oldmask);
@@ -913,9 +913,9 @@ LocalManager::startProxy(const char *onetime_options)
       int res;
 
       char env_prep_bin[MAXPATHLEN];
-      ats_scoped_str bindir(RecConfigReadBinDir());
+      std::string bindir(RecConfigReadBinDir());
 
-      ink_filepath_make(env_prep_bin, sizeof(env_prep_bin), bindir, env_prep);
+      ink_filepath_make(env_prep_bin, sizeof(env_prep_bin), bindir.c_str(), env_prep);
       res = execl(env_prep_bin, env_prep_bin, (char *)nullptr);
       _exit(res);
     }
diff --git a/mgmt/ProcessManager.cc b/mgmt/ProcessManager.cc
index cd7c714..3addf5b 100644
--- a/mgmt/ProcessManager.cc
+++ b/mgmt/ProcessManager.cc
@@ -178,8 +178,8 @@ ProcessManager::processSignalQueue()
 void
 ProcessManager::initLMConnection()
 {
-  ats_scoped_str rundir(RecConfigReadRuntimeDir());
-  ats_scoped_str sockpath(Layout::relative_to(rundir, LM_CONNECTION_SERVER));
+  std::string rundir(RecConfigReadRuntimeDir());
+  std::string sockpath(Layout::relative_to(rundir, LM_CONNECTION_SERVER));
 
   MgmtMessageHdr *mh_full;
   int data_len;
@@ -191,7 +191,7 @@ ProcessManager::initLMConnection()
   memset((char *)&serv_addr, 0, sizeof(serv_addr));
   serv_addr.sun_family = AF_UNIX;
 
-  ink_strlcpy(serv_addr.sun_path, sockpath, sizeof(serv_addr.sun_path));
+  ink_strlcpy(serv_addr.sun_path, sockpath.c_str(), sizeof(serv_addr.sun_path));
 #if defined(darwin) || defined(freebsd)
   servlen = sizeof(sockaddr_un);
 #else
diff --git a/mgmt/Rollback.cc b/mgmt/Rollback.cc
index 31d3f75..17dfc3c 100644
--- a/mgmt/Rollback.cc
+++ b/mgmt/Rollback.cc
@@ -233,8 +233,8 @@ Rollback::createPathStr(version_t version)
 {
   int bufSize  = 0;
   char *buffer = nullptr;
-  ats_scoped_str sysconfdir(RecConfigReadConfigDir());
-  bufSize = strlen(sysconfdir) + fileNameLen + MAX_VERSION_DIGITS + 1;
+  std::string sysconfdir(RecConfigReadConfigDir());
+  bufSize = sysconfdir.size() + fileNameLen + MAX_VERSION_DIGITS + 1;
   buffer  = (char *)ats_malloc(bufSize);
   Layout::get()->relative_to(buffer, bufSize, sysconfdir, fileName);
   if (version != ACTIVE_VERSION) {
diff --git a/mgmt/api/CoreAPIRemote.cc b/mgmt/api/CoreAPIRemote.cc
index 32e7ac1..caf57ad 100644
--- a/mgmt/api/CoreAPIRemote.cc
+++ b/mgmt/api/CoreAPIRemote.cc
@@ -196,7 +196,7 @@ Init(const char *socket_path, TSInitOptionT options)
   // libraries. The caller has to pass down the right socket path :(
   if (!socket_path) {
     Layout::create();
-    socket_path = Layout::get()->runtimedir;
+    socket_path = Layout::get()->runtimedir.c_str();
   }
 
   // store socket_path
diff --git a/mgmt/api/NetworkUtilsRemote.cc b/mgmt/api/NetworkUtilsRemote.cc
index 740ae46..d0c7152 100644
--- a/mgmt/api/NetworkUtilsRemote.cc
+++ b/mgmt/api/NetworkUtilsRemote.cc
@@ -57,8 +57,8 @@ set_socket_paths(const char *path)
   // construct paths based on user input
   // form by replacing "mgmtapi.sock" with "eventapi.sock"
   if (path) {
-    main_socket_path  = Layout::relative_to(path, MGMTAPI_MGMT_SOCKET_NAME);
-    event_socket_path = Layout::relative_to(path, MGMTAPI_EVENT_SOCKET_NAME);
+    main_socket_path  = ats_stringdup(Layout::relative_to(path, MGMTAPI_MGMT_SOCKET_NAME));
+    event_socket_path = ats_stringdup(Layout::relative_to(path, MGMTAPI_EVENT_SOCKET_NAME));
   } else {
     main_socket_path  = nullptr;
     event_socket_path = nullptr;
diff --git a/proxy/Crash.cc b/proxy/Crash.cc
index b99abde..366d5fd 100644
--- a/proxy/Crash.cc
+++ b/proxy/Crash.cc
@@ -40,7 +40,7 @@ static char *
 create_logger_path()
 {
   RecString name;
-  ats_scoped_str bindir;
+  std::string bindir;
   ats_scoped_str fullpath;
 
   if (RecGetRecordString_Xmalloc("proxy.config.crash_log_helper", &name) != REC_ERR_OKAY) {
diff --git a/proxy/InkAPI.cc b/proxy/InkAPI.cc
index 15fbe00..a23427f 100644
--- a/proxy/InkAPI.cc
+++ b/proxy/InkAPI.cc
@@ -1763,21 +1763,22 @@ TShrtime()
 const char *
 TSInstallDirGet(void)
 {
-  return Layout::get()->prefix;
+  static std::string prefix = Layout::get()->prefix;
+  return prefix.c_str();
 }
 
 const char *
 TSConfigDirGet(void)
 {
-  static const char *sysconfdir = RecConfigReadConfigDir();
-  return sysconfdir;
+  static std::string sysconfdir = RecConfigReadConfigDir();
+  return sysconfdir.c_str();
 }
 
 const char *
 TSRuntimeDirGet(void)
 {
-  static const char *runtimedir = RecConfigReadRuntimeDir();
-  return runtimedir;
+  static std::string runtimedir = RecConfigReadRuntimeDir();
+  return runtimedir.c_str();
 }
 
 const char *
@@ -1805,8 +1806,8 @@ TSTrafficServerVersionGetPatch()
 const char *
 TSPluginDirGet(void)
 {
-  static const char *path = RecConfigReadPrefixPath("proxy.config.plugin.plugin_dir");
-  return path;
+  static std::string path = RecConfigReadPluginDir();
+  return path.c_str();
 }
 
 ////////////////////////////////////////////////////////////////////
diff --git a/proxy/Main.cc b/proxy/Main.cc
index 8d13f26..eae8db0 100644
--- a/proxy/Main.cc
+++ b/proxy/Main.cc
@@ -485,19 +485,19 @@ init_system()
 static void
 check_lockfile()
 {
-  ats_scoped_str rundir(RecConfigReadRuntimeDir());
-  ats_scoped_str lockfile;
+  std::string rundir(RecConfigReadRuntimeDir());
+  std::string lockfile;
   pid_t holding_pid;
   int err;
 
   lockfile = Layout::relative_to(rundir, SERVER_LOCK);
 
-  Lockfile server_lockfile(lockfile);
+  Lockfile server_lockfile(lockfile.c_str());
   err = server_lockfile.Get(&holding_pid);
 
   if (err != 1) {
     char *reason = strerror(-err);
-    fprintf(stderr, "WARNING: Can't acquire lockfile '%s'", (const char *)lockfile);
+    fprintf(stderr, "WARNING: Can't acquire lockfile '%s'", lockfile.c_str());
 
     if ((err == 0) && (holding_pid != -1)) {
       fprintf(stderr, " (Lock file held by process ID %ld)\n", (long)holding_pid);
@@ -515,17 +515,17 @@ check_lockfile()
 static void
 check_config_directories()
 {
-  ats_scoped_str rundir(RecConfigReadRuntimeDir());
-  ats_scoped_str sysconfdir(RecConfigReadConfigDir());
+  std::string rundir(RecConfigReadRuntimeDir());
+  std::string sysconfdir(RecConfigReadConfigDir());
 
-  if (access(sysconfdir, R_OK) == -1) {
-    fprintf(stderr, "unable to access() config dir '%s': %d, %s\n", (const char *)sysconfdir, errno, strerror(errno));
+  if (access(sysconfdir.c_str(), R_OK) == -1) {
+    fprintf(stderr, "unable to access() config dir '%s': %d, %s\n", sysconfdir.c_str(), errno, strerror(errno));
     fprintf(stderr, "please set the 'TS_ROOT' environment variable\n");
     ::exit(1);
   }
 
-  if (access(rundir, R_OK | W_OK) == -1) {
-    fprintf(stderr, "unable to access() local state dir '%s': %d, %s\n", (const char *)rundir, errno, strerror(errno));
+  if (access(rundir.c_str(), R_OK | W_OK) == -1) {
+    fprintf(stderr, "unable to access() local state dir '%s': %d, %s\n", rundir.c_str(), errno, strerror(errno));
     fprintf(stderr, "please set 'proxy.config.local_state_dir'\n");
     ::exit(1);
   }
@@ -742,12 +742,12 @@ cmd_clear(char *cmd)
   bool c_cache = !strcmp(cmd, "clear_cache");
 
   if (c_all || c_hdb) {
-    ats_scoped_str rundir(RecConfigReadRuntimeDir());
-    ats_scoped_str config(Layout::relative_to(rundir, "hostdb.config"));
+    std::string rundir(RecConfigReadRuntimeDir());
+    std::string config(Layout::relative_to(rundir, "hostdb.config"));
 
     Note("Clearing HostDB Configuration");
-    if (unlink(config) < 0) {
-      Note("unable to unlink %s", (const char *)config);
+    if (unlink(config.c_str()) < 0) {
+      Note("unable to unlink %s", config.c_str());
     }
   }
 
@@ -1357,15 +1357,15 @@ run_RegressionTest()
 static void
 chdir_root()
 {
-  const char *prefix = Layout::get()->prefix;
+  std::string prefix = Layout::get()->prefix;
 
-  if (chdir(prefix) < 0) {
-    fprintf(stderr, "%s: unable to change to root directory \"%s\" [%d '%s']\n", appVersionInfo.AppStr, prefix, errno,
+  if (chdir(prefix.c_str()) < 0) {
+    fprintf(stderr, "%s: unable to change to root directory \"%s\" [%d '%s']\n", appVersionInfo.AppStr, prefix.c_str(), errno,
             strerror(errno));
     fprintf(stderr, "%s: please correct the path or set the TS_ROOT environment variable\n", appVersionInfo.AppStr);
     ::exit(1);
   } else {
-    printf("%s: using root directory '%s'\n", appVersionInfo.AppStr, prefix);
+    printf("%s: using root directory '%s'\n", appVersionInfo.AppStr, prefix.c_str());
   }
 }
 
diff --git a/proxy/Plugin.cc b/proxy/Plugin.cc
index c8b9107..250edf1 100644
--- a/proxy/Plugin.cc
+++ b/proxy/Plugin.cc
@@ -231,8 +231,7 @@ plugin_init(bool validateOnly)
 
   if (INIT_ONCE) {
     api_init();
-    TSConfigDirGet();
-    plugin_dir = TSPluginDirGet();
+    plugin_dir = ats_stringdup(RecConfigReadPluginDir());
     INIT_ONCE  = false;
   }
 
diff --git a/proxy/http/remap/RemapConfig.cc b/proxy/http/remap/RemapConfig.cc
index 1f43d4a..d528c1f 100644
--- a/proxy/http/remap/RemapConfig.cc
+++ b/proxy/http/remap/RemapConfig.cc
@@ -337,7 +337,7 @@ parse_include_directive(const char *directive, BUILD_TABLE_INFO *bti, char *errb
           continue;
         }
 
-        subpath = Layout::relative_to(path, entrylist[j]->d_name);
+        subpath = Layout::relative_to(path.get(), entrylist[j]->d_name);
 
         if (ink_file_is_directory(subpath)) {
           continue;
diff --git a/proxy/logging/LogConfig.cc b/proxy/logging/LogConfig.cc
index 1461599..86ed11b 100644
--- a/proxy/logging/LogConfig.cc
+++ b/proxy/logging/LogConfig.cc
@@ -163,7 +163,7 @@ LogConfig::read_configuration_variables()
   }
 
   ats_free(logfile_dir);
-  logfile_dir = RecConfigReadLogDir();
+  logfile_dir = ats_stringdup(RecConfigReadLogDir());
 
   if (access(logfile_dir, R_OK | W_OK | X_OK) == -1) {
     // Try 'system_root_dir/var/log/trafficserver' directory
diff --git a/proxy/logging/LogStandalone.cc b/proxy/logging/LogStandalone.cc
index 1102c59..d2091b3 100644
--- a/proxy/logging/LogStandalone.cc
+++ b/proxy/logging/LogStandalone.cc
@@ -148,12 +148,12 @@ check_lockfile()
   pid_t holding_pid;
   char *lockfile = nullptr;
 
-  if (access(Layout::get()->runtimedir, R_OK | W_OK) == -1) {
-    fprintf(stderr, "unable to access() dir'%s': %d, %s\n", Layout::get()->runtimedir, errno, strerror(errno));
+  if (access(Layout::get()->runtimedir.c_str(), R_OK | W_OK) == -1) {
+    fprintf(stderr, "unable to access() dir'%s': %d, %s\n", Layout::get()->runtimedir.c_str(), errno, strerror(errno));
     fprintf(stderr, " please set correct path in env variable TS_ROOT \n");
     ::exit(1);
   }
-  lockfile = Layout::relative_to(Layout::get()->runtimedir, SERVER_LOCK);
+  lockfile = ats_stringdup(Layout::relative_to(Layout::get()->runtimedir, SERVER_LOCK));
 
   Lockfile server_lockfile(lockfile);
   err = server_lockfile.Get(&holding_pid);
diff --git a/proxy/logstats.cc b/proxy/logstats.cc
index ff1ea11..8d9a1fa 100644
--- a/proxy/logstats.cc
+++ b/proxy/logstats.cc
@@ -2471,7 +2471,7 @@ main(int /* argc ATS_UNUSED */, const char *argv[])
         if (end > start) {
           char *buf;
 
-          buf = ats_strdup(line.substr(start, end).c_str());
+          buf = ats_stringdup(line.substr(start, end));
           if (buf) {
             origin_set->insert(buf);
           }
@@ -2499,7 +2499,7 @@ main(int /* argc ATS_UNUSED */, const char *argv[])
   // Do the incremental parse of the default squid log.
   if (cl.incremental) {
     // Change directory to the log dir
-    if (chdir(Layout::get()->logdir) < 0) {
+    if (chdir(Layout::get()->logdir.c_str()) < 0) {
       exit_status.set(EXIT_CRITICAL, " can't chdir to ");
       exit_status.append(Layout::get()->logdir);
       my_exit(exit_status);
@@ -2602,8 +2602,8 @@ main(int /* argc ATS_UNUSED */, const char *argv[])
       last_state.st_ino = stat_buf.st_ino;
 
       // Find the old log file.
-      dirp = opendir(Layout::get()->logdir);
-      if (NULL == dirp) {
+      dirp = opendir(Layout::get()->logdir.c_str());
+      if (nullptr == dirp) {
         exit_status.set(EXIT_WARNING, " can't read log directory");
       } else {
         while ((dp = readdir(dirp)) != NULL) {

-- 
To stop receiving notification emails like this one, please contact
"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>.