mirror of
https://github.com/ziglang/zig.git
synced 2026-01-05 13:03:25 +00:00
Add various build fixes
Fix WASI build, fix atomicSymlink by using `cwd().symLink`, add `Dir.symLink` on supported targets.
This commit is contained in:
parent
e0b77a6b77
commit
2c9c13f624
@ -66,7 +66,15 @@ pub const need_async_thread = std.io.is_async and switch (builtin.os.tag) {
|
||||
|
||||
/// TODO remove the allocator requirement from this API
|
||||
pub fn atomicSymLink(allocator: *Allocator, existing_path: []const u8, new_path: []const u8) !void {
|
||||
if (symLinkAbsolute(existing_path, new_path, .{})) {
|
||||
const res = blk: {
|
||||
// TODO this is just a temporary until Dir.symLink is implemented on Windows
|
||||
if (builtin.os.tag == .windows) {
|
||||
break :blk os.windows.CreateSymbolicLink(new_path, existing_path, false);
|
||||
} else {
|
||||
break :blk cwd().symLink(existing_path, new_path, .{});
|
||||
}
|
||||
};
|
||||
if (res) {
|
||||
return;
|
||||
} else |err| switch (err) {
|
||||
error.PathAlreadyExists => {},
|
||||
@ -84,7 +92,15 @@ pub fn atomicSymLink(allocator: *Allocator, existing_path: []const u8, new_path:
|
||||
try crypto.randomBytes(rand_buf[0..]);
|
||||
base64_encoder.encode(tmp_path[dirname.len + 1 ..], &rand_buf);
|
||||
|
||||
if (symLinkAbsolute(existing_path, tmp_path, .{})) {
|
||||
const res2 = blk: {
|
||||
// TODO this is just a temporary until Dir.symLink is implemented on Windows
|
||||
if (builtin.os.tag == .windows) {
|
||||
break :blk os.windows.CreateSymbolicLink(tmp_path, existing_path, false);
|
||||
} else {
|
||||
break :blk cwd().symLink(existing_path, new_path, .{});
|
||||
}
|
||||
};
|
||||
if (res2) {
|
||||
return rename(tmp_path, new_path);
|
||||
} else |err| switch (err) {
|
||||
error.PathAlreadyExists => continue,
|
||||
@ -669,7 +685,7 @@ pub const Dir = struct {
|
||||
w.RIGHT_FD_FILESTAT_SET_TIMES |
|
||||
w.RIGHT_FD_FILESTAT_SET_SIZE;
|
||||
}
|
||||
const fd = try os.openatWasi(self.fd, sub_path, 0x0, fdflags, base, 0x0);
|
||||
const fd = try os.openatWasi(self.fd, sub_path, 0x0, 0x0, fdflags, base, 0x0);
|
||||
return File{ .handle = fd };
|
||||
}
|
||||
|
||||
@ -789,7 +805,7 @@ pub const Dir = struct {
|
||||
if (flags.exclusive) {
|
||||
oflags |= w.O_EXCL;
|
||||
}
|
||||
const fd = try os.openatWasi(self.fd, sub_path, oflags, 0x0, base, 0x0);
|
||||
const fd = try os.openatWasi(self.fd, sub_path, 0x0, oflags, 0x0, base, 0x0);
|
||||
return File{ .handle = fd };
|
||||
}
|
||||
|
||||
@ -952,7 +968,7 @@ pub const Dir = struct {
|
||||
/// of the result. It means the `iterate` function can be called.
|
||||
iterate: bool = false,
|
||||
|
||||
/// `true` means it won't dereference the symlink.
|
||||
/// `true` means it won't dereference the symlinks.
|
||||
no_follow: bool = false,
|
||||
};
|
||||
|
||||
@ -1001,7 +1017,7 @@ pub const Dir = struct {
|
||||
// TODO do we really need all the rights here?
|
||||
const inheriting: w.rights_t = w.RIGHT_ALL ^ w.RIGHT_SOCK_SHUTDOWN;
|
||||
|
||||
const result = os.openatWasi(self.fd, sub_path, w.O_DIRECTORY, symlink_flags, base, inheriting);
|
||||
const result = os.openatWasi(self.fd, sub_path, symlink_flags, w.O_DIRECTORY, 0x0, base, inheriting);
|
||||
const fd = result catch |err| switch (err) {
|
||||
error.FileTooBig => unreachable, // can't happen for directories
|
||||
error.IsDir => unreachable, // we're providing O_DIRECTORY
|
||||
@ -1211,6 +1227,38 @@ pub const Dir = struct {
|
||||
};
|
||||
}
|
||||
|
||||
/// Creates a symbolic link named `sym_link_path` which contains the string `target_path`.
|
||||
/// A symbolic link (also known as a soft link) may point to an existing file or to a nonexistent
|
||||
/// one; the latter case is known as a dangling link.
|
||||
/// If `sym_link_path` exists, it will not be overwritten.
|
||||
/// TODO add Windows support
|
||||
pub fn symLink(
|
||||
self: Dir,
|
||||
target_path: []const u8,
|
||||
sym_link_path: []const u8,
|
||||
flags: SymLinkFlags,
|
||||
) !void {
|
||||
if (builtin.os.tag == .wasi) {
|
||||
return self.symLinkWasi(target_path, sym_link_path);
|
||||
}
|
||||
if (builtin.os.tag == .windows) {
|
||||
@compileError("TODO implement Dir.symLink on Windows");
|
||||
}
|
||||
const target_path_c = try os.toPosixPath(target_path);
|
||||
const sym_link_path_c = try os.toPosixPath(sym_link_path);
|
||||
return self.symLinkZ(&target_path_c, &sym_link_path_c, flags);
|
||||
}
|
||||
|
||||
/// WASI-only. Same as `symLink` except targeting WASI.
|
||||
pub fn symLinkWasi(self: Dir, target_path: []const u8, sym_link_path: []const u8, flags: SymLinkFlags) !void {
|
||||
return os.symlinkatWasi(target_path, self.fd, sym_link_path);
|
||||
}
|
||||
|
||||
/// Same as `symLink`, except the pathname parameters are null-terminated.
|
||||
pub fn symLinkZ(self: Dir, target_path_c: [*:0]const u8, sym_link_path_c: [*:0]const u8, flags: SymLinkFlags) !void {
|
||||
return os.symlinkatZ(target_path_c, self.fd, sym_link_path_c);
|
||||
}
|
||||
|
||||
/// Read value of a symbolic link.
|
||||
/// The return value is a slice of `buffer`, from index `0`.
|
||||
/// Asserts that the path parameter has no null bytes.
|
||||
@ -1305,7 +1353,6 @@ pub const Dir = struct {
|
||||
error.Unexpected,
|
||||
=> |e| return e,
|
||||
}
|
||||
|
||||
var dir = self.openDir(sub_path, .{ .iterate = true, .no_follow = true }) catch |err| switch (err) {
|
||||
error.NotDir => {
|
||||
if (got_access_denied) {
|
||||
@ -1718,7 +1765,7 @@ pub const readLinkC = @compileError("deprecated; use Dir.readLinkZ or readLinkAb
|
||||
/// or a directory. This value is ignored on all hosts except Windows where
|
||||
/// creating symlinks to different resource types, requires different flags.
|
||||
/// By default, `symLinkAbsolute` is assumed to point to a file.
|
||||
pub const SymlinkFlags = struct {
|
||||
pub const SymLinkFlags = struct {
|
||||
is_directory: bool = false,
|
||||
};
|
||||
|
||||
@ -1727,9 +1774,9 @@ pub const SymlinkFlags = struct {
|
||||
/// one; the latter case is known as a dangling link.
|
||||
/// If `sym_link_path` exists, it will not be overwritten.
|
||||
/// See also `symLinkAbsoluteZ` and `symLinkAbsoluteW`.
|
||||
pub fn symLinkAbsolute(target_path: []const u8, sym_link_path: []const u8, flags: SymlinkFlags) !void {
|
||||
pub fn symLinkAbsolute(target_path: []const u8, sym_link_path: []const u8, flags: SymLinkFlags) !void {
|
||||
if (builtin.os.tag == .wasi) {
|
||||
@compileError("symLinkAbsolute is not supported in WASI");
|
||||
@compileError("symLinkAbsolute is not supported in WASI; use Dir.symLinkWasi instead");
|
||||
}
|
||||
assert(path.isAbsolute(target_path));
|
||||
assert(path.isAbsolute(sym_link_path));
|
||||
@ -1741,9 +1788,9 @@ pub fn symLinkAbsolute(target_path: []const u8, sym_link_path: []const u8, flags
|
||||
|
||||
/// Windows-only. Same as `symLinkAbsolute` except the parameters are null-terminated, WTF16 encoded.
|
||||
/// Note that this function will by default try creating a symbolic link to a file. If you would
|
||||
/// like to create a symbolic link to a directory, specify this with `SymlinkFlags{ .is_directory = true }`.
|
||||
/// like to create a symbolic link to a directory, specify this with `SymLinkFlags{ .is_directory = true }`.
|
||||
/// See also `symLinkAbsolute`, `symLinkAbsoluteZ`.
|
||||
pub fn symLinkAbsoluteW(target_path_w: [*:0]const u16, sym_link_path_w: [*:0]const u16, flags: SymlinkFlags) !void {
|
||||
pub fn symLinkAbsoluteW(target_path_w: [*:0]const u16, sym_link_path_w: [*:0]const u16, flags: SymLinkFlags) !void {
|
||||
assert(path.isAbsoluteWindowsW(target_path_w));
|
||||
assert(path.isAbsoluteWindowsW(sym_link_path_w));
|
||||
return os.windows.CreateSymbolicLinkW(sym_link_path_w, target_path_w, flags.is_directory);
|
||||
@ -1751,7 +1798,7 @@ pub fn symLinkAbsoluteW(target_path_w: [*:0]const u16, sym_link_path_w: [*:0]con
|
||||
|
||||
/// Same as `symLinkAbsolute` except the parameters are null-terminated pointers.
|
||||
/// See also `symLinkAbsolute`.
|
||||
pub fn symLinkAbsoluteZ(target_path_c: [*:0]const u8, sym_link_path_c: [*:0]const u8, flags: SymlinkFlags) !void {
|
||||
pub fn symLinkAbsoluteZ(target_path_c: [*:0]const u8, sym_link_path_c: [*:0]const u8, flags: SymLinkFlags) !void {
|
||||
assert(path.isAbsoluteZ(target_path_c));
|
||||
assert(path.isAbsoluteZ(sym_link_path_c));
|
||||
if (builtin.os.tag == .windows) {
|
||||
@ -1762,8 +1809,8 @@ pub fn symLinkAbsoluteZ(target_path_c: [*:0]const u8, sym_link_path_c: [*:0]cons
|
||||
return os.symlinkZ(target_path_c, sym_link_path_c);
|
||||
}
|
||||
|
||||
pub const symLink = @compileError("deprecated: use symLinkAbsolute");
|
||||
pub const symLinkC = @compileError("deprecated: use symLinkAbsoluteC");
|
||||
pub const symLink = @compileError("deprecated: use Dir.symLink or symLinkAbsolute");
|
||||
pub const symLinkC = @compileError("deprecated: use Dir.symLinkZ or symLinkAbsoluteZ");
|
||||
|
||||
pub const Walker = struct {
|
||||
stack: std.ArrayList(StackItem),
|
||||
|
||||
@ -1109,10 +1109,10 @@ pub fn openat(dir_fd: fd_t, file_path: []const u8, flags: u32, mode: mode_t) Ope
|
||||
}
|
||||
|
||||
/// Open and possibly create a file in WASI.
|
||||
pub fn openatWasi(dir_fd: fd_t, file_path: []const u8, oflags: oflags_t, fdflags: fdflags_t, base: rights_t, inheriting: rights_t) OpenError!fd_t {
|
||||
pub fn openatWasi(dir_fd: fd_t, file_path: []const u8, lookup_flags: lookupflags_t, oflags: oflags_t, fdflags: fdflags_t, base: rights_t, inheriting: rights_t) OpenError!fd_t {
|
||||
while (true) {
|
||||
var fd: fd_t = undefined;
|
||||
switch (wasi.path_open(dir_fd, 0x0, file_path.ptr, file_path.len, oflags, base, inheriting, fdflags, &fd)) {
|
||||
switch (wasi.path_open(dir_fd, lookup_flags, file_path.ptr, file_path.len, oflags, base, inheriting, fdflags, &fd)) {
|
||||
wasi.ESUCCESS => return fd,
|
||||
wasi.EINTR => continue,
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user