Some related comments can be found in #4655 and #4605. Currently fs.realpath/os.realpath has different/broken symlink resolution behavior on different platforms (or maybe just Windows). The doc comments say:
|
/// Return the canonicalized absolute pathname. |
|
/// Expands all symbolic links and resolves references to `.`, `..`, and |
|
/// extra `/` characters in `pathname`. |
|
/// The return value is a slice of `out_buffer`, but not necessarily from the beginning. |
|
/// See also `realpathC` and `realpathW`. |
|
pub fn realpath(pathname: []const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 { |
Janky test code (realpath.zig built via zig build-exe realpath.zig):
const std = @import("std");
pub fn main() anyerror!void {
var args = try std.process.argsAlloc(std.heap.page_allocator);
std.debug.assert(args.len > 1);
std.debug.warn("path={}\n", .{args[1]});
var real_path = try std.fs.realpathAlloc(std.heap.page_allocator, args[1]);
std.debug.warn("realpath={}\n", .{real_path});
}
On Windows:
Setup:
mkdir foo
mkdir foo\bar
mkdir foo\bar\dir
echo. > foo\bar\file
mkdir dir
echo. > file
echo. > foo\file
mklink /J link foo\bar
C:\tmp>.\realpath.exe dir
path=dir
error: AccessDenied
C:\Users\Ryan\Programming\Zig\bin\lib\zig\std\os\windows.zig:81:31: 0x13fb88907 in std.os.windows.CreateFileW (realpath.obj)
.ACCESS_DENIED => return error.AccessDenied,
^
C:\Users\Ryan\Programming\Zig\bin\lib\zig\std\os.zig:3004:20: 0x13fb83e4f in std.os.realpathW (realpath.obj)
const h_file = try windows.CreateFileW(
^
C:\Users\Ryan\Programming\Zig\bin\lib\zig\std\os.zig:2965:9: 0x13fb83d97 in std.os.realpath (realpath.obj)
return realpathW(&pathname_w, out_buffer);
^
C:\Users\Ryan\Programming\Zig\bin\lib\zig\std\fs.zig:1664:36: 0x13fb78861 in std.fs.realpathAlloc (realpath.obj)
return mem.dupe(allocator, u8, try os.realpath(pathname, &buf));
^
C:\tmp\realpath.zig:7:21: 0x13fb62f62 in main (realpath.obj)
var real_path = try std.fs.realpathAlloc(std.heap.page_allocator, args[1]);
^
C:\tmp>.\realpath.exe file
path=file
realpath=C:\tmp\file
C:\tmp>.\realpath.exe link\file
path=link\file
realpath=C:\tmp\foo\bar\file
C:\tmp>.\realpath.exe link\.\file
path=link\.\file
realpath=C:\tmp\foo\bar\file
C:\tmp\link>..\realpath.exe file
path=file
realpath=C:\tmp\foo\bar\file
C:\tmp\link>..\realpath.exe .\file
path=.\file
realpath=C:\tmp\foo\bar\file
C:\tmp\link>..\realpath.exe .\..\file
path=.\..\file
realpath=C:\tmp\file
C:\tmp>.\realpath.exe link\..\file
path=link\..\file
realpath=C:\tmp\file
On Linux:
Setup:
mkdir -p foo/bar/dir
touch foo/bar/file
mkdir dir
touch file
touch foo/file
ln -s foo/bar link
~/tmp$ ./realpath dir
path=dir
realpath=/home/ryan/tmp/dir
~/tmp$ ./realpath file
path=file
realpath=/home/ryan/tmp/file
~/tmp$ ./realpath link/file
path=link/file
realpath=/home/ryan/tmp/foo/bar/file
~/tmp$ ./realpath link/./file
path=link/./file
realpath=/home/ryan/tmp/foo/bar/file
~/tmp/link$ ~/tmp/realpath file
path=file
realpath=/home/ryan/tmp/foo/bar/file
~/tmp/link$ ~/tmp/realpath ./file
path=./file
realpath=/home/ryan/tmp/foo/bar/file
~/tmp/link$ ~/tmp/realpath ./../file
path=./../file
realpath=/home/ryan/tmp/foo/file
~/tmp$ ./realpath link/../file
path=link/../file
realpath=/home/ryan/tmp/foo/file
Some related comments can be found in #4655 and #4605. Currently
fs.realpath/os.realpathhas different/broken symlink resolution behavior on different platforms (or maybe just Windows). The doc comments say:zig/lib/std/os.zig
Lines 3027 to 3032 in eaccfff
Janky test code (
realpath.zigbuilt viazig build-exe realpath.zig):On Windows:
Setup:
(expectedrealpathreturnserror.AccessDeniedfor directories on Windowsrealpath=C:\tmp\dir) [Fixed by Windows: Fix std.fs.realpath/os.realpathW for directories #4697]realpathworks correctly for files on Windowsrealpathresolves files in a symlinked dir on Windowsrealpathresolves files in a symlinked dir whencwdis the symlinked dir on Windowsrealpathdoes not resolve symlinks before resolving..on Windows (note: the intended resolution order is not currently specified in therealpathdoc comments)On Linux:
Setup:
realpathworks for directories on Linuxrealpathworks correctly for files on Linuxrealpathresolves files in a symlinked dir on Linuxrealpathresolves files in a symlinked dir whencwdis the symlinked dir on Linuxrealpathresolves symlinks before resolving..on Linux (note: the intended resolution order is not currently specified in therealpathdoc comments)