authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-07-19 23:18:20+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-07-22 08:51:22+02:00
log2c9c13f624a48e6a22ae84b236eb131c24ba2eb4
tree6d8520a5dd8599c33510f12c77e5df97960fc50a
parente0b77a6b77614538d18b9f0b9e3e7e434ccee4ff

Add various build fixes

Fix WASI build, fix atomicSymlink by using `cwd().symLink`, add `Dir.symLink` on supported targets.

2 files changed, 64 insertions(+), 17 deletions(-)

lib/std/fs.zig+62-15
......@@ -66,7 +66,15 @@ pub const need_async_thread = std.io.is_async and switch (builtin.os.tag) {
6666
6767/// TODO remove the allocator requirement from this API
6868pub fn atomicSymLink(allocator: *Allocator, existing_path: []const u8, new_path: []const u8) !void {
69 if (symLinkAbsolute(existing_path, new_path, .{})) {
69 const res = blk: {
70 // TODO this is just a temporary until Dir.symLink is implemented on Windows
71 if (builtin.os.tag == .windows) {
72 break :blk os.windows.CreateSymbolicLink(new_path, existing_path, false);
73 } else {
74 break :blk cwd().symLink(existing_path, new_path, .{});
75 }
76 };
77 if (res) {
7078 return;
7179 } else |err| switch (err) {
7280 error.PathAlreadyExists => {},
......@@ -84,7 +92,15 @@ pub fn atomicSymLink(allocator: *Allocator, existing_path: []const u8, new_path:
8492 try crypto.randomBytes(rand_buf[0..]);
8593 base64_encoder.encode(tmp_path[dirname.len + 1 ..], &rand_buf);
8694
87 if (symLinkAbsolute(existing_path, tmp_path, .{})) {
95 const res2 = blk: {
96 // TODO this is just a temporary until Dir.symLink is implemented on Windows
97 if (builtin.os.tag == .windows) {
98 break :blk os.windows.CreateSymbolicLink(tmp_path, existing_path, false);
99 } else {
100 break :blk cwd().symLink(existing_path, new_path, .{});
101 }
102 };
103 if (res2) {
88104 return rename(tmp_path, new_path);
89105 } else |err| switch (err) {
90106 error.PathAlreadyExists => continue,
......@@ -669,7 +685,7 @@ pub const Dir = struct {
669685 w.RIGHT_FD_FILESTAT_SET_TIMES |
670686 w.RIGHT_FD_FILESTAT_SET_SIZE;
671687 }
672 const fd = try os.openatWasi(self.fd, sub_path, 0x0, fdflags, base, 0x0);
688 const fd = try os.openatWasi(self.fd, sub_path, 0x0, 0x0, fdflags, base, 0x0);
673689 return File{ .handle = fd };
674690 }
675691
......@@ -789,7 +805,7 @@ pub const Dir = struct {
789805 if (flags.exclusive) {
790806 oflags |= w.O_EXCL;
791807 }
792 const fd = try os.openatWasi(self.fd, sub_path, oflags, 0x0, base, 0x0);
808 const fd = try os.openatWasi(self.fd, sub_path, 0x0, oflags, 0x0, base, 0x0);
793809 return File{ .handle = fd };
794810 }
795811
......@@ -952,7 +968,7 @@ pub const Dir = struct {
952968 /// of the result. It means the `iterate` function can be called.
953969 iterate: bool = false,
954970
955 /// `true` means it won't dereference the symlink.
971 /// `true` means it won't dereference the symlinks.
956972 no_follow: bool = false,
957973 };
958974
......@@ -1001,7 +1017,7 @@ pub const Dir = struct {
10011017 // TODO do we really need all the rights here?
10021018 const inheriting: w.rights_t = w.RIGHT_ALL ^ w.RIGHT_SOCK_SHUTDOWN;
10031019
1004 const result = os.openatWasi(self.fd, sub_path, w.O_DIRECTORY, symlink_flags, base, inheriting);
1020 const result = os.openatWasi(self.fd, sub_path, symlink_flags, w.O_DIRECTORY, 0x0, base, inheriting);
10051021 const fd = result catch |err| switch (err) {
10061022 error.FileTooBig => unreachable, // can't happen for directories
10071023 error.IsDir => unreachable, // we're providing O_DIRECTORY
......@@ -1211,6 +1227,38 @@ pub const Dir = struct {
12111227 };
12121228 }
12131229
1230 /// Creates a symbolic link named `sym_link_path` which contains the string `target_path`.
1231 /// A symbolic link (also known as a soft link) may point to an existing file or to a nonexistent
1232 /// one; the latter case is known as a dangling link.
1233 /// If `sym_link_path` exists, it will not be overwritten.
1234 /// TODO add Windows support
1235 pub fn symLink(
1236 self: Dir,
1237 target_path: []const u8,
1238 sym_link_path: []const u8,
1239 flags: SymLinkFlags,
1240 ) !void {
1241 if (builtin.os.tag == .wasi) {
1242 return self.symLinkWasi(target_path, sym_link_path);
1243 }
1244 if (builtin.os.tag == .windows) {
1245 @compileError("TODO implement Dir.symLink on Windows");
1246 }
1247 const target_path_c = try os.toPosixPath(target_path);
1248 const sym_link_path_c = try os.toPosixPath(sym_link_path);
1249 return self.symLinkZ(&target_path_c, &sym_link_path_c, flags);
1250 }
1251
1252 /// WASI-only. Same as `symLink` except targeting WASI.
1253 pub fn symLinkWasi(self: Dir, target_path: []const u8, sym_link_path: []const u8, flags: SymLinkFlags) !void {
1254 return os.symlinkatWasi(target_path, self.fd, sym_link_path);
1255 }
1256
1257 /// Same as `symLink`, except the pathname parameters are null-terminated.
1258 pub fn symLinkZ(self: Dir, target_path_c: [*:0]const u8, sym_link_path_c: [*:0]const u8, flags: SymLinkFlags) !void {
1259 return os.symlinkatZ(target_path_c, self.fd, sym_link_path_c);
1260 }
1261
12141262 /// Read value of a symbolic link.
12151263 /// The return value is a slice of `buffer`, from index `0`.
12161264 /// Asserts that the path parameter has no null bytes.
......@@ -1305,7 +1353,6 @@ pub const Dir = struct {
13051353 error.Unexpected,
13061354 => |e| return e,
13071355 }
1308
13091356 var dir = self.openDir(sub_path, .{ .iterate = true, .no_follow = true }) catch |err| switch (err) {
13101357 error.NotDir => {
13111358 if (got_access_denied) {
......@@ -1718,7 +1765,7 @@ pub const readLinkC = @compileError("deprecated; use Dir.readLinkZ or readLinkAb
17181765/// or a directory. This value is ignored on all hosts except Windows where
17191766/// creating symlinks to different resource types, requires different flags.
17201767/// By default, `symLinkAbsolute` is assumed to point to a file.
1721pub const SymlinkFlags = struct {
1768pub const SymLinkFlags = struct {
17221769 is_directory: bool = false,
17231770};
17241771
......@@ -1727,9 +1774,9 @@ pub const SymlinkFlags = struct {
17271774/// one; the latter case is known as a dangling link.
17281775/// If `sym_link_path` exists, it will not be overwritten.
17291776/// See also `symLinkAbsoluteZ` and `symLinkAbsoluteW`.
1730pub fn symLinkAbsolute(target_path: []const u8, sym_link_path: []const u8, flags: SymlinkFlags) !void {
1777pub fn symLinkAbsolute(target_path: []const u8, sym_link_path: []const u8, flags: SymLinkFlags) !void {
17311778 if (builtin.os.tag == .wasi) {
1732 @compileError("symLinkAbsolute is not supported in WASI");
1779 @compileError("symLinkAbsolute is not supported in WASI; use Dir.symLinkWasi instead");
17331780 }
17341781 assert(path.isAbsolute(target_path));
17351782 assert(path.isAbsolute(sym_link_path));
......@@ -1741,9 +1788,9 @@ pub fn symLinkAbsolute(target_path: []const u8, sym_link_path: []const u8, flags
17411788
17421789/// Windows-only. Same as `symLinkAbsolute` except the parameters are null-terminated, WTF16 encoded.
17431790/// Note that this function will by default try creating a symbolic link to a file. If you would
1744/// like to create a symbolic link to a directory, specify this with `SymlinkFlags{ .is_directory = true }`.
1791/// like to create a symbolic link to a directory, specify this with `SymLinkFlags{ .is_directory = true }`.
17451792/// See also `symLinkAbsolute`, `symLinkAbsoluteZ`.
1746pub fn symLinkAbsoluteW(target_path_w: [*:0]const u16, sym_link_path_w: [*:0]const u16, flags: SymlinkFlags) !void {
1793pub fn symLinkAbsoluteW(target_path_w: [*:0]const u16, sym_link_path_w: [*:0]const u16, flags: SymLinkFlags) !void {
17471794 assert(path.isAbsoluteWindowsW(target_path_w));
17481795 assert(path.isAbsoluteWindowsW(sym_link_path_w));
17491796 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
17511798
17521799/// Same as `symLinkAbsolute` except the parameters are null-terminated pointers.
17531800/// See also `symLinkAbsolute`.
1754pub fn symLinkAbsoluteZ(target_path_c: [*:0]const u8, sym_link_path_c: [*:0]const u8, flags: SymlinkFlags) !void {
1801pub fn symLinkAbsoluteZ(target_path_c: [*:0]const u8, sym_link_path_c: [*:0]const u8, flags: SymLinkFlags) !void {
17551802 assert(path.isAbsoluteZ(target_path_c));
17561803 assert(path.isAbsoluteZ(sym_link_path_c));
17571804 if (builtin.os.tag == .windows) {
......@@ -1762,8 +1809,8 @@ pub fn symLinkAbsoluteZ(target_path_c: [*:0]const u8, sym_link_path_c: [*:0]cons
17621809 return os.symlinkZ(target_path_c, sym_link_path_c);
17631810}
17641811
1765pub const symLink = @compileError("deprecated: use symLinkAbsolute");
1766pub const symLinkC = @compileError("deprecated: use symLinkAbsoluteC");
1812pub const symLink = @compileError("deprecated: use Dir.symLink or symLinkAbsolute");
1813pub const symLinkC = @compileError("deprecated: use Dir.symLinkZ or symLinkAbsoluteZ");
17671814
17681815pub const Walker = struct {
17691816 stack: std.ArrayList(StackItem),
lib/std/os.zig+2-2
......@@ -1109,10 +1109,10 @@ pub fn openat(dir_fd: fd_t, file_path: []const u8, flags: u32, mode: mode_t) Ope
11091109}
11101110
11111111/// Open and possibly create a file in WASI.
1112pub 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 {
1112pub 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 {
11131113 while (true) {
11141114 var fd: fd_t = undefined;
1115 switch (wasi.path_open(dir_fd, 0x0, file_path.ptr, file_path.len, oflags, base, inheriting, fdflags, &fd)) {
1115 switch (wasi.path_open(dir_fd, lookup_flags, file_path.ptr, file_path.len, oflags, base, inheriting, fdflags, &fd)) {
11161116 wasi.ESUCCESS => return fd,
11171117 wasi.EINTR => continue,
11181118