| ... | @@ -300,6 +300,10 @@ pub const ReadError = error{ | ... | @@ -300,6 +300,10 @@ pub const ReadError = error{ |
| 300 | /// This error occurs when no global event loop is configured, | 300 | /// This error occurs when no global event loop is configured, |
| 301 | /// and reading from the file descriptor would block. | 301 | /// and reading from the file descriptor would block. |
| 302 | WouldBlock, | 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 | } || UnexpectedError; | 307 | } || UnexpectedError; |
| 304 | | 308 | |
| 305 | /// Returns the number of bytes that were read, which can be less than | 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,6 +339,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize { |
| 335 | wasi.ENOMEM => return error.SystemResources, | 339 | wasi.ENOMEM => return error.SystemResources, |
| 336 | wasi.ECONNRESET => return error.ConnectionResetByPeer, | 340 | wasi.ECONNRESET => return error.ConnectionResetByPeer, |
| 337 | wasi.ETIMEDOUT => return error.ConnectionTimedOut, | 341 | wasi.ETIMEDOUT => return error.ConnectionTimedOut, |
| | 342 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 338 | else => |err| return unexpectedErrno(err), | 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,6 +407,7 @@ pub fn readv(fd: fd_t, iov: []const iovec) ReadError!usize { |
| 402 | wasi.EISDIR => return error.IsDir, | 407 | wasi.EISDIR => return error.IsDir, |
| 403 | wasi.ENOBUFS => return error.SystemResources, | 408 | wasi.ENOBUFS => return error.SystemResources, |
| 404 | wasi.ENOMEM => return error.SystemResources, | 409 | wasi.ENOMEM => return error.SystemResources, |
| | 410 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 405 | else => |err| return unexpectedErrno(err), | 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,6 +472,7 @@ pub fn pread(fd: fd_t, buf: []u8, offset: u64) PReadError!usize { |
| 466 | wasi.ENXIO => return error.Unseekable, | 472 | wasi.ENXIO => return error.Unseekable, |
| 467 | wasi.ESPIPE => return error.Unseekable, | 473 | wasi.ESPIPE => return error.Unseekable, |
| 468 | wasi.EOVERFLOW => return error.Unseekable, | 474 | wasi.EOVERFLOW => return error.Unseekable, |
| | 475 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 469 | else => |err| return unexpectedErrno(err), | 476 | else => |err| return unexpectedErrno(err), |
| 470 | } | 477 | } |
| 471 | } | 478 | } |
| ... | @@ -502,6 +509,10 @@ pub const TruncateError = error{ | ... | @@ -502,6 +509,10 @@ pub const TruncateError = error{ |
| 502 | InputOutput, | 509 | InputOutput, |
| 503 | CannotTruncate, | 510 | CannotTruncate, |
| 504 | FileBusy, | 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 | } || UnexpectedError; | 516 | } || UnexpectedError; |
| 506 | | 517 | |
| 507 | pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void { | 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,6 +547,7 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void { |
| 536 | wasi.ETXTBSY => return error.FileBusy, | 547 | wasi.ETXTBSY => return error.FileBusy, |
| 537 | wasi.EBADF => unreachable, // Handle not open for writing | 548 | wasi.EBADF => unreachable, // Handle not open for writing |
| 538 | wasi.EINVAL => unreachable, // Handle not open for writing | 549 | wasi.EINVAL => unreachable, // Handle not open for writing |
| | 550 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 539 | else => |err| return unexpectedErrno(err), | 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,6 +616,7 @@ pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) PReadError!usize { |
| 604 | wasi.ENXIO => return error.Unseekable, | 616 | wasi.ENXIO => return error.Unseekable, |
| 605 | wasi.ESPIPE => return error.Unseekable, | 617 | wasi.ESPIPE => return error.Unseekable, |
| 606 | wasi.EOVERFLOW => return error.Unseekable, | 618 | wasi.EOVERFLOW => return error.Unseekable, |
| | 619 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 607 | else => |err| return unexpectedErrno(err), | 620 | else => |err| return unexpectedErrno(err), |
| 608 | } | 621 | } |
| 609 | } | 622 | } |
| ... | @@ -649,6 +662,10 @@ pub const WriteError = error{ | ... | @@ -649,6 +662,10 @@ pub const WriteError = error{ |
| 649 | /// This error occurs when no global event loop is configured, | 662 | /// This error occurs when no global event loop is configured, |
| 650 | /// and reading from the file descriptor would block. | 663 | /// and reading from the file descriptor would block. |
| 651 | WouldBlock, | 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 | } || UnexpectedError; | 669 | } || UnexpectedError; |
| 653 | | 670 | |
| 654 | /// Write to a file descriptor. | 671 | /// Write to a file descriptor. |
| ... | @@ -697,6 +714,7 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!usize { | ... | @@ -697,6 +714,7 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!usize { |
| 697 | wasi.ENOSPC => return error.NoSpaceLeft, | 714 | wasi.ENOSPC => return error.NoSpaceLeft, |
| 698 | wasi.EPERM => return error.AccessDenied, | 715 | wasi.EPERM => return error.AccessDenied, |
| 699 | wasi.EPIPE => return error.BrokenPipe, | 716 | wasi.EPIPE => return error.BrokenPipe, |
| | 717 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 700 | else => |err| return unexpectedErrno(err), | 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,6 +792,7 @@ pub fn writev(fd: fd_t, iov: []const iovec_const) WriteError!usize { |
| 774 | wasi.ENOSPC => return error.NoSpaceLeft, | 792 | wasi.ENOSPC => return error.NoSpaceLeft, |
| 775 | wasi.EPERM => return error.AccessDenied, | 793 | wasi.EPERM => return error.AccessDenied, |
| 776 | wasi.EPIPE => return error.BrokenPipe, | 794 | wasi.EPIPE => return error.BrokenPipe, |
| | 795 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 777 | else => |err| return unexpectedErrno(err), | 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,6 +875,7 @@ pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize { |
| 856 | wasi.ENXIO => return error.Unseekable, | 875 | wasi.ENXIO => return error.Unseekable, |
| 857 | wasi.ESPIPE => return error.Unseekable, | 876 | wasi.ESPIPE => return error.Unseekable, |
| 858 | wasi.EOVERFLOW => return error.Unseekable, | 877 | wasi.EOVERFLOW => return error.Unseekable, |
| | 878 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 859 | else => |err| return unexpectedErrno(err), | 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,6 +969,7 @@ pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) PWriteError!usiz |
| 949 | wasi.ENXIO => return error.Unseekable, | 969 | wasi.ENXIO => return error.Unseekable, |
| 950 | wasi.ESPIPE => return error.Unseekable, | 970 | wasi.ESPIPE => return error.Unseekable, |
| 951 | wasi.EOVERFLOW => return error.Unseekable, | 971 | wasi.EOVERFLOW => return error.Unseekable, |
| | 972 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 952 | else => |err| return unexpectedErrno(err), | 973 | else => |err| return unexpectedErrno(err), |
| 953 | } | 974 | } |
| 954 | } | 975 | } |
| ... | @@ -1020,6 +1041,10 @@ pub const OpenError = error{ | ... | @@ -1020,6 +1041,10 @@ pub const OpenError = error{ |
| 1020 | | 1041 | |
| 1021 | /// The underlying filesystem does not support file locks | 1042 | /// The underlying filesystem does not support file locks |
| 1022 | FileLocksNotSupported, | 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 | } || UnexpectedError; | 1048 | } || UnexpectedError; |
| 1024 | | 1049 | |
| 1025 | /// Open and possibly create a file. Keeps trying if it gets interrupted. | 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,6 +1138,7 @@ pub fn openatWasi(dir_fd: fd_t, file_path: []const u8, oflags: oflags_t, fdflags |
| 1113 | wasi.EPERM => return error.AccessDenied, | 1138 | wasi.EPERM => return error.AccessDenied, |
| 1114 | wasi.EEXIST => return error.PathAlreadyExists, | 1139 | wasi.EEXIST => return error.PathAlreadyExists, |
| 1115 | wasi.EBUSY => return error.DeviceBusy, | 1140 | wasi.EBUSY => return error.DeviceBusy, |
| | 1141 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 1116 | else => |err| return unexpectedErrno(err), | 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,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 | /// Similar to `symlink`, however, creates a symbolic link named `sym_link_path` which contains the string | 1598 | /// Similar to `symlink`, however, creates a symbolic link named `sym_link_path` which contains the string |
| 1567 | /// `target_path` **relative** to `newdirfd` directory handle. | 1599 | /// `target_path` **relative** to `newdirfd` directory handle. |
| 1568 | /// A symbolic link (also known as a soft link) may point to an existing file or to a nonexistent | 1600 | /// A symbolic link (also known as a soft link) may point to an existing file or to a nonexistent |
| 1569 | /// one; the latter case is known as a dangling link. | 1601 | /// one; the latter case is known as a dangling link. |
| 1570 | /// If `sym_link_path` exists, it will not be overwritten. | 1602 | /// If `sym_link_path` exists, it will not be overwritten. |
| 1571 | /// See also `symlinkatWasi`, `symlinkatZ` and `symlinkatW`. | 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 | if (builtin.os.tag == .wasi) { | 1605 | if (builtin.os.tag == .wasi) { |
| 1574 | return symlinkatWasi(target_path, newdirfd, sym_link_path); | 1606 | return symlinkatWasi(target_path, newdirfd, sym_link_path); |
| 1575 | } | 1607 | } |
| ... | @@ -1587,7 +1619,7 @@ pub const symlinkatC = @compileError("deprecated: renamed to symlinkatZ"); | ... | @@ -1587,7 +1619,7 @@ pub const symlinkatC = @compileError("deprecated: renamed to symlinkatZ"); |
| 1587 | | 1619 | |
| 1588 | /// WASI-only. The same as `symlinkat` but targeting WASI. | 1620 | /// WASI-only. The same as `symlinkat` but targeting WASI. |
| 1589 | /// See also `symlinkat`. | 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 | switch (wasi.path_symlink(target_path.ptr, target_path.len, newdirfd, sym_link_path.ptr, sym_link_path.len)) { | 1623 | switch (wasi.path_symlink(target_path.ptr, target_path.len, newdirfd, sym_link_path.ptr, sym_link_path.len)) { |
| 1592 | wasi.ESUCCESS => {}, | 1624 | wasi.ESUCCESS => {}, |
| 1593 | wasi.EFAULT => unreachable, | 1625 | wasi.EFAULT => unreachable, |
| ... | @@ -1604,19 +1636,20 @@ pub fn symlinkatWasi(target_path: []const u8, newdirfd: fd_t, sym_link_path: []c | ... | @@ -1604,19 +1636,20 @@ pub fn symlinkatWasi(target_path: []const u8, newdirfd: fd_t, sym_link_path: []c |
| 1604 | wasi.ENOMEM => return error.SystemResources, | 1636 | wasi.ENOMEM => return error.SystemResources, |
| 1605 | wasi.ENOSPC => return error.NoSpaceLeft, | 1637 | wasi.ENOSPC => return error.NoSpaceLeft, |
| 1606 | wasi.EROFS => return error.ReadOnlyFileSystem, | 1638 | wasi.EROFS => return error.ReadOnlyFileSystem, |
| | 1639 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 1607 | else => |err| return unexpectedErrno(err), | 1640 | else => |err| return unexpectedErrno(err), |
| 1608 | } | 1641 | } |
| 1609 | } | 1642 | } |
| 1610 | | 1643 | |
| 1611 | /// Windows-only. The same as `symlinkat` except the paths are null-terminated, WTF-16 encoded. | 1644 | /// Windows-only. The same as `symlinkat` except the paths are null-terminated, WTF-16 encoded. |
| 1612 | /// See also `symlinkat`. | 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 | @compileError("TODO implement on Windows"); | 1647 | @compileError("TODO implement on Windows"); |
| 1615 | } | 1648 | } |
| 1616 | | 1649 | |
| 1617 | /// The same as `symlinkat` except the parameters are null-terminated pointers. | 1650 | /// The same as `symlinkat` except the parameters are null-terminated pointers. |
| 1618 | /// See also `symlinkat`. | 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 | if (builtin.os.tag == .windows) { | 1653 | if (builtin.os.tag == .windows) { |
| 1621 | const target_path_w = try windows.cStrToPrefixedFileW(target_path); | 1654 | const target_path_w = try windows.cStrToPrefixedFileW(target_path); |
| 1622 | const sym_link_path_w = try windows.cStrToPrefixedFileW(sym_link_path); | 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,6 +1739,10 @@ pub fn unlinkZ(file_path: [*:0]const u8) UnlinkError!void { |
| 1706 | pub const UnlinkatError = UnlinkError || error{ | 1739 | pub const UnlinkatError = UnlinkError || error{ |
| 1707 | /// When passing `AT_REMOVEDIR`, this error occurs when the named directory is not empty. | 1740 | /// When passing `AT_REMOVEDIR`, this error occurs when the named directory is not empty. |
| 1708 | DirNotEmpty, | 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 | /// Delete a file name and possibly the file it refers to, based on an open directory handle. | 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,6 +1784,7 @@ pub fn unlinkatWasi(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatErro |
| 1747 | wasi.ENOMEM => return error.SystemResources, | 1784 | wasi.ENOMEM => return error.SystemResources, |
| 1748 | wasi.EROFS => return error.ReadOnlyFileSystem, | 1785 | wasi.EROFS => return error.ReadOnlyFileSystem, |
| 1749 | wasi.ENOTEMPTY => return error.DirNotEmpty, | 1786 | wasi.ENOTEMPTY => return error.DirNotEmpty, |
| | 1787 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 1750 | | 1788 | |
| 1751 | wasi.EINVAL => unreachable, // invalid flags, or pathname has . as last component | 1789 | wasi.EINVAL => unreachable, // invalid flags, or pathname has . as last component |
| 1752 | wasi.EBADF => unreachable, // always a race condition | 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,13 +1963,19 @@ pub fn renameW(old_path: [*:0]const u16, new_path: [*:0]const u16) RenameError!v |
| 1925 | return windows.MoveFileExW(old_path, new_path, flags); | 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 | /// Change the name or location of a file based on an open directory handle. | 1972 | /// Change the name or location of a file based on an open directory handle. |
| 1929 | pub fn renameat( | 1973 | pub fn renameat( |
| 1930 | old_dir_fd: fd_t, | 1974 | old_dir_fd: fd_t, |
| 1931 | old_path: []const u8, | 1975 | old_path: []const u8, |
| 1932 | new_dir_fd: fd_t, | 1976 | new_dir_fd: fd_t, |
| 1933 | new_path: []const u8, | 1977 | new_path: []const u8, |
| 1934 | ) RenameError!void { | 1978 | ) RenameatError!void { |
| 1935 | if (builtin.os.tag == .windows) { | 1979 | if (builtin.os.tag == .windows) { |
| 1936 | const old_path_w = try windows.sliceToPrefixedFileW(old_path); | 1980 | const old_path_w = try windows.sliceToPrefixedFileW(old_path); |
| 1937 | const new_path_w = try windows.sliceToPrefixedFileW(new_path); | 1981 | const new_path_w = try windows.sliceToPrefixedFileW(new_path); |
| ... | @@ -1947,7 +1991,7 @@ pub fn renameat( | ... | @@ -1947,7 +1991,7 @@ pub fn renameat( |
| 1947 | | 1991 | |
| 1948 | /// WASI-only. Same as `renameat` expect targeting WASI. | 1992 | /// WASI-only. Same as `renameat` expect targeting WASI. |
| 1949 | /// See also `renameat`. | 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 | switch (wasi.path_rename(old_dir_fd, old_path.ptr, old_path.len, new_dir_fd, new_path.ptr, new_path.len)) { | 1995 | switch (wasi.path_rename(old_dir_fd, old_path.ptr, old_path.len, new_dir_fd, new_path.ptr, new_path.len)) { |
| 1952 | wasi.ESUCCESS => return, | 1996 | wasi.ESUCCESS => return, |
| 1953 | wasi.EACCES => return error.AccessDenied, | 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,6 +2012,7 @@ pub fn renameatWasi(old_dir_fd: fd_t, old_path: []const u8, new_dir_fd: fd_t, ne |
| 1968 | wasi.ENOTEMPTY => return error.PathAlreadyExists, | 2012 | wasi.ENOTEMPTY => return error.PathAlreadyExists, |
| 1969 | wasi.EROFS => return error.ReadOnlyFileSystem, | 2013 | wasi.EROFS => return error.ReadOnlyFileSystem, |
| 1970 | wasi.EXDEV => return error.RenameAcrossMountPoints, | 2014 | wasi.EXDEV => return error.RenameAcrossMountPoints, |
| | 2015 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 1971 | else => |err| return unexpectedErrno(err), | 2016 | else => |err| return unexpectedErrno(err), |
| 1972 | } | 2017 | } |
| 1973 | } | 2018 | } |
| ... | @@ -1978,7 +2023,7 @@ pub fn renameatZ( | ... | @@ -1978,7 +2023,7 @@ pub fn renameatZ( |
| 1978 | old_path: [*:0]const u8, | 2023 | old_path: [*:0]const u8, |
| 1979 | new_dir_fd: fd_t, | 2024 | new_dir_fd: fd_t, |
| 1980 | new_path: [*:0]const u8, | 2025 | new_path: [*:0]const u8, |
| 1981 | ) RenameError!void { | 2026 | ) RenameatError!void { |
| 1982 | if (builtin.os.tag == .windows) { | 2027 | if (builtin.os.tag == .windows) { |
| 1983 | const old_path_w = try windows.cStrToPrefixedFileW(old_path); | 2028 | const old_path_w = try windows.cStrToPrefixedFileW(old_path); |
| 1984 | const new_path_w = try windows.cStrToPrefixedFileW(new_path); | 2029 | const new_path_w = try windows.cStrToPrefixedFileW(new_path); |
| ... | @@ -2017,7 +2062,7 @@ pub fn renameatW( | ... | @@ -2017,7 +2062,7 @@ pub fn renameatW( |
| 2017 | new_dir_fd: fd_t, | 2062 | new_dir_fd: fd_t, |
| 2018 | new_path_w: []const u16, | 2063 | new_path_w: []const u16, |
| 2019 | ReplaceIfExists: windows.BOOLEAN, | 2064 | ReplaceIfExists: windows.BOOLEAN, |
| 2020 | ) RenameError!void { | 2065 | ) RenameatError!void { |
| 2021 | const src_fd = windows.OpenFile(old_path_w, .{ | 2066 | const src_fd = windows.OpenFile(old_path_w, .{ |
| 2022 | .dir = old_dir_fd, | 2067 | .dir = old_dir_fd, |
| 2023 | .access_mask = windows.SYNCHRONIZE | windows.GENERIC_WRITE | windows.DELETE, | 2068 | .access_mask = windows.SYNCHRONIZE | windows.GENERIC_WRITE | windows.DELETE, |
| ... | @@ -2066,24 +2111,13 @@ pub fn renameatW( | ... | @@ -2066,24 +2111,13 @@ pub fn renameatW( |
| 2066 | } | 2111 | } |
| 2067 | } | 2112 | } |
| 2068 | | 2113 | |
| 2069 | pub const MakeDirError = error{ | 2114 | pub const MakeDirAtError = error{ |
| 2070 | AccessDenied, | 2115 | /// WASI-only. This error occurs when the file descriptor does |
| 2071 | DiskQuota, | 2116 | /// not hold the required rights to create a new directory relative to it. |
| 2072 | PathAlreadyExists, | 2117 | NotCapable, |
| 2073 | SymLinkLoop, | 2118 | } || MakeDirError; |
| 2074 | LinkQuotaExceeded, | | |
| 2075 | NameTooLong, | | |
| 2076 | FileNotFound, | | |
| 2077 | SystemResources, | | |
| 2078 | NoSpaceLeft, | | |
| 2079 | NotDir, | | |
| 2080 | ReadOnlyFileSystem, | | |
| 2081 | InvalidUtf8, | | |
| 2082 | BadPathName, | | |
| 2083 | NoDevice, | | |
| 2084 | } || UnexpectedError; | | |
| 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 | if (builtin.os.tag == .windows) { | 2121 | if (builtin.os.tag == .windows) { |
| 2088 | const sub_dir_path_w = try windows.sliceToPrefixedFileW(sub_dir_path); | 2122 | const sub_dir_path_w = try windows.sliceToPrefixedFileW(sub_dir_path); |
| 2089 | return mkdiratW(dir_fd, sub_dir_path_w.span().ptr, mode); | 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,7 +2131,7 @@ pub fn mkdirat(dir_fd: fd_t, sub_dir_path: []const u8, mode: u32) MakeDirError!v |
| 2097 | | 2131 | |
| 2098 | pub const mkdiratC = @compileError("deprecated: renamed to mkdiratZ"); | 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 | switch (wasi.path_create_directory(dir_fd, sub_dir_path.ptr, sub_dir_path.len)) { | 2135 | switch (wasi.path_create_directory(dir_fd, sub_dir_path.ptr, sub_dir_path.len)) { |
| 2102 | wasi.ESUCCESS => return, | 2136 | wasi.ESUCCESS => return, |
| 2103 | wasi.EACCES => return error.AccessDenied, | 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,11 +2148,12 @@ pub fn mkdiratWasi(dir_fd: fd_t, sub_dir_path: []const u8, mode: u32) MakeDirErr |
| 2114 | wasi.ENOSPC => return error.NoSpaceLeft, | 2148 | wasi.ENOSPC => return error.NoSpaceLeft, |
| 2115 | wasi.ENOTDIR => return error.NotDir, | 2149 | wasi.ENOTDIR => return error.NotDir, |
| 2116 | wasi.EROFS => return error.ReadOnlyFileSystem, | 2150 | wasi.EROFS => return error.ReadOnlyFileSystem, |
| | 2151 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 2117 | else => |err| return unexpectedErrno(err), | 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 | if (builtin.os.tag == .windows) { | 2157 | if (builtin.os.tag == .windows) { |
| 2123 | const sub_dir_path_w = try windows.cStrToPrefixedFileW(sub_dir_path); | 2158 | const sub_dir_path_w = try windows.cStrToPrefixedFileW(sub_dir_path); |
| 2124 | return mkdiratW(dir_fd, sub_dir_path_w.span().ptr, mode); | 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,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 | const sub_dir_handle = try windows.CreateDirectoryW(dir_fd, sub_path_w, null); | 2182 | const sub_dir_handle = try windows.CreateDirectoryW(dir_fd, sub_path_w, null); |
| 2148 | windows.CloseHandle(sub_dir_handle); | 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 | /// Create a directory. | 2203 | /// Create a directory. |
| 2152 | /// `mode` is ignored on Windows. | 2204 | /// `mode` is ignored on Windows. |
| 2153 | pub fn mkdir(dir_path: []const u8, mode: u32) MakeDirError!void { | 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,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 | /// Similar to `readlink` except reads value of a symbolink link **relative** to `dirfd` directory handle. | 2425 | /// Similar to `readlink` except reads value of a symbolink link **relative** to `dirfd` directory handle. |
| 2368 | /// The return value is a slice of `out_buffer` from index 0. | 2426 | /// The return value is a slice of `out_buffer` from index 0. |
| 2369 | /// See also `readlinkatWasi`, `realinkatZ` and `realinkatW`. | 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 | if (builtin.os.tag == .wasi) { | 2429 | if (builtin.os.tag == .wasi) { |
| 2372 | return readlinkatWasi(dirfd, file_path, out_buffer); | 2430 | return readlinkatWasi(dirfd, file_path, out_buffer); |
| 2373 | } | 2431 | } |
| ... | @@ -2383,7 +2441,7 @@ pub const readlinkatC = @compileError("deprecated: renamed to readlinkatZ"); | ... | @@ -2383,7 +2441,7 @@ pub const readlinkatC = @compileError("deprecated: renamed to readlinkatZ"); |
| 2383 | | 2441 | |
| 2384 | /// WASI-only. Same as `readlinkat` but targets WASI. | 2442 | /// WASI-only. Same as `readlinkat` but targets WASI. |
| 2385 | /// See also `readlinkat`. | 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 | var bufused: usize = undefined; | 2445 | var bufused: usize = undefined; |
| 2388 | switch (wasi.path_readlink(dirfd, file_path.ptr, file_path.len, out_buffer.ptr, out_buffer.len, &bufused)) { | 2446 | switch (wasi.path_readlink(dirfd, file_path.ptr, file_path.len, out_buffer.ptr, out_buffer.len, &bufused)) { |
| 2389 | wasi.ESUCCESS => return out_buffer[0..bufused], | 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,19 +2454,20 @@ pub fn readlinkatWasi(dirfd: fd_t, file_path: []const u8, out_buffer: []u8) Read |
| 2396 | wasi.ENOENT => return error.FileNotFound, | 2454 | wasi.ENOENT => return error.FileNotFound, |
| 2397 | wasi.ENOMEM => return error.SystemResources, | 2455 | wasi.ENOMEM => return error.SystemResources, |
| 2398 | wasi.ENOTDIR => return error.NotDir, | 2456 | wasi.ENOTDIR => return error.NotDir, |
| | 2457 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 2399 | else => |err| return unexpectedErrno(err), | 2458 | else => |err| return unexpectedErrno(err), |
| 2400 | } | 2459 | } |
| 2401 | } | 2460 | } |
| 2402 | | 2461 | |
| 2403 | /// Windows-only. Same as `readlinkat` except `file_path` is null-terminated, WTF16 encoded. | 2462 | /// Windows-only. Same as `readlinkat` except `file_path` is null-terminated, WTF16 encoded. |
| 2404 | /// See also `readlinkat`. | 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 | @compileError("TODO implement on Windows"); | 2465 | @compileError("TODO implement on Windows"); |
| 2407 | } | 2466 | } |
| 2408 | | 2467 | |
| 2409 | /// Same as `readlinkat` except `file_path` is null-terminated. | 2468 | /// Same as `readlinkat` except `file_path` is null-terminated. |
| 2410 | /// See also `readlinkat`. | 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 | if (builtin.os.tag == .windows) { | 2471 | if (builtin.os.tag == .windows) { |
| 2413 | const file_path_w = try windows.cStrToPrefixedFileW(file_path); | 2472 | const file_path_w = try windows.cStrToPrefixedFileW(file_path); |
| 2414 | return readlinkatW(dirfd, file_path_w.span().ptr, out_buffer); | 2473 | return readlinkatW(dirfd, file_path_w.span().ptr, out_buffer); |
| ... | @@ -3074,6 +3133,10 @@ pub fn waitpid(pid: i32, flags: u32) u32 { | ... | @@ -3074,6 +3133,10 @@ pub fn waitpid(pid: i32, flags: u32) u32 { |
| 3074 | pub const FStatError = error{ | 3133 | pub const FStatError = error{ |
| 3075 | SystemResources, | 3134 | SystemResources, |
| 3076 | AccessDenied, | 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 | } || UnexpectedError; | 3140 | } || UnexpectedError; |
| 3078 | | 3141 | |
| 3079 | /// Return information about a file descriptor. | 3142 | /// Return information about a file descriptor. |
| ... | @@ -3086,6 +3149,7 @@ pub fn fstat(fd: fd_t) FStatError!Stat { | ... | @@ -3086,6 +3149,7 @@ pub fn fstat(fd: fd_t) FStatError!Stat { |
| 3086 | wasi.EBADF => unreachable, // Always a race condition. | 3149 | wasi.EBADF => unreachable, // Always a race condition. |
| 3087 | wasi.ENOMEM => return error.SystemResources, | 3150 | wasi.ENOMEM => return error.SystemResources, |
| 3088 | wasi.EACCES => return error.AccessDenied, | 3151 | wasi.EACCES => return error.AccessDenied, |
| | 3152 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 3089 | else => |err| return unexpectedErrno(err), | 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,6 +3200,7 @@ pub fn fstatatWasi(dirfd: fd_t, pathname: []const u8, flags: u32) FStatAtError!S |
| 3136 | wasi.ENAMETOOLONG => return error.NameTooLong, | 3200 | wasi.ENAMETOOLONG => return error.NameTooLong, |
| 3137 | wasi.ENOENT => return error.FileNotFound, | 3201 | wasi.ENOENT => return error.FileNotFound, |
| 3138 | wasi.ENOTDIR => return error.FileNotFound, | 3202 | wasi.ENOTDIR => return error.FileNotFound, |
| | 3203 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 3139 | else => |err| return unexpectedErrno(err), | 3204 | else => |err| return unexpectedErrno(err), |
| 3140 | } | 3205 | } |
| 3141 | } | 3206 | } |
| ... | @@ -3641,7 +3706,13 @@ pub fn gettimeofday(tv: ?*timeval, tz: ?*timezone) void { | ... | @@ -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 | /// Repositions read/write file offset relative to the beginning. | 3717 | /// Repositions read/write file offset relative to the beginning. |
| 3647 | pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void { | 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,6 +3740,7 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void { |
| 3669 | wasi.EOVERFLOW => return error.Unseekable, | 3740 | wasi.EOVERFLOW => return error.Unseekable, |
| 3670 | wasi.ESPIPE => return error.Unseekable, | 3741 | wasi.ESPIPE => return error.Unseekable, |
| 3671 | wasi.ENXIO => return error.Unseekable, | 3742 | wasi.ENXIO => return error.Unseekable, |
| | 3743 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 3672 | else => |err| return unexpectedErrno(err), | 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,6 +3782,7 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void { |
| 3710 | wasi.EOVERFLOW => return error.Unseekable, | 3782 | wasi.EOVERFLOW => return error.Unseekable, |
| 3711 | wasi.ESPIPE => return error.Unseekable, | 3783 | wasi.ESPIPE => return error.Unseekable, |
| 3712 | wasi.ENXIO => return error.Unseekable, | 3784 | wasi.ENXIO => return error.Unseekable, |
| | 3785 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 3713 | else => |err| return unexpectedErrno(err), | 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,6 +3823,7 @@ pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void { |
| 3750 | wasi.EOVERFLOW => return error.Unseekable, | 3823 | wasi.EOVERFLOW => return error.Unseekable, |
| 3751 | wasi.ESPIPE => return error.Unseekable, | 3824 | wasi.ESPIPE => return error.Unseekable, |
| 3752 | wasi.ENXIO => return error.Unseekable, | 3825 | wasi.ENXIO => return error.Unseekable, |
| | 3826 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 3753 | else => |err| return unexpectedErrno(err), | 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,6 +3864,7 @@ pub fn lseek_CUR_get(fd: fd_t) SeekError!u64 { |
| 3790 | wasi.EOVERFLOW => return error.Unseekable, | 3864 | wasi.EOVERFLOW => return error.Unseekable, |
| 3791 | wasi.ESPIPE => return error.Unseekable, | 3865 | wasi.ESPIPE => return error.Unseekable, |
| 3792 | wasi.ENXIO => return error.Unseekable, | 3866 | wasi.ENXIO => return error.Unseekable, |
| | 3867 | wasi.ENOTCAPABLE => return error.NotCapable, |
| 3793 | else => |err| return unexpectedErrno(err), | 3868 | else => |err| return unexpectedErrno(err), |
| 3794 | } | 3869 | } |
| 3795 | } | 3870 | } |