AbsolutePath() is good if file doesn't exist

Instead of converting the whole path, relative paths are prefixed with
the absolute path of the current directory from realpath(".")

Bug: 111640251
Bug: 111522903
Test: local boot with empty ~/cuttlefish_runtime
Change-Id: I67fa3a11e048ef967bb96ef647ac4dd32663afb1
diff --git a/common/libs/utils/files.cpp b/common/libs/utils/files.cpp
index 85c7ef7..1eb91d8 100644
--- a/common/libs/utils/files.cpp
+++ b/common/libs/utils/files.cpp
@@ -49,14 +49,21 @@
   return true;
 }
 
-std::string RealPath(const std::string& path) {
-  std::array<char, PATH_MAX> buffer{};
-  if (!realpath(path.c_str(), buffer.data())) {
-    LOG(WARNING) << "Could not get real path for file " << path << ": "
-                 << strerror(errno);
+std::string AbsolutePath(const std::string& path) {
+  if (path.empty()) {
     return {};
   }
-  return {buffer.data()};
+  if (path[0] == '/') {
+    return path;
+  }
+
+  std::array<char, PATH_MAX> buffer{};
+  if (!realpath(".", buffer.data())) {
+    LOG(WARNING) << "Could not get real path for current directory \".\""
+                 << ": " << strerror(errno);
+    return {};
+  }
+  return std::string{buffer.data()} + "/" + path;
 }
 
 }  // namespace cvd
diff --git a/common/libs/utils/files.h b/common/libs/utils/files.h
index 51ba25e..07d5d2f 100644
--- a/common/libs/utils/files.h
+++ b/common/libs/utils/files.h
@@ -21,6 +21,8 @@
 bool FileHasContent(const std::string& path);
 bool DirectoryExists(const std::string& path);
 
-// returns empty string if realpath() fails
-std::string RealPath(const std::string& path);
+// The returned value may contain .. or . if these are present in the path
+// argument.
+// path must not contain ~
+std::string AbsolutePath(const std::string& path);
 }  // namespace cvd
diff --git a/host/libs/config/cuttlefish_config.cpp b/host/libs/config/cuttlefish_config.cpp
index 9104b54..7cb0194 100644
--- a/host/libs/config/cuttlefish_config.cpp
+++ b/host/libs/config/cuttlefish_config.cpp
@@ -162,9 +162,16 @@
   return (*dictionary_)[kKernelImagePath].asString();
 }
 
+void CuttlefishConfig::SetPath(const std::string& key,
+                               const std::string& path) {
+  if (!path.empty()) {
+    (*dictionary_)[key] = cvd::AbsolutePath(path);
+  }
+}
+
 void CuttlefishConfig::set_kernel_image_path(
     const std::string& kernel_image_path) {
-  (*dictionary_)[kKernelImagePath] = kernel_image_path;
+  SetPath(kKernelImagePath, kernel_image_path);
 }
 
 std::string CuttlefishConfig::gdb_flag() const {
@@ -173,7 +180,7 @@
 
 void CuttlefishConfig::set_gdb_flag(
     const std::string& device) {
-  (*dictionary_)[kGdbFlag] = device;
+  SetPath(kGdbFlag, device);
 }
 
 std::string CuttlefishConfig::kernel_args() const {
@@ -188,7 +195,7 @@
 }
 void CuttlefishConfig::set_ramdisk_image_path(
     const std::string& ramdisk_image_path) {
-  (*dictionary_)[kRamdiskImagePath] = ramdisk_image_path;
+  SetPath(kRamdiskImagePath, ramdisk_image_path);
 }
 
 std::string CuttlefishConfig::system_image_path() const {
@@ -196,7 +203,7 @@
 }
 void CuttlefishConfig::set_system_image_path(
     const std::string& system_image_path) {
-  (*dictionary_)[kSystemImagePath] = system_image_path;
+  SetPath(kSystemImagePath, system_image_path);
 }
 
 std::string CuttlefishConfig::cache_image_path() const {
@@ -204,14 +211,14 @@
 }
 void CuttlefishConfig::set_cache_image_path(
     const std::string& cache_image_path) {
-  (*dictionary_)[kCacheImagePath] = cache_image_path;
+  SetPath(kCacheImagePath, cache_image_path);
 }
 
 std::string CuttlefishConfig::data_image_path() const {
   return (*dictionary_)[kDataImagePath].asString();
 }
 void CuttlefishConfig::set_data_image_path(const std::string& data_image_path) {
-  (*dictionary_)[kDataImagePath] = data_image_path;
+  SetPath(kDataImagePath, data_image_path);
 }
 
 std::string CuttlefishConfig::vendor_image_path() const {
@@ -219,21 +226,21 @@
 }
 void CuttlefishConfig::set_vendor_image_path(
     const std::string& vendor_image_path) {
-  (*dictionary_)[kVendorImagePath] = vendor_image_path;
+  SetPath(kVendorImagePath, vendor_image_path);
 }
 
 std::string CuttlefishConfig::dtb_path() const {
   return (*dictionary_)[kDtbPath].asString();
 }
 void CuttlefishConfig::set_dtb_path(const std::string& dtb_path) {
-  (*dictionary_)[kDtbPath] = dtb_path;
+  SetPath(kDtbPath, dtb_path);
 }
 
 std::string CuttlefishConfig::mempath() const {
   return (*dictionary_)[kMempath].asString();
 }
 void CuttlefishConfig::set_mempath(const std::string& mempath) {
-  (*dictionary_)[kMempath] = mempath;
+  SetPath(kMempath, mempath);
 }
 
 std::string CuttlefishConfig::ivshmem_qemu_socket_path() const {
@@ -241,7 +248,7 @@
 }
 void CuttlefishConfig::set_ivshmem_qemu_socket_path(
     const std::string& ivshmem_qemu_socket_path) {
-  (*dictionary_)[kIvshmemQemuSocketPath] = ivshmem_qemu_socket_path;
+  SetPath(kIvshmemQemuSocketPath, ivshmem_qemu_socket_path);
 }
 
 std::string CuttlefishConfig::ivshmem_client_socket_path() const {
@@ -249,7 +256,7 @@
 }
 void CuttlefishConfig::set_ivshmem_client_socket_path(
     const std::string& ivshmem_client_socket_path) {
-  (*dictionary_)[kIvshmemClientSocketPath] = ivshmem_client_socket_path;
+  SetPath(kIvshmemClientSocketPath, ivshmem_client_socket_path);
 }
 
 int CuttlefishConfig::ivshmem_vector_count() const {
@@ -294,14 +301,14 @@
   return (*dictionary_)[kConsolePath].asString();
 }
 void CuttlefishConfig::set_console_path(const std::string& console_path) {
-  (*dictionary_)[kConsolePath] = console_path;
+  SetPath(kConsolePath, console_path);
 }
 
 std::string CuttlefishConfig::logcat_path() const {
   return (*dictionary_)[kLogcatPath].asString();
 }
 void CuttlefishConfig::set_logcat_path(const std::string& logcat_path) {
-  (*dictionary_)[kLogcatPath] = logcat_path;
+  SetPath(kLogcatPath, logcat_path);
 }
 
 std::string CuttlefishConfig::mobile_bridge_name() const {
@@ -372,7 +379,7 @@
 }
 
 void CuttlefishConfig::set_cuttlefish_env_path(const std::string& path) {
-  (*dictionary_)[kCuttlefishEnvPath] = path;
+  SetPath(kCuttlefishEnvPath, path);
 }
 std::string CuttlefishConfig::cuttlefish_env_path() const {
   return (*dictionary_)[kCuttlefishEnvPath].asString();
@@ -406,7 +413,7 @@
 }
 
 void CuttlefishConfig::LoadFromFile(const char* file) {
-  auto real_file_path = cvd::RealPath(file);
+  auto real_file_path = cvd::AbsolutePath(file);
   if (real_file_path.empty()) {
     LOG(FATAL) << "Could not get real path for file " << file;
   }
diff --git a/host/libs/config/cuttlefish_config.h b/host/libs/config/cuttlefish_config.h
index 9250b3e..cc2abfd 100644
--- a/host/libs/config/cuttlefish_config.h
+++ b/host/libs/config/cuttlefish_config.h
@@ -169,6 +169,7 @@
   std::unique_ptr<Json::Value> dictionary_;
 
   void LoadFromFile(const char* file);
+  void SetPath(const std::string& key, const std::string& path);
 
   CuttlefishConfig();
   CuttlefishConfig(const CuttlefishConfig&) = delete;