| ... | ... | @@ -300,6 +300,10 @@ pub const ReadError = error{ |
| 300 | 300 | /// This error occurs when no global event loop is configured, |
| 301 | 301 | /// and reading from the file descriptor would block. |
| 302 | 302 | WouldBlock, |
| 303 | |
| 304 | /// WASI-only. This error occurs when the file descriptor does |
| 305 | /// not hold the required rights to read from it. |
| 306 | NotCapable, |
| 303 | 307 | } || UnexpectedError; |
| 304 | 308 | |
| 305 | 309 | /// Returns the number of bytes that were read, which can be less than |
| ... | ... | @@ -335,6 +339,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize { |
| 335 | 339 | wasi.ENOMEM => return error.SystemResources, |
| 336 | 340 | wasi.ECONNRESET => return error.ConnectionResetByPeer, |
| 337 | 341 | wasi.ETIMEDOUT => return error.ConnectionTimedOut, |
| 342 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 338 | 343 | else => |err| return unexpectedErrno(err), |
| 339 | 344 | } |
| 340 | 345 | } |
| ... | ... | @@ -402,6 +407,7 @@ pub fn readv(fd: fd_t, iov: []const iovec) ReadError!usize { |
| 402 | 407 | wasi.EISDIR => return error.IsDir, |
| 403 | 408 | wasi.ENOBUFS => return error.SystemResources, |
| 404 | 409 | wasi.ENOMEM => return error.SystemResources, |
| 410 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 405 | 411 | else => |err| return unexpectedErrno(err), |
| 406 | 412 | } |
| 407 | 413 | } |
| ... | ... | @@ -466,6 +472,7 @@ pub fn pread(fd: fd_t, buf: []u8, offset: u64) PReadError!usize { |
| 466 | 472 | wasi.ENXIO => return error.Unseekable, |
| 467 | 473 | wasi.ESPIPE => return error.Unseekable, |
| 468 | 474 | wasi.EOVERFLOW => return error.Unseekable, |
| 475 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 469 | 476 | else => |err| return unexpectedErrno(err), |
| 470 | 477 | } |
| 471 | 478 | } |
| ... | ... | @@ -502,6 +509,10 @@ pub const TruncateError = error{ |
| 502 | 509 | InputOutput, |
| 503 | 510 | CannotTruncate, |
| 504 | 511 | FileBusy, |
| 512 | |
| 513 | /// WASI-only. This error occurs when the file descriptor does |
| 514 | /// not hold the required rights to call `ftruncate` on it. |
| 515 | NotCapable, |
| 505 | 516 | } || UnexpectedError; |
| 506 | 517 | |
| 507 | 518 | pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void { |
| ... | ... | @@ -536,6 +547,7 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void { |
| 536 | 547 | wasi.ETXTBSY => return error.FileBusy, |
| 537 | 548 | wasi.EBADF => unreachable, // Handle not open for writing |
| 538 | 549 | wasi.EINVAL => unreachable, // Handle not open for writing |
| 550 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 539 | 551 | else => |err| return unexpectedErrno(err), |
| 540 | 552 | } |
| 541 | 553 | } |
| ... | ... | @@ -604,6 +616,7 @@ pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) PReadError!usize { |
| 604 | 616 | wasi.ENXIO => return error.Unseekable, |
| 605 | 617 | wasi.ESPIPE => return error.Unseekable, |
| 606 | 618 | wasi.EOVERFLOW => return error.Unseekable, |
| 619 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 607 | 620 | else => |err| return unexpectedErrno(err), |
| 608 | 621 | } |
| 609 | 622 | } |
| ... | ... | @@ -649,6 +662,10 @@ pub const WriteError = error{ |
| 649 | 662 | /// This error occurs when no global event loop is configured, |
| 650 | 663 | /// and reading from the file descriptor would block. |
| 651 | 664 | WouldBlock, |
| 665 | |
| 666 | /// WASI-only. This error occurs when the file descriptor does |
| 667 | /// not hold the required rights to write to it. |
| 668 | NotCapable, |
| 652 | 669 | } || UnexpectedError; |
| 653 | 670 | |
| 654 | 671 | /// Write to a file descriptor. |
| ... | ... | @@ -697,6 +714,7 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!usize { |
| 697 | 714 | wasi.ENOSPC => return error.NoSpaceLeft, |
| 698 | 715 | wasi.EPERM => return error.AccessDenied, |
| 699 | 716 | wasi.EPIPE => return error.BrokenPipe, |
| 717 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 700 | 718 | else => |err| return unexpectedErrno(err), |
| 701 | 719 | } |
| 702 | 720 | } |
| ... | ... | @@ -774,6 +792,7 @@ pub fn writev(fd: fd_t, iov: []const iovec_const) WriteError!usize { |
| 774 | 792 | wasi.ENOSPC => return error.NoSpaceLeft, |
| 775 | 793 | wasi.EPERM => return error.AccessDenied, |
| 776 | 794 | wasi.EPIPE => return error.BrokenPipe, |
| 795 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 777 | 796 | else => |err| return unexpectedErrno(err), |
| 778 | 797 | } |
| 779 | 798 | } |
| ... | ... | @@ -856,6 +875,7 @@ pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize { |
| 856 | 875 | wasi.ENXIO => return error.Unseekable, |
| 857 | 876 | wasi.ESPIPE => return error.Unseekable, |
| 858 | 877 | wasi.EOVERFLOW => return error.Unseekable, |
| 878 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 859 | 879 | else => |err| return unexpectedErrno(err), |
| 860 | 880 | } |
| 861 | 881 | } |
| ... | ... | @@ -949,6 +969,7 @@ pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) PWriteError!usiz |
| 949 | 969 | wasi.ENXIO => return error.Unseekable, |
| 950 | 970 | wasi.ESPIPE => return error.Unseekable, |
| 951 | 971 | wasi.EOVERFLOW => return error.Unseekable, |
| 972 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 952 | 973 | else => |err| return unexpectedErrno(err), |
| 953 | 974 | } |
| 954 | 975 | } |
| ... | ... | @@ -1020,6 +1041,10 @@ pub const OpenError = error{ |
| 1020 | 1041 | |
| 1021 | 1042 | /// The underlying filesystem does not support file locks |
| 1022 | 1043 | FileLocksNotSupported, |
| 1044 | |
| 1045 | /// WASI-only. This error occurs when the file descriptor does |
| 1046 | /// not hold the required rights to open a new resource relative to it. |
| 1047 | NotCapable, |
| 1023 | 1048 | } || UnexpectedError; |
| 1024 | 1049 | |
| 1025 | 1050 | /// Open and possibly create a file. Keeps trying if it gets interrupted. |
| ... | ... | @@ -1113,6 +1138,7 @@ pub fn openatWasi(dir_fd: fd_t, file_path: []const u8, oflags: oflags_t, fdflags |
| 1113 | 1138 | wasi.EPERM => return error.AccessDenied, |
| 1114 | 1139 | wasi.EEXIST => return error.PathAlreadyExists, |
| 1115 | 1140 | wasi.EBUSY => return error.DeviceBusy, |
| 1141 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 1116 | 1142 | else => |err| return unexpectedErrno(err), |
| 1117 | 1143 | } |
| 1118 | 1144 | } |
| ... | ... | @@ -1563,13 +1589,19 @@ pub fn symlinkZ(target_path: [*:0]const u8, sym_link_path: [*:0]const u8) SymLin |
| 1563 | 1589 | } |
| 1564 | 1590 | } |
| 1565 | 1591 | |
| 1592 | pub const SymlinkatError = error{ |
| 1593 | /// WASI-only. This error occurs when the file descriptor does |
| 1594 | /// not hold the required rights to create a new symbolic link relative to it. |
| 1595 | NotCapable, |
| 1596 | } || SymlinkError; |
| 1597 | |
| 1566 | 1598 | /// Similar to `symlink`, however, creates a symbolic link named `sym_link_path` which contains the string |
| 1567 | 1599 | /// `target_path` **relative** to `newdirfd` directory handle. |
| 1568 | 1600 | /// A symbolic link (also known as a soft link) may point to an existing file or to a nonexistent |
| 1569 | 1601 | /// one; the latter case is known as a dangling link. |
| 1570 | 1602 | /// If `sym_link_path` exists, it will not be overwritten. |
| 1571 | 1603 | /// See also `symlinkatWasi`, `symlinkatZ` and `symlinkatW`. |
| 1572 | | pub fn symlinkat(target_path: []const u8, newdirfd: fd_t, sym_link_path: []const u8) SymLinkError!void { |
| 1604 | pub fn symlinkat(target_path: []const u8, newdirfd: fd_t, sym_link_path: []const u8) SymLinkatError!void { |
| 1573 | 1605 | if (builtin.os.tag == .wasi) { |
| 1574 | 1606 | return symlinkatWasi(target_path, newdirfd, sym_link_path); |
| 1575 | 1607 | } |
| ... | ... | @@ -1587,7 +1619,7 @@ pub const symlinkatC = @compileError("deprecated: renamed to symlinkatZ"); |
| 1587 | 1619 | |
| 1588 | 1620 | /// WASI-only. The same as `symlinkat` but targeting WASI. |
| 1589 | 1621 | /// See also `symlinkat`. |
| 1590 | | pub fn symlinkatWasi(target_path: []const u8, newdirfd: fd_t, sym_link_path: []const u8) SymLinkError!void { |
| 1622 | pub fn symlinkatWasi(target_path: []const u8, newdirfd: fd_t, sym_link_path: []const u8) SymLinkatError!void { |
| 1591 | 1623 | switch (wasi.path_symlink(target_path.ptr, target_path.len, newdirfd, sym_link_path.ptr, sym_link_path.len)) { |
| 1592 | 1624 | wasi.ESUCCESS => {}, |
| 1593 | 1625 | wasi.EFAULT => unreachable, |
| ... | ... | @@ -1604,19 +1636,20 @@ pub fn symlinkatWasi(target_path: []const u8, newdirfd: fd_t, sym_link_path: []c |
| 1604 | 1636 | wasi.ENOMEM => return error.SystemResources, |
| 1605 | 1637 | wasi.ENOSPC => return error.NoSpaceLeft, |
| 1606 | 1638 | wasi.EROFS => return error.ReadOnlyFileSystem, |
| 1639 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 1607 | 1640 | else => |err| return unexpectedErrno(err), |
| 1608 | 1641 | } |
| 1609 | 1642 | } |
| 1610 | 1643 | |
| 1611 | 1644 | /// Windows-only. The same as `symlinkat` except the paths are null-terminated, WTF-16 encoded. |
| 1612 | 1645 | /// See also `symlinkat`. |
| 1613 | | pub fn symlinkatW(target_path: [*:0]const u16, newdirfd: fd_t, sym_link_path: [*:0]const u16) SymlinkError!void { |
| 1646 | pub fn symlinkatW(target_path: [*:0]const u16, newdirfd: fd_t, sym_link_path: [*:0]const u16) SymlinkatError!void { |
| 1614 | 1647 | @compileError("TODO implement on Windows"); |
| 1615 | 1648 | } |
| 1616 | 1649 | |
| 1617 | 1650 | /// The same as `symlinkat` except the parameters are null-terminated pointers. |
| 1618 | 1651 | /// See also `symlinkat`. |
| 1619 | | pub fn symlinkatZ(target_path: [*:0]const u8, newdirfd: fd_t, sym_link_path: [*:0]const u8) SymLinkError!void { |
| 1652 | pub fn symlinkatZ(target_path: [*:0]const u8, newdirfd: fd_t, sym_link_path: [*:0]const u8) SymLinkatError!void { |
| 1620 | 1653 | if (builtin.os.tag == .windows) { |
| 1621 | 1654 | const target_path_w = try windows.cStrToPrefixedFileW(target_path); |
| 1622 | 1655 | const sym_link_path_w = try windows.cStrToPrefixedFileW(sym_link_path); |
| ... | ... | @@ -1706,6 +1739,10 @@ pub fn unlinkZ(file_path: [*:0]const u8) UnlinkError!void { |
| 1706 | 1739 | pub const UnlinkatError = UnlinkError || error{ |
| 1707 | 1740 | /// When passing `AT_REMOVEDIR`, this error occurs when the named directory is not empty. |
| 1708 | 1741 | DirNotEmpty, |
| 1742 | |
| 1743 | /// WASI-only. This error occurs when the file descriptor does |
| 1744 | /// not hold the required rights to unlink a resource by path relative to it. |
| 1745 | NotCapable, |
| 1709 | 1746 | }; |
| 1710 | 1747 | |
| 1711 | 1748 | /// Delete a file name and possibly the file it refers to, based on an open directory handle. |
| ... | ... | @@ -1747,6 +1784,7 @@ pub fn unlinkatWasi(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatErro |
| 1747 | 1784 | wasi.ENOMEM => return error.SystemResources, |
| 1748 | 1785 | wasi.EROFS => return error.ReadOnlyFileSystem, |
| 1749 | 1786 | wasi.ENOTEMPTY => return error.DirNotEmpty, |
| 1787 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 1750 | 1788 | |
| 1751 | 1789 | wasi.EINVAL => unreachable, // invalid flags, or pathname has . as last component |
| 1752 | 1790 | wasi.EBADF => unreachable, // always a race condition |
| ... | ... | @@ -1925,13 +1963,19 @@ pub fn renameW(old_path: [*:0]const u16, new_path: [*:0]const u16) RenameError!v |
| 1925 | 1963 | return windows.MoveFileExW(old_path, new_path, flags); |
| 1926 | 1964 | } |
| 1927 | 1965 | |
| 1966 | pub const RenameatError = error{ |
| 1967 | /// WASI-only. This error occurs when the file descriptor does |
| 1968 | /// not hold the required rights to rename a resource by path relative to it. |
| 1969 | NotCapable, |
| 1970 | } || RenameError; |
| 1971 | |
| 1928 | 1972 | /// Change the name or location of a file based on an open directory handle. |
| 1929 | 1973 | pub fn renameat( |
| 1930 | 1974 | old_dir_fd: fd_t, |
| 1931 | 1975 | old_path: []const u8, |
| 1932 | 1976 | new_dir_fd: fd_t, |
| 1933 | 1977 | new_path: []const u8, |
| 1934 | | ) RenameError!void { |
| 1978 | ) RenameatError!void { |
| 1935 | 1979 | if (builtin.os.tag == .windows) { |
| 1936 | 1980 | const old_path_w = try windows.sliceToPrefixedFileW(old_path); |
| 1937 | 1981 | const new_path_w = try windows.sliceToPrefixedFileW(new_path); |
| ... | ... | @@ -1947,7 +1991,7 @@ pub fn renameat( |
| 1947 | 1991 | |
| 1948 | 1992 | /// WASI-only. Same as `renameat` expect targeting WASI. |
| 1949 | 1993 | /// See also `renameat`. |
| 1950 | | pub fn renameatWasi(old_dir_fd: fd_t, old_path: []const u8, new_dir_fd: fd_t, new_path: []const u8) RenameError!void { |
| 1994 | pub fn renameatWasi(old_dir_fd: fd_t, old_path: []const u8, new_dir_fd: fd_t, new_path: []const u8) RenameatError!void { |
| 1951 | 1995 | switch (wasi.path_rename(old_dir_fd, old_path.ptr, old_path.len, new_dir_fd, new_path.ptr, new_path.len)) { |
| 1952 | 1996 | wasi.ESUCCESS => return, |
| 1953 | 1997 | wasi.EACCES => return error.AccessDenied, |
| ... | ... | @@ -1968,6 +2012,7 @@ pub fn renameatWasi(old_dir_fd: fd_t, old_path: []const u8, new_dir_fd: fd_t, ne |
| 1968 | 2012 | wasi.ENOTEMPTY => return error.PathAlreadyExists, |
| 1969 | 2013 | wasi.EROFS => return error.ReadOnlyFileSystem, |
| 1970 | 2014 | wasi.EXDEV => return error.RenameAcrossMountPoints, |
| 2015 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 1971 | 2016 | else => |err| return unexpectedErrno(err), |
| 1972 | 2017 | } |
| 1973 | 2018 | } |
| ... | ... | @@ -1978,7 +2023,7 @@ pub fn renameatZ( |
| 1978 | 2023 | old_path: [*:0]const u8, |
| 1979 | 2024 | new_dir_fd: fd_t, |
| 1980 | 2025 | new_path: [*:0]const u8, |
| 1981 | | ) RenameError!void { |
| 2026 | ) RenameatError!void { |
| 1982 | 2027 | if (builtin.os.tag == .windows) { |
| 1983 | 2028 | const old_path_w = try windows.cStrToPrefixedFileW(old_path); |
| 1984 | 2029 | const new_path_w = try windows.cStrToPrefixedFileW(new_path); |
| ... | ... | @@ -2017,7 +2062,7 @@ pub fn renameatW( |
| 2017 | 2062 | new_dir_fd: fd_t, |
| 2018 | 2063 | new_path_w: []const u16, |
| 2019 | 2064 | ReplaceIfExists: windows.BOOLEAN, |
| 2020 | | ) RenameError!void { |
| 2065 | ) RenameatError!void { |
| 2021 | 2066 | const src_fd = windows.OpenFile(old_path_w, .{ |
| 2022 | 2067 | .dir = old_dir_fd, |
| 2023 | 2068 | .access_mask = windows.SYNCHRONIZE | windows.GENERIC_WRITE | windows.DELETE, |
| ... | ... | @@ -2066,24 +2111,13 @@ pub fn renameatW( |
| 2066 | 2111 | } |
| 2067 | 2112 | } |
| 2068 | 2113 | |
| 2069 | | pub const MakeDirError = error{ |
| 2070 | | AccessDenied, |
| 2071 | | DiskQuota, |
| 2072 | | PathAlreadyExists, |
| 2073 | | SymLinkLoop, |
| 2074 | | LinkQuotaExceeded, |
| 2075 | | NameTooLong, |
| 2076 | | FileNotFound, |
| 2077 | | SystemResources, |
| 2078 | | NoSpaceLeft, |
| 2079 | | NotDir, |
| 2080 | | ReadOnlyFileSystem, |
| 2081 | | InvalidUtf8, |
| 2082 | | BadPathName, |
| 2083 | | NoDevice, |
| 2084 | | } || UnexpectedError; |
| 2114 | pub const MakeDirAtError = error{ |
| 2115 | /// WASI-only. This error occurs when the file descriptor does |
| 2116 | /// not hold the required rights to create a new directory relative to it. |
| 2117 | NotCapable, |
| 2118 | } || MakeDirError; |
| 2085 | 2119 | |
| 2086 | | pub fn mkdirat(dir_fd: fd_t, sub_dir_path: []const u8, mode: u32) MakeDirError!void { |
| 2120 | pub fn mkdirat(dir_fd: fd_t, sub_dir_path: []const u8, mode: u32) MakeDirAtError!void { |
| 2087 | 2121 | if (builtin.os.tag == .windows) { |
| 2088 | 2122 | const sub_dir_path_w = try windows.sliceToPrefixedFileW(sub_dir_path); |
| 2089 | 2123 | return mkdiratW(dir_fd, sub_dir_path_w.span().ptr, mode); |
| ... | ... | @@ -2097,7 +2131,7 @@ pub fn mkdirat(dir_fd: fd_t, sub_dir_path: []const u8, mode: u32) MakeDirError!v |
| 2097 | 2131 | |
| 2098 | 2132 | pub const mkdiratC = @compileError("deprecated: renamed to mkdiratZ"); |
| 2099 | 2133 | |
| 2100 | | pub fn mkdiratWasi(dir_fd: fd_t, sub_dir_path: []const u8, mode: u32) MakeDirError!void { |
| 2134 | pub fn mkdiratWasi(dir_fd: fd_t, sub_dir_path: []const u8, mode: u32) MakeDirAtError!void { |
| 2101 | 2135 | switch (wasi.path_create_directory(dir_fd, sub_dir_path.ptr, sub_dir_path.len)) { |
| 2102 | 2136 | wasi.ESUCCESS => return, |
| 2103 | 2137 | wasi.EACCES => return error.AccessDenied, |
| ... | ... | @@ -2114,11 +2148,12 @@ pub fn mkdiratWasi(dir_fd: fd_t, sub_dir_path: []const u8, mode: u32) MakeDirErr |
| 2114 | 2148 | wasi.ENOSPC => return error.NoSpaceLeft, |
| 2115 | 2149 | wasi.ENOTDIR => return error.NotDir, |
| 2116 | 2150 | wasi.EROFS => return error.ReadOnlyFileSystem, |
| 2151 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 2117 | 2152 | else => |err| return unexpectedErrno(err), |
| 2118 | 2153 | } |
| 2119 | 2154 | } |
| 2120 | 2155 | |
| 2121 | | pub fn mkdiratZ(dir_fd: fd_t, sub_dir_path: [*:0]const u8, mode: u32) MakeDirError!void { |
| 2156 | pub fn mkdiratZ(dir_fd: fd_t, sub_dir_path: [*:0]const u8, mode: u32) MakeDirAtError!void { |
| 2122 | 2157 | if (builtin.os.tag == .windows) { |
| 2123 | 2158 | const sub_dir_path_w = try windows.cStrToPrefixedFileW(sub_dir_path); |
| 2124 | 2159 | return mkdiratW(dir_fd, sub_dir_path_w.span().ptr, mode); |
| ... | ... | @@ -2143,11 +2178,28 @@ pub fn mkdiratZ(dir_fd: fd_t, sub_dir_path: [*:0]const u8, mode: u32) MakeDirErr |
| 2143 | 2178 | } |
| 2144 | 2179 | } |
| 2145 | 2180 | |
| 2146 | | pub fn mkdiratW(dir_fd: fd_t, sub_path_w: [*:0]const u16, mode: u32) MakeDirError!void { |
| 2181 | pub fn mkdiratW(dir_fd: fd_t, sub_path_w: [*:0]const u16, mode: u32) MakeDirAtError!void { |
| 2147 | 2182 | const sub_dir_handle = try windows.CreateDirectoryW(dir_fd, sub_path_w, null); |
| 2148 | 2183 | windows.CloseHandle(sub_dir_handle); |
| 2149 | 2184 | } |
| 2150 | 2185 | |
| 2186 | pub const MakeDirError = error{ |
| 2187 | AccessDenied, |
| 2188 | DiskQuota, |
| 2189 | PathAlreadyExists, |
| 2190 | SymLinkLoop, |
| 2191 | LinkQuotaExceeded, |
| 2192 | NameTooLong, |
| 2193 | FileNotFound, |
| 2194 | SystemResources, |
| 2195 | NoSpaceLeft, |
| 2196 | NotDir, |
| 2197 | ReadOnlyFileSystem, |
| 2198 | InvalidUtf8, |
| 2199 | BadPathName, |
| 2200 | NoDevice, |
| 2201 | } || UnexpectedError; |
| 2202 | |
| 2151 | 2203 | /// Create a directory. |
| 2152 | 2204 | /// `mode` is ignored on Windows. |
| 2153 | 2205 | pub fn mkdir(dir_path: []const u8, mode: u32) MakeDirError!void { |
| ... | ... | @@ -2364,10 +2416,16 @@ pub fn readlinkZ(file_path: [*:0]const u8, out_buffer: []u8) ReadLinkError![]u8 |
| 2364 | 2416 | } |
| 2365 | 2417 | } |
| 2366 | 2418 | |
| 2419 | pub const ReadLinkAtError = error{ |
| 2420 | /// WASI-only. This error occurs when the file descriptor does |
| 2421 | /// not hold the required rights to read value of a symbolic link relative to it. |
| 2422 | NotCapable, |
| 2423 | } || ReadLinkError; |
| 2424 | |
| 2367 | 2425 | /// Similar to `readlink` except reads value of a symbolink link **relative** to `dirfd` directory handle. |
| 2368 | 2426 | /// The return value is a slice of `out_buffer` from index 0. |
| 2369 | 2427 | /// See also `readlinkatWasi`, `realinkatZ` and `realinkatW`. |
| 2370 | | pub fn readlinkat(dirfd: fd_t, file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 { |
| 2428 | pub fn readlinkat(dirfd: fd_t, file_path: []const u8, out_buffer: []u8) ReadLinkAtError![]u8 { |
| 2371 | 2429 | if (builtin.os.tag == .wasi) { |
| 2372 | 2430 | return readlinkatWasi(dirfd, file_path, out_buffer); |
| 2373 | 2431 | } |
| ... | ... | @@ -2383,7 +2441,7 @@ pub const readlinkatC = @compileError("deprecated: renamed to readlinkatZ"); |
| 2383 | 2441 | |
| 2384 | 2442 | /// WASI-only. Same as `readlinkat` but targets WASI. |
| 2385 | 2443 | /// See also `readlinkat`. |
| 2386 | | pub fn readlinkatWasi(dirfd: fd_t, file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 { |
| 2444 | pub fn readlinkatWasi(dirfd: fd_t, file_path: []const u8, out_buffer: []u8) ReadLinkAtError![]u8 { |
| 2387 | 2445 | var bufused: usize = undefined; |
| 2388 | 2446 | switch (wasi.path_readlink(dirfd, file_path.ptr, file_path.len, out_buffer.ptr, out_buffer.len, &bufused)) { |
| 2389 | 2447 | wasi.ESUCCESS => return out_buffer[0..bufused], |
| ... | ... | @@ -2396,19 +2454,20 @@ pub fn readlinkatWasi(dirfd: fd_t, file_path: []const u8, out_buffer: []u8) Read |
| 2396 | 2454 | wasi.ENOENT => return error.FileNotFound, |
| 2397 | 2455 | wasi.ENOMEM => return error.SystemResources, |
| 2398 | 2456 | wasi.ENOTDIR => return error.NotDir, |
| 2457 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 2399 | 2458 | else => |err| return unexpectedErrno(err), |
| 2400 | 2459 | } |
| 2401 | 2460 | } |
| 2402 | 2461 | |
| 2403 | 2462 | /// Windows-only. Same as `readlinkat` except `file_path` is null-terminated, WTF16 encoded. |
| 2404 | 2463 | /// See also `readlinkat`. |
| 2405 | | pub fn readlinkatW(dirfd: fd_t, file_path: [*:0]const u16, out_buffer: []u8) ReadLinkError![]u8 { |
| 2464 | pub fn readlinkatW(dirfd: fd_t, file_path: [*:0]const u16, out_buffer: []u8) ReadLinkAtError![]u8 { |
| 2406 | 2465 | @compileError("TODO implement on Windows"); |
| 2407 | 2466 | } |
| 2408 | 2467 | |
| 2409 | 2468 | /// Same as `readlinkat` except `file_path` is null-terminated. |
| 2410 | 2469 | /// See also `readlinkat`. |
| 2411 | | pub fn readlinkatZ(dirfd: fd_t, file_path: [*:0]const u8, out_buffer: []u8) ReadLinkError![]u8 { |
| 2470 | pub fn readlinkatZ(dirfd: fd_t, file_path: [*:0]const u8, out_buffer: []u8) ReadLinkAtError![]u8 { |
| 2412 | 2471 | if (builtin.os.tag == .windows) { |
| 2413 | 2472 | const file_path_w = try windows.cStrToPrefixedFileW(file_path); |
| 2414 | 2473 | return readlinkatW(dirfd, file_path_w.span().ptr, out_buffer); |
| ... | ... | @@ -3074,6 +3133,10 @@ pub fn waitpid(pid: i32, flags: u32) u32 { |
| 3074 | 3133 | pub const FStatError = error{ |
| 3075 | 3134 | SystemResources, |
| 3076 | 3135 | AccessDenied, |
| 3136 | |
| 3137 | /// WASI-only. This error occurs when the file descriptor does |
| 3138 | /// not hold the required rights to get its filestat information. |
| 3139 | NotCapable, |
| 3077 | 3140 | } || UnexpectedError; |
| 3078 | 3141 | |
| 3079 | 3142 | /// Return information about a file descriptor. |
| ... | ... | @@ -3086,6 +3149,7 @@ pub fn fstat(fd: fd_t) FStatError!Stat { |
| 3086 | 3149 | wasi.EBADF => unreachable, // Always a race condition. |
| 3087 | 3150 | wasi.ENOMEM => return error.SystemResources, |
| 3088 | 3151 | wasi.EACCES => return error.AccessDenied, |
| 3152 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 3089 | 3153 | else => |err| return unexpectedErrno(err), |
| 3090 | 3154 | } |
| 3091 | 3155 | } |
| ... | ... | @@ -3136,6 +3200,7 @@ pub fn fstatatWasi(dirfd: fd_t, pathname: []const u8, flags: u32) FStatAtError!S |
| 3136 | 3200 | wasi.ENAMETOOLONG => return error.NameTooLong, |
| 3137 | 3201 | wasi.ENOENT => return error.FileNotFound, |
| 3138 | 3202 | wasi.ENOTDIR => return error.FileNotFound, |
| 3203 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 3139 | 3204 | else => |err| return unexpectedErrno(err), |
| 3140 | 3205 | } |
| 3141 | 3206 | } |
| ... | ... | @@ -3641,7 +3706,13 @@ pub fn gettimeofday(tv: ?*timeval, tz: ?*timezone) void { |
| 3641 | 3706 | } |
| 3642 | 3707 | } |
| 3643 | 3708 | |
| 3644 | | pub const SeekError = error{Unseekable} || UnexpectedError; |
| 3709 | pub const SeekError = error{ |
| 3710 | Unseekable, |
| 3711 | |
| 3712 | /// WASI-only. This error occurs when the file descriptor does |
| 3713 | /// not hold the required rights to seek on it. |
| 3714 | NotCapable, |
| 3715 | } || UnexpectedError; |
| 3645 | 3716 | |
| 3646 | 3717 | /// Repositions read/write file offset relative to the beginning. |
| 3647 | 3718 | pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void { |
| ... | ... | @@ -3669,6 +3740,7 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void { |
| 3669 | 3740 | wasi.EOVERFLOW => return error.Unseekable, |
| 3670 | 3741 | wasi.ESPIPE => return error.Unseekable, |
| 3671 | 3742 | wasi.ENXIO => return error.Unseekable, |
| 3743 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 3672 | 3744 | else => |err| return unexpectedErrno(err), |
| 3673 | 3745 | } |
| 3674 | 3746 | } |
| ... | ... | @@ -3710,6 +3782,7 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void { |
| 3710 | 3782 | wasi.EOVERFLOW => return error.Unseekable, |
| 3711 | 3783 | wasi.ESPIPE => return error.Unseekable, |
| 3712 | 3784 | wasi.ENXIO => return error.Unseekable, |
| 3785 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 3713 | 3786 | else => |err| return unexpectedErrno(err), |
| 3714 | 3787 | } |
| 3715 | 3788 | } |
| ... | ... | @@ -3750,6 +3823,7 @@ pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void { |
| 3750 | 3823 | wasi.EOVERFLOW => return error.Unseekable, |
| 3751 | 3824 | wasi.ESPIPE => return error.Unseekable, |
| 3752 | 3825 | wasi.ENXIO => return error.Unseekable, |
| 3826 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 3753 | 3827 | else => |err| return unexpectedErrno(err), |
| 3754 | 3828 | } |
| 3755 | 3829 | } |
| ... | ... | @@ -3790,6 +3864,7 @@ pub fn lseek_CUR_get(fd: fd_t) SeekError!u64 { |
| 3790 | 3864 | wasi.EOVERFLOW => return error.Unseekable, |
| 3791 | 3865 | wasi.ESPIPE => return error.Unseekable, |
| 3792 | 3866 | wasi.ENXIO => return error.Unseekable, |
| 3867 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 3793 | 3868 | else => |err| return unexpectedErrno(err), |
| 3794 | 3869 | } |
| 3795 | 3870 | } |