aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorQyriad <qyriad@qyriad.me>2024-07-12 16:15:33 -0600
committerQyriad <qyriad@qyriad.me>2024-07-15 15:26:53 -0600
commitd9c51ec4e5919245dcc5e9f2f5532f4d85be5218 (patch)
tree4727d01f8fdffb5dd411645135637c91478f04a3 /src
parent1eb5d22132a57487e0cb84a65ecd35814624c0e5 (diff)
libutil: implement a realPath() utility
Just a wrapper around POSIX realpath(). Change-Id: I2593770285dbae573eace490efce5b272b00b001
Diffstat (limited to 'src')
-rw-r--r--src/libutil/file-system.cc19
-rw-r--r--src/libutil/file-system.hh16
2 files changed, 35 insertions, 0 deletions
diff --git a/src/libutil/file-system.cc b/src/libutil/file-system.cc
index 278e5187c..f0199d36f 100644
--- a/src/libutil/file-system.cc
+++ b/src/libutil/file-system.cc
@@ -1,4 +1,5 @@
#include <sys/time.h>
+#include <cstdlib>
#include <filesystem>
#include <atomic>
@@ -106,6 +107,24 @@ Path canonPath(PathView path, bool resolveSymlinks)
return s.empty() ? "/" : std::move(s);
}
+Path realPath(Path const & path)
+{
+ // With nullptr, realpath() malloc's and returns a new c-string.
+ char * resolved = realpath(path.c_str(), nullptr);
+ int saved = errno;
+ if (resolved == nullptr) {
+ throw SysError(saved, "cannot get realpath for '%s'", path);
+ }
+
+ Finally const _free([&] { free(resolved); });
+
+ // There's not really a from_raw_parts() for std::string.
+ // The copy is not a big deal.
+ Path ret(resolved);
+
+ return ret;
+}
+
void chmodPath(const Path & path, mode_t mode)
{
if (chmod(path.c_str(), mode) == -1)
diff --git a/src/libutil/file-system.hh b/src/libutil/file-system.hh
index 636c13f13..e49323e84 100644
--- a/src/libutil/file-system.hh
+++ b/src/libutil/file-system.hh
@@ -47,6 +47,22 @@ Path absPath(Path path,
Path canonPath(PathView path, bool resolveSymlinks = false);
/**
+ * Resolves a file path to a fully absolute path with no symbolic links.
+ *
+ * @param path The path to resolve. If it is relative, it will be resolved relative
+ * to the process's current directory.
+ *
+ * @note This is not a pure function; it performs this resolution by querying
+ * the filesystem.
+ *
+ * @note @ref path sadly must be (a reference to) an owned string, as std::string_view
+ * are not valid C strings...
+ *
+ * @return The fully resolved path.
+ */
+Path realPath(Path const & path);
+
+/**
* Change the permissions of a path
* Not called `chmod` as it shadows and could be confused with
* `int chmod(char *, mode_t)`, which does not handle errors