| ... | @@ -37,7 +37,7 @@ pub const Watch = @import("fs/watch.zig").Watch; | ... | @@ -37,7 +37,7 @@ pub const Watch = @import("fs/watch.zig").Watch; |
| 37 | /// fit into a UTF-8 encoded array of this length. | 37 | /// fit into a UTF-8 encoded array of this length. |
| 38 | /// The byte count includes room for a null sentinel byte. | 38 | /// The byte count includes room for a null sentinel byte. |
| 39 | pub const MAX_PATH_BYTES = switch (builtin.os.tag) { | 39 | pub const MAX_PATH_BYTES = switch (builtin.os.tag) { |
| 40 | .linux, .macosx, .ios, .freebsd, .netbsd, .dragonfly => os.PATH_MAX, | 40 | .linux, .macosx, .ios, .freebsd, .netbsd, .dragonfly, .wasi => os.PATH_MAX, |
| 41 | // Each UTF-16LE character may be expanded to 3 UTF-8 bytes. | 41 | // Each UTF-16LE character may be expanded to 3 UTF-8 bytes. |
| 42 | // If it would require 4 UTF-8 bytes, then there would be a surrogate | 42 | // If it would require 4 UTF-8 bytes, then there would be a surrogate |
| 43 | // pair in the UTF-16LE, and we (over)account 3 bytes for it that way. | 43 | // pair in the UTF-16LE, and we (over)account 3 bytes for it that way. |
| ... | @@ -584,10 +584,33 @@ pub const Dir = struct { | ... | @@ -584,10 +584,33 @@ pub const Dir = struct { |
| 584 | const path_w = try os.windows.sliceToPrefixedFileW(sub_path); | 584 | const path_w = try os.windows.sliceToPrefixedFileW(sub_path); |
| 585 | return self.openFileW(path_w.span(), flags); | 585 | return self.openFileW(path_w.span(), flags); |
| 586 | } | 586 | } |
| | 587 | if (builtin.os.tag == .wasi) { |
| | 588 | return self.openFileWasi(sub_path, flags); |
| | 589 | } |
| 587 | const path_c = try os.toPosixPath(sub_path); | 590 | const path_c = try os.toPosixPath(sub_path); |
| 588 | return self.openFileZ(&path_c, flags); | 591 | return self.openFileZ(&path_c, flags); |
| 589 | } | 592 | } |
| 590 | | 593 | |
| | 594 | pub fn openFileWasi(self: Dir, sub_path: []const u8, flags: File.OpenFlags) File.OpenError!File { |
| | 595 | var fdflags: wasi.fdflag_t = 0x0; |
| | 596 | var rights: wasi.rights_t = 0x0; |
| | 597 | if (flags.read) { |
| | 598 | rights |= wasi.FD_READ | wasi.FD_TELL | wasi.FD_FILESTAT_GET; |
| | 599 | } |
| | 600 | if (flags.write) { |
| | 601 | fdflags |= wasi.FDFLAG_APPEND; |
| | 602 | rights |= wasi.FD_WRITE | wasi.FD_DATASYNC | wasi.FD_SEEK | wasi.FD_FDSTAT_SET_FLAGS | wasi.FD_SYNC | wasi.FD_ALLOCATE | wasi.FD_ADVISE | wasi.FD_FILESTAT_SET_TIMES | wasi.FD_FILESTAT_SET_SIZE; |
| | 603 | } |
| | 604 | |
| | 605 | const fd = try os.openatWasi(self.fd, sub_path, 0x0, fdflags, rights); |
| | 606 | |
| | 607 | return File{ |
| | 608 | .handle = fd, |
| | 609 | .io_mode = .blocking, |
| | 610 | .async_block_allowed = File.async_block_allowed_no, |
| | 611 | }; |
| | 612 | } |
| | 613 | |
| 591 | pub const openFileC = @compileError("deprecated: renamed to openFileZ"); | 614 | pub const openFileC = @compileError("deprecated: renamed to openFileZ"); |
| 592 | | 615 | |
| 593 | /// Same as `openFile` but the path parameter is null-terminated. | 616 | /// Same as `openFile` but the path parameter is null-terminated. |
| ... | @@ -671,12 +694,37 @@ pub const Dir = struct { | ... | @@ -671,12 +694,37 @@ pub const Dir = struct { |
| 671 | const path_w = try os.windows.sliceToPrefixedFileW(sub_path); | 694 | const path_w = try os.windows.sliceToPrefixedFileW(sub_path); |
| 672 | return self.createFileW(path_w.span(), flags); | 695 | return self.createFileW(path_w.span(), flags); |
| 673 | } | 696 | } |
| | 697 | if (builtin.os.tag == .wasi) { |
| | 698 | return self.createFileWasi(sub_path, flags); |
| | 699 | } |
| 674 | const path_c = try os.toPosixPath(sub_path); | 700 | const path_c = try os.toPosixPath(sub_path); |
| 675 | return self.createFileZ(&path_c, flags); | 701 | return self.createFileZ(&path_c, flags); |
| 676 | } | 702 | } |
| 677 | | 703 | |
| 678 | pub const createFileC = @compileError("deprecated: renamed to createFileZ"); | 704 | pub const createFileC = @compileError("deprecated: renamed to createFileZ"); |
| 679 | | 705 | |
| | 706 | pub fn createFileWasi(self: Dir, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File { |
| | 707 | var oflags: wasi.oflags_t = 0x0; |
| | 708 | var rights: wasi.rights_t = wasi.FD_WRITE | wasi.FD_DATASYNC | wasi.FD_SEEK | wasi.FD_FDSTAT_SET_FLAGS | wasi.FD_SYNC | wasi.FD_ALLOCATE | wasi.FD_ADVISE | wasi.FD_FILESTAT_SET_TIMES | wasi.FD_FILESTAT_SET_SIZE; |
| | 709 | if (flags.read) { |
| | 710 | rights |= wasi.FD_READ | wasi.FD_TELL | wasi.FD_FILESTAT_GET; |
| | 711 | } |
| | 712 | if (flags.truncate) { |
| | 713 | oflags |= wasi.O_TRUNC; |
| | 714 | } |
| | 715 | if (flags.exclusive) { |
| | 716 | oflags |= wasi.O_EXCL; |
| | 717 | } |
| | 718 | |
| | 719 | const fd = try os.openatWasi(self.fd, sub_path, oflags, 0x0, rights); |
| | 720 | |
| | 721 | return File{ |
| | 722 | .handle = fd, |
| | 723 | .io_mode = .blocking, |
| | 724 | .async_block_allowed = File.async_block_allowed_no, |
| | 725 | }; |
| | 726 | } |
| | 727 | |
| 680 | /// Same as `createFile` but the path parameter is null-terminated. | 728 | /// Same as `createFile` but the path parameter is null-terminated. |
| 681 | pub fn createFileZ(self: Dir, sub_path_c: [*:0]const u8, flags: File.CreateFlags) File.OpenError!File { | 729 | pub fn createFileZ(self: Dir, sub_path_c: [*:0]const u8, flags: File.CreateFlags) File.OpenError!File { |
| 682 | if (builtin.os.tag == .windows) { | 730 | if (builtin.os.tag == .windows) { |