| ... | @@ -66,15 +66,7 @@ pub const need_async_thread = std.io.is_async and switch (builtin.os.tag) { | ... | @@ -66,15 +66,7 @@ pub const need_async_thread = std.io.is_async and switch (builtin.os.tag) { |
| 66 | | 66 | |
| 67 | /// TODO remove the allocator requirement from this API | 67 | /// TODO remove the allocator requirement from this API |
| 68 | pub fn atomicSymLink(allocator: *Allocator, existing_path: []const u8, new_path: []const u8) !void { | 68 | pub fn atomicSymLink(allocator: *Allocator, existing_path: []const u8, new_path: []const u8) !void { |
| 69 | const res = blk: { | 69 | if (cwd().symLink(existing_path, new_path, .{})) { |
| 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) { | | |
| 78 | return; | 70 | return; |
| 79 | } else |err| switch (err) { | 71 | } else |err| switch (err) { |
| 80 | error.PathAlreadyExists => {}, | 72 | error.PathAlreadyExists => {}, |
| ... | @@ -92,15 +84,7 @@ pub fn atomicSymLink(allocator: *Allocator, existing_path: []const u8, new_path: | ... | @@ -92,15 +84,7 @@ pub fn atomicSymLink(allocator: *Allocator, existing_path: []const u8, new_path: |
| 92 | try crypto.randomBytes(rand_buf[0..]); | 84 | try crypto.randomBytes(rand_buf[0..]); |
| 93 | base64_encoder.encode(tmp_path[dirname.len + 1 ..], &rand_buf); | 85 | base64_encoder.encode(tmp_path[dirname.len + 1 ..], &rand_buf); |
| 94 | | 86 | |
| 95 | const res2 = blk: { | 87 | if (cwd().symLink(existing_path, new_path, .{})) { |
| 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) { | | |
| 104 | return rename(tmp_path, new_path); | 88 | return rename(tmp_path, new_path); |
| 105 | } else |err| switch (err) { | 89 | } else |err| switch (err) { |
| 106 | error.PathAlreadyExists => continue, | 90 | error.PathAlreadyExists => continue, |
| ... | @@ -1239,10 +1223,12 @@ pub const Dir = struct { | ... | @@ -1239,10 +1223,12 @@ pub const Dir = struct { |
| 1239 | flags: SymLinkFlags, | 1223 | flags: SymLinkFlags, |
| 1240 | ) !void { | 1224 | ) !void { |
| 1241 | if (builtin.os.tag == .wasi) { | 1225 | if (builtin.os.tag == .wasi) { |
| 1242 | return self.symLinkWasi(target_path, sym_link_path); | 1226 | return self.symLinkWasi(target_path, sym_link_path, flags); |
| 1243 | } | 1227 | } |
| 1244 | if (builtin.os.tag == .windows) { | 1228 | if (builtin.os.tag == .windows) { |
| 1245 | @compileError("TODO implement Dir.symLink on Windows"); | 1229 | const target_path_w = try os.windows.sliceToPrefixedFileW(target_path); |
| | 1230 | const sym_link_path_w = try os.windows.sliceToPrefixedFileW(sym_link_path); |
| | 1231 | return self.symLinkW(target_path_w.span(), sym_link_path_w.span(), flags); |
| 1246 | } | 1232 | } |
| 1247 | const target_path_c = try os.toPosixPath(target_path); | 1233 | const target_path_c = try os.toPosixPath(target_path); |
| 1248 | const sym_link_path_c = try os.toPosixPath(sym_link_path); | 1234 | const sym_link_path_c = try os.toPosixPath(sym_link_path); |
| ... | @@ -1250,15 +1236,41 @@ pub const Dir = struct { | ... | @@ -1250,15 +1236,41 @@ pub const Dir = struct { |
| 1250 | } | 1236 | } |
| 1251 | | 1237 | |
| 1252 | /// WASI-only. Same as `symLink` except targeting WASI. | 1238 | /// 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 { | 1239 | pub fn symLinkWasi( |
| | 1240 | self: Dir, |
| | 1241 | target_path: []const u8, |
| | 1242 | sym_link_path: []const u8, |
| | 1243 | flags: SymLinkFlags, |
| | 1244 | ) !void { |
| 1254 | return os.symlinkatWasi(target_path, self.fd, sym_link_path); | 1245 | return os.symlinkatWasi(target_path, self.fd, sym_link_path); |
| 1255 | } | 1246 | } |
| 1256 | | 1247 | |
| 1257 | /// Same as `symLink`, except the pathname parameters are null-terminated. | 1248 | /// 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 { | 1249 | pub fn symLinkZ( |
| | 1250 | self: Dir, |
| | 1251 | target_path_c: [*:0]const u8, |
| | 1252 | sym_link_path_c: [*:0]const u8, |
| | 1253 | flags: SymLinkFlags, |
| | 1254 | ) !void { |
| | 1255 | if (builtin.os.tag == .windows) { |
| | 1256 | const target_path_w = try os.windows.cStrToPrefixedFileW(target_path_c); |
| | 1257 | const sym_link_path_w = try os.windows.cStrToPrefixedFileW(sym_link_path_c); |
| | 1258 | return self.symLinkW(target_path_w.span(), sym_link_path_w.span(), flags); |
| | 1259 | } |
| 1259 | return os.symlinkatZ(target_path_c, self.fd, sym_link_path_c); | 1260 | return os.symlinkatZ(target_path_c, self.fd, sym_link_path_c); |
| 1260 | } | 1261 | } |
| 1261 | | 1262 | |
| | 1263 | /// Windows-only. Same as `symLink` except the pathname parameters |
| | 1264 | /// are null-terminated, WTF16 encoded. |
| | 1265 | pub fn symLinkW( |
| | 1266 | self: Dir, |
| | 1267 | target_path_w: [:0]const u16, |
| | 1268 | sym_link_path_w: [:0]const u16, |
| | 1269 | flags: SymLinkFlags, |
| | 1270 | ) !void { |
| | 1271 | return os.windows.CreateSymbolicLinkW(self.fd, sym_link_path_w, target_path_w, flags.is_directory); |
| | 1272 | } |
| | 1273 | |
| 1262 | /// Read value of a symbolic link. | 1274 | /// Read value of a symbolic link. |
| 1263 | /// The return value is a slice of `buffer`, from index `0`. | 1275 | /// The return value is a slice of `buffer`, from index `0`. |
| 1264 | /// Asserts that the path parameter has no null bytes. | 1276 | /// Asserts that the path parameter has no null bytes. |
| ... | @@ -1761,10 +1773,10 @@ pub fn readLinkAbsoluteZ(pathname_c: [*:0]const u8, buffer: *[MAX_PATH_BYTES]u8) | ... | @@ -1761,10 +1773,10 @@ pub fn readLinkAbsoluteZ(pathname_c: [*:0]const u8, buffer: *[MAX_PATH_BYTES]u8) |
| 1761 | pub const readLink = @compileError("deprecated; use Dir.readLink or readLinkAbsolute"); | 1773 | pub const readLink = @compileError("deprecated; use Dir.readLink or readLinkAbsolute"); |
| 1762 | pub const readLinkC = @compileError("deprecated; use Dir.readLinkZ or readLinkAbsoluteZ"); | 1774 | pub const readLinkC = @compileError("deprecated; use Dir.readLinkZ or readLinkAbsoluteZ"); |
| 1763 | | 1775 | |
| 1764 | /// Use with `symLinkAbsolute` to specify whether the symlink will point to a file | 1776 | /// Use with `Dir.symLink` and `symLinkAbsolute` to specify whether the symlink |
| 1765 | /// or a directory. This value is ignored on all hosts except Windows where | 1777 | /// will point to a file or a directory. This value is ignored on all hosts |
| 1766 | /// creating symlinks to different resource types, requires different flags. | 1778 | /// except Windows where creating symlinks to different resource types, requires |
| 1767 | /// By default, `symLinkAbsolute` is assumed to point to a file. | 1779 | /// different flags. By default, `symLinkAbsolute` is assumed to point to a file. |
| 1768 | pub const SymLinkFlags = struct { | 1780 | pub const SymLinkFlags = struct { |
| 1769 | is_directory: bool = false, | 1781 | is_directory: bool = false, |
| 1770 | }; | 1782 | }; |
| ... | @@ -1781,7 +1793,7 @@ pub fn symLinkAbsolute(target_path: []const u8, sym_link_path: []const u8, flags | ... | @@ -1781,7 +1793,7 @@ pub fn symLinkAbsolute(target_path: []const u8, sym_link_path: []const u8, flags |
| 1781 | assert(path.isAbsolute(target_path)); | 1793 | assert(path.isAbsolute(target_path)); |
| 1782 | assert(path.isAbsolute(sym_link_path)); | 1794 | assert(path.isAbsolute(sym_link_path)); |
| 1783 | if (builtin.os.tag == .windows) { | 1795 | if (builtin.os.tag == .windows) { |
| 1784 | return os.windows.CreateSymbolicLink(sym_link_path, target_path, flags.is_directory); | 1796 | return os.windows.CreateSymbolicLink(null, sym_link_path, target_path, flags.is_directory); |
| 1785 | } | 1797 | } |
| 1786 | return os.symlink(target_path, sym_link_path); | 1798 | return os.symlink(target_path, sym_link_path); |
| 1787 | } | 1799 | } |
| ... | @@ -1790,10 +1802,10 @@ pub fn symLinkAbsolute(target_path: []const u8, sym_link_path: []const u8, flags | ... | @@ -1790,10 +1802,10 @@ pub fn symLinkAbsolute(target_path: []const u8, sym_link_path: []const u8, flags |
| 1790 | /// Note that this function will by default try creating a symbolic link to a file. If you would | 1802 | /// Note that this function will by default try creating a symbolic link to a file. If you would |
| 1791 | /// like to create a symbolic link to a directory, specify this with `SymLinkFlags{ .is_directory = true }`. | 1803 | /// like to create a symbolic link to a directory, specify this with `SymLinkFlags{ .is_directory = true }`. |
| 1792 | /// See also `symLinkAbsolute`, `symLinkAbsoluteZ`. | 1804 | /// See also `symLinkAbsolute`, `symLinkAbsoluteZ`. |
| 1793 | pub fn symLinkAbsoluteW(target_path_w: [*:0]const u16, sym_link_path_w: [*:0]const u16, flags: SymLinkFlags) !void { | 1805 | pub fn symLinkAbsoluteW(target_path_w: [:0]const u16, sym_link_path_w: [:0]const u16, flags: SymLinkFlags) !void { |
| 1794 | assert(path.isAbsoluteWindowsW(target_path_w)); | 1806 | assert(path.isAbsoluteWindowsW(target_path_w)); |
| 1795 | assert(path.isAbsoluteWindowsW(sym_link_path_w)); | 1807 | assert(path.isAbsoluteWindowsW(sym_link_path_w)); |
| 1796 | return os.windows.CreateSymbolicLinkW(sym_link_path_w, target_path_w, flags.is_directory); | 1808 | return os.windows.CreateSymbolicLinkW(null, sym_link_path_w, target_path_w, flags.is_directory); |
| 1797 | } | 1809 | } |
| 1798 | | 1810 | |
| 1799 | /// Same as `symLinkAbsolute` except the parameters are null-terminated pointers. | 1811 | /// Same as `symLinkAbsolute` except the parameters are null-terminated pointers. |