[llvm] r297483 - Add llvm::sys::fs::real_path.

Davide Italiano via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 8 18:21:18 PST 2018


On Fri, Mar 10, 2017 at 9:39 AM, Zachary Turner via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: zturner
> Date: Fri Mar 10 11:39:21 2017
> New Revision: 297483
>
> URL: http://llvm.org/viewvc/llvm-project?rev=297483&view=rev
> Log:
> Add llvm::sys::fs::real_path.
>
> LLVM already has real_path like functionality, but it is
> cumbersome to use and involves clean up after (e.g. you have
> to call openFileForRead, then close the resulting FD).
>
> Furthermore, on Windows it doesn't work for directories since
> opening a directory and opening a file require slightly
> different flags.
>
> So I add a simple function `real_path` which works for all
> paths on all platforms and has a simple to use interface.
>
> In doing so, I add the ability to opt in to resolving tilde
> expressions (e.g. ~/foo), which are normally handled by
> the shell.
>
>

Apologies for thread necromancy, but the only consumer of this is
subtly broken in some cases :( (i.e. lldb)
In particular, if you have a directory that you can stat() but has no
read permissions, real_path() will fail (note that POSIX realpath()
doesn't).

I wonder why on UNIX we don't just have this as a wrapper to the POSIX
realpath? Something like this:

diff --git a/lib/Support/Unix/Path.inc b/lib/Support/Unix/Path.inc
index 2ecb97316c8..220162d1c19 100644
--- a/lib/Support/Unix/Path.inc
+++ b/lib/Support/Unix/Path.inc
@@ -860,12 +860,12 @@ std::error_code real_path(const Twine &path,
SmallVectorImpl<char> &dest,
     return real_path(Storage, dest, false);
   }

-  int fd;
-  std::error_code EC = openFileForRead(path, fd, &dest);
-
-  if (EC)
-    return EC;
-  ::close(fd);
+  SmallString<128> Storage;
+  StringRef P = path.toNullTerminatedStringRef(Storage);
+  char Buffer[PATH_MAX];
+  if (::realpath(P.begin(), Buffer) == nullptr)
+    return std::error_code(errno, std::generic_category());
+  dest.append(Buffer, Buffer + strlen(Buffer));
   return std::error_code();
 }

I also wonder whether the "expand_tilde" argument is required.
As far as I can tell the POSIX realpath always expands "~" and,
regardless, the current code calls `openFileForRead()` which
internally calls `::realpath` so even if we don't ask to expand "~",
it will be expanded anyway (I think).
I don't know exactly what should happen on Windows, but maybe we can
expand ~ always there as well? (I'm not really familiar with windows
path conventions/rules, so I don't know whether there can be a path
starting with ~).

Thanks!

--
Davide


More information about the llvm-commits mailing list