mirror of
https://github.com/ziglang/zig.git
synced 2026-01-21 06:45:24 +00:00
POSIX link() syscall only takes two arguments (no flags)
The signature is documented as:
int link(const char *, const char *);
(see https://man7.org/linux/man-pages/man2/link.2.html or https://man.netbsd.org/link.2)
And its not some Linux extension, the [syscall
implementation](21b136cc63/fs/namei.c (L4794-L4797))
only expects two arguments too.
It probably *should* have a flags parameter, but its too late now.
I am a bit surprised that linking glibc or musl against code that invokes
a 'link' with three parameters doesn't fail (at least, I couldn't get any
local test cases to trigger a compile or link error).
The test case in std/posix/test.zig is currently disabled, but if I
manually enable it, it works with this change.
This commit is contained in:
parent
979fd12be9
commit
4d6429fc4f
@ -9060,7 +9060,7 @@ pub extern "c" fn pwrite(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: off_t
|
||||
pub extern "c" fn mmap(addr: ?*align(page_size) anyopaque, len: usize, prot: c_uint, flags: MAP, fd: fd_t, offset: off_t) *anyopaque;
|
||||
pub extern "c" fn munmap(addr: *align(page_size) const anyopaque, len: usize) c_int;
|
||||
pub extern "c" fn mprotect(addr: *align(page_size) anyopaque, len: usize, prot: c_uint) c_int;
|
||||
pub extern "c" fn link(oldpath: [*:0]const u8, newpath: [*:0]const u8, flags: c_int) c_int;
|
||||
pub extern "c" fn link(oldpath: [*:0]const u8, newpath: [*:0]const u8) c_int;
|
||||
pub extern "c" fn linkat(oldfd: fd_t, oldpath: [*:0]const u8, newfd: fd_t, newpath: [*:0]const u8, flags: c_int) c_int;
|
||||
pub extern "c" fn unlink(path: [*:0]const u8) c_int;
|
||||
pub extern "c" fn unlinkat(dirfd: fd_t, path: [*:0]const u8, flags: c_uint) c_int;
|
||||
|
||||
@ -1339,13 +1339,12 @@ pub fn tgkill(tgid: pid_t, tid: pid_t, sig: i32) usize {
|
||||
return syscall3(.tgkill, @as(usize, @bitCast(@as(isize, tgid))), @as(usize, @bitCast(@as(isize, tid))), @as(usize, @bitCast(@as(isize, sig))));
|
||||
}
|
||||
|
||||
pub fn link(oldpath: [*:0]const u8, newpath: [*:0]const u8, flags: i32) usize {
|
||||
pub fn link(oldpath: [*:0]const u8, newpath: [*:0]const u8) usize {
|
||||
if (@hasField(SYS, "link")) {
|
||||
return syscall3(
|
||||
return syscall2(
|
||||
.link,
|
||||
@intFromPtr(oldpath),
|
||||
@intFromPtr(newpath),
|
||||
@as(usize, @bitCast(@as(isize, flags))),
|
||||
);
|
||||
} else {
|
||||
return syscall5(
|
||||
@ -1354,7 +1353,7 @@ pub fn link(oldpath: [*:0]const u8, newpath: [*:0]const u8, flags: i32) usize {
|
||||
@intFromPtr(oldpath),
|
||||
@as(usize, @bitCast(@as(isize, AT.FDCWD))),
|
||||
@intFromPtr(newpath),
|
||||
@as(usize, @bitCast(@as(isize, flags))),
|
||||
0,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2202,11 +2202,11 @@ pub const LinkError = UnexpectedError || error{
|
||||
|
||||
/// On WASI, both paths should be encoded as valid UTF-8.
|
||||
/// On other platforms, both paths are an opaque sequence of bytes with no particular encoding.
|
||||
pub fn linkZ(oldpath: [*:0]const u8, newpath: [*:0]const u8, flags: i32) LinkError!void {
|
||||
pub fn linkZ(oldpath: [*:0]const u8, newpath: [*:0]const u8) LinkError!void {
|
||||
if (native_os == .wasi and !builtin.link_libc) {
|
||||
return link(mem.sliceTo(oldpath, 0), mem.sliceTo(newpath, 0), flags);
|
||||
return link(mem.sliceTo(oldpath, 0), mem.sliceTo(newpath, 0));
|
||||
}
|
||||
switch (errno(system.link(oldpath, newpath, flags))) {
|
||||
switch (errno(system.link(oldpath, newpath))) {
|
||||
.SUCCESS => return,
|
||||
.ACCES => return error.AccessDenied,
|
||||
.DQUOT => return error.DiskQuota,
|
||||
@ -2233,16 +2233,16 @@ pub fn linkZ(oldpath: [*:0]const u8, newpath: [*:0]const u8, flags: i32) LinkErr
|
||||
|
||||
/// On WASI, both paths should be encoded as valid UTF-8.
|
||||
/// On other platforms, both paths are an opaque sequence of bytes with no particular encoding.
|
||||
pub fn link(oldpath: []const u8, newpath: []const u8, flags: i32) LinkError!void {
|
||||
pub fn link(oldpath: []const u8, newpath: []const u8) LinkError!void {
|
||||
if (native_os == .wasi and !builtin.link_libc) {
|
||||
return linkat(wasi.AT.FDCWD, oldpath, wasi.AT.FDCWD, newpath, flags) catch |err| switch (err) {
|
||||
return linkat(wasi.AT.FDCWD, oldpath, wasi.AT.FDCWD, newpath, 0) catch |err| switch (err) {
|
||||
error.NotDir => unreachable, // link() does not support directories
|
||||
else => |e| return e,
|
||||
};
|
||||
}
|
||||
const old = try toPosixPath(oldpath);
|
||||
const new = try toPosixPath(newpath);
|
||||
return try linkZ(&old, &new, flags);
|
||||
return try linkZ(&old, &new);
|
||||
}
|
||||
|
||||
pub const LinkatError = LinkError || error{NotDir};
|
||||
|
||||
@ -278,7 +278,7 @@ test "link with relative paths" {
|
||||
cwd.deleteFile("new.txt") catch {};
|
||||
|
||||
try cwd.writeFile(.{ .sub_path = "example.txt", .data = "example" });
|
||||
try posix.link("example.txt", "new.txt", 0);
|
||||
try posix.link("example.txt", "new.txt");
|
||||
|
||||
const efd = try cwd.openFile("example.txt", .{});
|
||||
defer efd.close();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user