dafi
January 14, 2025, 11:45am
1
Hi,
I created a symlink file from unix shell with the command ln -s
and I want from zig to determine its kind but doesn’t work, the kind type is always file
May you help me?
Below my code
test "SymLink" {
const file = try std.fs.cwd().openFile("./file_size/left/sym_f010.txt", .{ });
const stat = try file.stat();
const metadata = try file.metadata();
print("Using stat {}\n", .{stat.kind == std.fs.File.Kind.sym_link});
print("Using metadata {any}\n", .{metadata.kind() == std.fs.File.Kind.sym_link});
}
1 Like
yataro
January 14, 2025, 12:01pm
2
Symlink is followed when you open it. You need to stick with std.posix
dafi
January 14, 2025, 12:40pm
3
Thanks for your reply but using fstatat
doesn’t work
const file_fd = try std.posix.open("./file_size/left", .{}, 0o600);
const stat = try std.posix.fstatat(file_fd, "sym_f010.txt", 0);
print("posix {}", .{stat});
print("posix {}", .{std.posix.S.ISLNK(stat.mode)});
dimdin
January 14, 2025, 12:42pm
4
Check if std.os.linux.S.IFLNK bit is set in mode using std.os.linux.S.ISLNK
const stat = ...;
if (std.os.linux.S.ISLNK(stat.mode)) {
}
See: man inode(7)
dafi
January 14, 2025, 12:51pm
5
It’s the same code I posted using fstatat
PS
I’m on macOS
On Linux, to get a file descriptor of a symbolic link, both O_NOFOLLOW
and O_PATH
have to be set. See the O_PATH
docs for open(2) :
If pathname is a symbolic link and the O_NOFOLLOW flag is also specified, then the call returns a file descriptor referring to the symbolic link.
On Mac, it looks like the relevant flag is O_SYMLINK
and possibly also O_NOFOLLOW
Side note: there’s actually a test for this in the Zig standard library fs tests , but right now it only tests Linux and Windows
2 Likes
dimdin
January 14, 2025, 12:54pm
7
It is the same, use the package std.posix
instead of std.os.linux
.
(For macos zig uses ISLNK
from std.c.S )
2 Likes
dafi
January 14, 2025, 1:32pm
8
GREAT!!!
The working code on macOS
The program crashes when NOFOLLOW
is set, using SYMLINK
is enough
test "SymLink" {
const flags: std.posix.O = .{
.SYMLINK = true,
};
const file_fd = try std.posix.open("./file_size/left/sym_f010.txt", flags, 0o600);
const stat = try std.posix.fstat(file_fd);
print("posix is symlink? {}\n", .{std.posix.S.ISLNK(stat.mode)});
}
1 Like