| ... | ... | @@ -66,15 +66,7 @@ pub const need_async_thread = std.io.is_async and switch (builtin.os.tag) { |
| 66 | 66 | |
| 67 | 67 | /// TODO remove the allocator requirement from this API |
| 68 | 68 | pub fn atomicSymLink(allocator: *Allocator, existing_path: []const u8, new_path: []const u8) !void { |
| 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) { |
| 69 | if (cwd().symLink(existing_path, new_path, .{})) { |
| 78 | 70 | return; |
| 79 | 71 | } else |err| switch (err) { |
| 80 | 72 | error.PathAlreadyExists => {}, |
| ... | ... | @@ -92,15 +84,7 @@ pub fn atomicSymLink(allocator: *Allocator, existing_path: []const u8, new_path: |
| 92 | 84 | try crypto.randomBytes(rand_buf[0..]); |
| 93 | 85 | base64_encoder.encode(tmp_path[dirname.len + 1 ..], &rand_buf); |
| 94 | 86 | |
| 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) { |
| 87 | if (cwd().symLink(existing_path, new_path, .{})) { |
| 104 | 88 | return rename(tmp_path, new_path); |
| 105 | 89 | } else |err| switch (err) { |
| 106 | 90 | error.PathAlreadyExists => continue, |
| ... | ... | @@ -1239,10 +1223,12 @@ pub const Dir = struct { |
| 1239 | 1223 | flags: SymLinkFlags, |
| 1240 | 1224 | ) !void { |
| 1241 | 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 | 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 | 1233 | const target_path_c = try os.toPosixPath(target_path); |
| 1248 | 1234 | const sym_link_path_c = try os.toPosixPath(sym_link_path); |
| ... | ... | @@ -1250,15 +1236,41 @@ pub const Dir = struct { |
| 1250 | 1236 | } |
| 1251 | 1237 | |
| 1252 | 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 | 1245 | return os.symlinkatWasi(target_path, self.fd, sym_link_path); |
| 1255 | 1246 | } |
| 1256 | 1247 | |
| 1257 | 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 | 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 | 1274 | /// Read value of a symbolic link. |
| 1263 | 1275 | /// The return value is a slice of `buffer`, from index `0`. |
| 1264 | 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 | 1773 | pub const readLink = @compileError("deprecated; use Dir.readLink or readLinkAbsolute"); |
| 1762 | 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 |
| 1765 | | /// or a directory. This value is ignored on all hosts except Windows where |
| 1766 | | /// creating symlinks to different resource types, requires different flags. |
| 1767 | | /// By default, `symLinkAbsolute` is assumed to point to a file. |
| 1776 | /// Use with `Dir.symLink` and `symLinkAbsolute` to specify whether the symlink |
| 1777 | /// will point to a file or a directory. This value is ignored on all hosts |
| 1778 | /// except Windows where creating symlinks to different resource types, requires |
| 1779 | /// different flags. By default, `symLinkAbsolute` is assumed to point to a file. |
| 1768 | 1780 | pub const SymLinkFlags = struct { |
| 1769 | 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 | 1793 | assert(path.isAbsolute(target_path)); |
| 1782 | 1794 | assert(path.isAbsolute(sym_link_path)); |
| 1783 | 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 | 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 | 1802 | /// Note that this function will by default try creating a symbolic link to a file. If you would |
| 1791 | 1803 | /// like to create a symbolic link to a directory, specify this with `SymLinkFlags{ .is_directory = true }`. |
| 1792 | 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 | 1806 | assert(path.isAbsoluteWindowsW(target_path_w)); |
| 1795 | 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 | 1811 | /// Same as `symLinkAbsolute` except the parameters are null-terminated pointers. |