| author | |
| committer | |
| log | f2227ae6776112f952f7db1c0a0eb2a0a27cf576 |
| tree | 3d6ce48d8015bd19a541e7a4d289507367fbda1e |
| parent | 328ae41468f3514251ac1b0726c41eca9fbc3fb5 |
3 files changed, 48 insertions(+), 38 deletions(-)
lib/std/fs.zig+10-1| ... | ... | @@ -643,10 +643,19 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 { |
| 643 | 643 | // symlink, not the path that the symlink points to. We want the path |
| 644 | 644 | // that the symlink points to, though, so we need to get the realpath. |
| 645 | 645 | const pathname_w = try windows.wToPrefixedFileW(null, image_path_name); |
| 646 | return std.fs.cwd().realpathW(pathname_w.span(), out_buffer) catch |err| switch (err) { | |
| 646 | ||
| 647 | var wide_buf: [windows.PATH_MAX_WIDE]u16 = undefined; | |
| 648 | const wide_slice = std.fs.cwd().realpathW(pathname_w.span(), &wide_buf) catch |err| switch (err) { | |
| 647 | 649 | error.InvalidWtf8 => unreachable, |
| 648 | 650 | else => |e| return e, |
| 649 | 651 | }; |
| 652 | ||
| 653 | const len = std.unicode.calcWtf8Len(wide_slice); | |
| 654 | if (len > out_buffer.len) | |
| 655 | return error.NameTooLong; | |
| 656 | ||
| 657 | const end_index = std.unicode.wtf16LeToWtf8(out_buffer, wide_slice); | |
| 658 | return out_buffer[0..end_index]; | |
| 650 | 659 | }, |
| 651 | 660 | else => @compileError("std.fs.selfExePath not supported for this target"), |
| 652 | 661 | } |
lib/std/fs/Dir.zig+23-11| ... | ... | @@ -1370,7 +1370,16 @@ pub fn realpath(self: Dir, pathname: []const u8, out_buffer: []u8) RealPathError |
| 1370 | 1370 | } |
| 1371 | 1371 | if (native_os == .windows) { |
| 1372 | 1372 | const pathname_w = try windows.sliceToPrefixedFileW(self.fd, pathname); |
| 1373 | return self.realpathW(pathname_w.span(), out_buffer); | |
| 1373 | ||
| 1374 | var wide_buf: [windows.PATH_MAX_WIDE]u16 = undefined; | |
| 1375 | const wide_slice = try self.realpathW(pathname_w.span(), &wide_buf); | |
| 1376 | ||
| 1377 | const len = std.unicode.calcWtf8Len(wide_slice); | |
| 1378 | if (len > out_buffer.len) | |
| 1379 | return error.NameTooLong; | |
| 1380 | ||
| 1381 | const end_index = std.unicode.wtf16LeToWtf8(out_buffer, wide_slice); | |
| 1382 | return out_buffer[0..end_index]; | |
| 1374 | 1383 | } |
| 1375 | 1384 | const pathname_c = try posix.toPosixPath(pathname); |
| 1376 | 1385 | return self.realpathZ(&pathname_c, out_buffer); |
| ... | ... | @@ -1381,7 +1390,16 @@ pub fn realpath(self: Dir, pathname: []const u8, out_buffer: []u8) RealPathError |
| 1381 | 1390 | pub fn realpathZ(self: Dir, pathname: [*:0]const u8, out_buffer: []u8) RealPathError![]u8 { |
| 1382 | 1391 | if (native_os == .windows) { |
| 1383 | 1392 | const pathname_w = try windows.cStrToPrefixedFileW(self.fd, pathname); |
| 1384 | return self.realpathW(pathname_w.span(), out_buffer); | |
| 1393 | ||
| 1394 | var wide_buf: [windows.PATH_MAX_WIDE]u16 = undefined; | |
| 1395 | const wide_slice = try self.realpathW(pathname_w.span(), &wide_buf); | |
| 1396 | ||
| 1397 | const len = std.unicode.calcWtf8Len(wide_slice); | |
| 1398 | if (len > out_buffer.len) | |
| 1399 | return error.NameTooLong; | |
| 1400 | ||
| 1401 | const end_index = std.unicode.wtf16LeToWtf8(out_buffer, wide_slice); | |
| 1402 | return out_buffer[0..end_index]; | |
| 1385 | 1403 | } |
| 1386 | 1404 | |
| 1387 | 1405 | var flags: posix.O = .{}; |
| ... | ... | @@ -1411,9 +1429,9 @@ pub fn realpathZ(self: Dir, pathname: [*:0]const u8, out_buffer: []u8) RealPathE |
| 1411 | 1429 | } |
| 1412 | 1430 | |
| 1413 | 1431 | /// Windows-only. Same as `Dir.realpath` except `pathname` is WTF16 LE encoded. |
| 1414 | /// The result is encoded as [WTF-8](https://simonsapin.github.io/wtf-8/). | |
| 1432 | /// The result is encoded as WTF16 LE. | |
| 1415 | 1433 | /// See also `Dir.realpath`, `realpathW`. |
| 1416 | pub fn realpathW(self: Dir, pathname: []const u16, out_buffer: []u8) RealPathError![]u8 { | |
| 1434 | pub fn realpathW(self: Dir, pathname: []const u16, out_buffer: []u16) RealPathError![]u16 { | |
| 1417 | 1435 | const w = windows; |
| 1418 | 1436 | |
| 1419 | 1437 | const access_mask = w.GENERIC_READ | w.SYNCHRONIZE; |
| ... | ... | @@ -1434,13 +1452,7 @@ pub fn realpathW(self: Dir, pathname: []const u16, out_buffer: []u8) RealPathErr |
| 1434 | 1452 | }; |
| 1435 | 1453 | defer w.CloseHandle(h_file); |
| 1436 | 1454 | |
| 1437 | var wide_buf: [w.PATH_MAX_WIDE]u16 = undefined; | |
| 1438 | const wide_slice = try w.GetFinalPathNameByHandle(h_file, .{}, &wide_buf); | |
| 1439 | const len = std.unicode.calcWtf8Len(wide_slice); | |
| 1440 | if (len > out_buffer.len) | |
| 1441 | return error.NameTooLong; | |
| 1442 | const end_index = std.unicode.wtf16LeToWtf8(out_buffer, wide_slice); | |
| 1443 | return out_buffer[0..end_index]; | |
| 1455 | return w.GetFinalPathNameByHandle(h_file, .{}, out_buffer); | |
| 1444 | 1456 | } |
| 1445 | 1457 | |
| 1446 | 1458 | pub const RealPathAllocError = RealPathError || Allocator.Error; |
lib/std/posix.zig+15-26| ... | ... | @@ -5676,7 +5676,12 @@ pub const RealPathError = error{ |
| 5676 | 5676 | pub fn realpath(pathname: []const u8, out_buffer: *[max_path_bytes]u8) RealPathError![]u8 { |
| 5677 | 5677 | if (native_os == .windows) { |
| 5678 | 5678 | const pathname_w = try windows.sliceToPrefixedFileW(null, pathname); |
| 5679 | return realpathW(pathname_w.span(), out_buffer); | |
| 5679 | ||
| 5680 | var wide_buf: [windows.PATH_MAX_WIDE]u16 = undefined; | |
| 5681 | const wide_slice = try realpathW(pathname_w.span(), &wide_buf); | |
| 5682 | ||
| 5683 | const end_index = std.unicode.wtf16LeToWtf8(out_buffer, wide_slice); | |
| 5684 | return out_buffer[0..end_index]; | |
| 5680 | 5685 | } else if (native_os == .wasi and !builtin.link_libc) { |
| 5681 | 5686 | @compileError("WASI does not support os.realpath"); |
| 5682 | 5687 | } |
| ... | ... | @@ -5690,7 +5695,12 @@ pub fn realpath(pathname: []const u8, out_buffer: *[max_path_bytes]u8) RealPathE |
| 5690 | 5695 | pub fn realpathZ(pathname: [*:0]const u8, out_buffer: *[max_path_bytes]u8) RealPathError![]u8 { |
| 5691 | 5696 | if (native_os == .windows) { |
| 5692 | 5697 | const pathname_w = try windows.cStrToPrefixedFileW(null, pathname); |
| 5693 | return realpathW(pathname_w.span(), out_buffer); | |
| 5698 | ||
| 5699 | var wide_buf: [windows.PATH_MAX_WIDE]u16 = undefined; | |
| 5700 | const wide_slice = try realpathW(pathname_w.span(), &wide_buf); | |
| 5701 | ||
| 5702 | const end_index = std.unicode.wtf16LeToWtf8(out_buffer, wide_slice); | |
| 5703 | return out_buffer[0..end_index]; | |
| 5694 | 5704 | } else if (native_os == .wasi and !builtin.link_libc) { |
| 5695 | 5705 | return realpath(mem.sliceTo(pathname, 0), out_buffer); |
| 5696 | 5706 | } |
| ... | ... | @@ -5736,32 +5746,11 @@ pub fn realpathZ(pathname: [*:0]const u8, out_buffer: *[max_path_bytes]u8) RealP |
| 5736 | 5746 | |
| 5737 | 5747 | /// Same as `realpath` except `pathname` is WTF16LE-encoded. |
| 5738 | 5748 | /// |
| 5739 | /// The result is encoded as [WTF-8](https://simonsapin.github.io/wtf-8/). | |
| 5749 | /// The result is encoded as WTF16LE. | |
| 5740 | 5750 | /// |
| 5741 | 5751 | /// Calling this function is usually a bug. |
| 5742 | pub fn realpathW(pathname: []const u16, out_buffer: *[max_path_bytes]u8) RealPathError![]u8 { | |
| 5743 | const w = windows; | |
| 5744 | ||
| 5745 | const dir = fs.cwd().fd; | |
| 5746 | const access_mask = w.GENERIC_READ | w.SYNCHRONIZE; | |
| 5747 | const share_access = w.FILE_SHARE_READ | w.FILE_SHARE_WRITE | w.FILE_SHARE_DELETE; | |
| 5748 | const creation = w.FILE_OPEN; | |
| 5749 | const h_file = blk: { | |
| 5750 | const res = w.OpenFile(pathname, .{ | |
| 5751 | .dir = dir, | |
| 5752 | .access_mask = access_mask, | |
| 5753 | .share_access = share_access, | |
| 5754 | .creation = creation, | |
| 5755 | .filter = .any, | |
| 5756 | }) catch |err| switch (err) { | |
| 5757 | error.WouldBlock => unreachable, | |
| 5758 | else => |e| return e, | |
| 5759 | }; | |
| 5760 | break :blk res; | |
| 5761 | }; | |
| 5762 | defer w.CloseHandle(h_file); | |
| 5763 | ||
| 5764 | return std.os.getFdPath(h_file, out_buffer); | |
| 5752 | pub fn realpathW(pathname: []const u16, out_buffer: *[max_path_bytes]u16) RealPathError![]u16 { | |
| 5753 | return fs.cwd().realpathW(pathname, out_buffer); | |
| 5765 | 5754 | } |
| 5766 | 5755 | |
| 5767 | 5756 | /// Spurious wakeups are possible and no precision of timing is guaranteed. |