diff --git a/core/os/os_wasi.odin b/core/os/os_wasi.odin index 266833a31..584f2f85f 100644 --- a/core/os/os_wasi.odin +++ b/core/os/os_wasi.odin @@ -27,29 +27,76 @@ stderr: Handle = 2 write :: proc(fd: Handle, data: []byte) -> (int, Errno) { iovs := wasi.ciovec_t(data) - n, err := wasi.fd_write(wasi.fd_t(fd), &iovs, 1) + n, err := wasi.fd_write(wasi.fd_t(fd), {iovs}) return int(n), Errno(err) } read :: proc(fd: Handle, data: []byte) -> (int, Errno) { iovs := wasi.iovec_t(data) - n, err := wasi.fd_read(wasi.fd_t(fd), &iovs, 1) + n, err := wasi.fd_read(wasi.fd_t(fd), {iovs}) return int(n), Errno(err) } write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Errno) { iovs := wasi.ciovec_t(data) - n, err := wasi.fd_pwrite(wasi.fd_t(fd), &iovs, 1, wasi.filesize_t(offset)) + n, err := wasi.fd_pwrite(wasi.fd_t(fd), {iovs}, wasi.filesize_t(offset)) return int(n), Errno(err) } read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Errno) { iovs := wasi.iovec_t(data) - n, err := wasi.fd_pread(wasi.fd_t(fd), &iovs, 1, wasi.filesize_t(offset)) + n, err := wasi.fd_pread(wasi.fd_t(fd), {iovs}, wasi.filesize_t(offset)) return int(n), Errno(err) } open :: proc(path: string, mode: int = O_RDONLY, perm: int = 0) -> (Handle, Errno) { - return 0, 0 + flags: wasi.oflags_t + fs_rights_base: wasi.rights_t + fs_rights_inheriting: wasi.rights_t + fdflags: wasi.fdflags_t + + if mode & O_RDONLY == O_RDONLY { + fs_rights_base += {.FD_READ} + } + if mode & O_WRONLY == O_WRONLY { + fs_rights_base += {.FD_WRITE} + } + if mode & O_RDWR == O_RDWR { + fs_rights_base += {.FD_READ, .FD_WRITE} + } + if mode & O_CREATE == O_CREATE { + flags += {.CREATE} + fs_rights_base += {.FD_WRITE} + } + if mode & O_EXCL == O_EXCL { + flags += {.EXCL} + } + if mode & O_NOCTTY == O_NOCTTY { + + } + if mode & O_TRUNC == O_TRUNC { + flags += {.TRUNC} + } + if mode & O_NONBLOCK == O_NONBLOCK { + fdflags += {.NONBLOCK} + } + if mode & O_APPEND == O_APPEND { + fdflags += {.APPEND} + } + if mode & O_SYNC == O_SYNC { + fdflags += {.DSYNC, .RSYNC, .SYNC} + } + if mode & O_ASYNC == O_ASYNC { + + } + if mode & O_CLOEXEC == O_CLOEXEC { + + } + fs_rights_inheriting = fs_rights_base + + + fd, err := wasi.path_open(0, {}, path, flags, fs_rights_base, fs_rights_inheriting, fdflags) + return Handle(fd), Errno(err) } close :: proc(fd: Handle) -> Errno { - return 0 + err := wasi.fd_close(wasi.fd_t(fd)) + return Errno(err) } seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) { n, err := wasi.fd_seek(wasi.fd_t(fd), wasi.filedelta_t(offset), wasi.whence_t(whence)) diff --git a/core/runtime/os_specific_wasi.odin b/core/runtime/os_specific_wasi.odin index 94cf4c85c..3f69504ee 100644 --- a/core/runtime/os_specific_wasi.odin +++ b/core/runtime/os_specific_wasi.odin @@ -5,6 +5,6 @@ import "core:sys/wasm/wasi" _os_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) { data := (wasi.ciovec_t)(data) - n, err := wasi.fd_write(1, &data, 1) + n, err := wasi.fd_write(1, {data}) return int(n), _OS_Errno(err) } diff --git a/core/sys/wasm/wasi/wasi_api.odin b/core/sys/wasm/wasi/wasi_api.odin index e7cb98bcf..2e2a99617 100644 --- a/core/sys/wasm/wasi/wasi_api.odin +++ b/core/sys/wasm/wasi/wasi_api.odin @@ -1087,17 +1087,6 @@ foreign wasi { */ fst_flags: fstflags_t, ) -> errno_t --- - /** - * Return a description of the given preopened file descriptor. - */ - fd_prestat_dir_name :: proc( - fd: fd_t, - /** - * A buffer into which to write the preopened directory name. - */ - path: [^]u8, - path_len: size_t, - ) -> errno_t --- /** * Atomically replace a file descriptor by renumbering another file descriptor. * Due to the strong focus on thread safety, this environment does not provide @@ -1122,135 +1111,6 @@ foreign wasi { fd_sync :: proc( f: fd_t, ) -> errno_t --- - /** - * Create a directory. - * Note: This is similar to `mkdirat` in POSIX. - */ - path_create_directory :: proc( - fd: fd_t, - /** - * The path at which to create the directory. - */ - path: [^]byte, - path_len: size_t, - ) -> errno_t --- - /** - * Adjust the timestamps of a file or directory. - * Note: This is similar to `utimensat` in POSIX. - */ - path_filestat_set_times :: proc( - fd: fd_t, - /** - * Flags determining the method of how the path is resolved. - */ - flags: lookupflags_t, - /** - * The path of the file or directory to operate on. - */ - path: [^]byte, - path_len: size_t, - /** - * The desired values of the data access timestamp. - */ - atim: timestamp_t, - /** - * The desired values of the data modification timestamp. - */ - mtim: timestamp_t, - /** - * A bitmask indicating which timestamps to adjust. - */ - fst_flags: fstflags_t, - ) -> errno_t --- - /** - * Create a hard link. - * Note: This is similar to `linkat` in POSIX. - */ - path_link :: proc( - old_fd: fd_t, - /** - * Flags determining the method of how the path is resolved. - */ - old_flags: lookupflags_t, - /** - * The source path from which to link. - */ - old_path: [^]byte, - old_path_len: size_t, - /** - * The working directory at which the resolution of the new path starts. - */ - new_fd: fd_t, - /** - * The destination path at which to create the hard link. - */ - new_path: [^]byte, - new_path_len: size_t, - ) -> errno_t --- - /** - * Remove a directory. - * Return `errno::notempty` if the directory is not empty. - * Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - */ - path_remove_directory :: proc( - fd: fd_t, - /** - * The path to a directory to remove. - */ - path: [^]byte, - path_len: size_t, - ) -> errno_t --- - /** - * Rename a file or directory. - * Note: This is similar to `renameat` in POSIX. - */ - path_rename :: proc( - fd: fd_t, - /** - * The source path of the file or directory to rename. - */ - old_path: [^]byte, - old_path_len: size_t, - /** - * The working directory at which the resolution of the new path starts. - */ - new_fd: fd_t, - /** - * The destination path to which to rename the file or directory. - */ - new_path: [^]byte, - new_path_len: size_t, - ) -> errno_t --- - /** - * Create a symbolic link. - * Note: This is similar to `symlinkat` in POSIX. - */ - path_symlink :: proc( - /** - * The contents of the symbolic link. - */ - old_path: [^]byte, - old_path_len: size_t, - fd: fd_t, - /** - * The destination path at which to create the symbolic link. - */ - new_path: [^]byte, - new_path_len: size_t, - ) -> errno_t --- - /** - * Unlink a file. - * Return `errno::isdir` if the path refers to a directory. - * Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - */ - path_unlink_file :: proc( - fd: fd_t, - /** - * The path to a file to unlink. - */ - path: [^]byte, - path_len: size_t, - ) -> errno_t --- /** * Terminate the process normally. An exit code of 0 indicates successful * termination of the program. The meanings of other values is dependent on @@ -1277,21 +1137,6 @@ foreign wasi { * Note: This is similar to `sched_yield` in POSIX. */ sched_yield :: proc() -> errno_t --- - /** - * Write high-quality random data into a buffer. - * This function blocks when the implementation is unable to immediately - * provide sufficient high-quality random data. - * This function may execute slowly, so when large mounts of random data are - * required, it's advisable to use this function to seed a pseudo-random - * number generator, rather than to provide the random data directly. - */ - random_get :: proc( - /** - * The buffer to fill with random data. - */ - buf: [^]u8, - buf_len: size_t, - ) -> errno_t --- /** * Shut down socket send and receive channels. * Note: This is similar to `shutdown` in POSIX. @@ -1399,17 +1244,13 @@ fd_pread :: proc "c" ( /** * List of scatter/gather vectors in which to store data. */ - iovs: [^]iovec_t, - /** - * The length of the array pointed to by `iovs`. - */ - iovs_len: size_t, + iovs: []iovec_t, /** * The offset within the file at which to read. */ offset: filesize_t, ) -> (n: size_t, err: errno_t) { - err = wasi_fd_pread(fd, iovs, iovs_len, offset, &n) + err = wasi_fd_pread(fd, raw_data(iovs), len(iovs), offset, &n) return } /** @@ -1434,17 +1275,13 @@ fd_pwrite :: proc "c" ( /** * List of scatter/gather vectors from which to retrieve data. */ - iovs: [^]ciovec_t, - /** - * The length of the array pointed to by `iovs`. - */ - iovs_len: size_t, + iovs: []ciovec_t, /** * The offset within the file at which to write. */ offset: filesize_t, ) -> (n: size_t, err: errno_t) { - err = wasi_fd_pwrite(fd, iovs, iovs_len, offset, &n) + err = wasi_fd_pwrite(fd, raw_data(iovs), len(iovs), offset, &n) return } /** @@ -1458,13 +1295,9 @@ fd_read :: proc "c" ( /** * List of scatter/gather vectors to which to store data. */ - iovs: [^]iovec_t, - /** - * The length of the array pointed to by `iovs`. - */ - iovs_len: size_t, + iovs: []iovec_t, ) -> (n: size_t, err: errno_t) { - err = wasi_fd_read(fd, iovs, iovs_len, &n) + err = wasi_fd_read(fd, raw_data(iovs), len(iovs), &n) return } /** @@ -1485,14 +1318,13 @@ fd_readdir :: proc "c" ( /** * The buffer where directory entries are stored */ - buf: [^]u8, - buf_len: size_t, + buf: []byte, /** * The location within the directory to start reading */ cookie: dircookie_t, ) -> (n: size_t, err: errno_t) { - err = wasi_fd_readdir(fd, buf, buf_len, cookie, &n) + err = wasi_fd_readdir(fd, raw_data(buf), len(buf), cookie, &n) return } /** @@ -1536,13 +1368,9 @@ fd_write :: proc "c" ( /** * List of scatter/gather vectors from which to retrieve data. */ - iovs: [^]ciovec_t, - /** - * The length of the array pointed to by `iovs`. - */ - iovs_len: size_t, + iovs: []ciovec_t, ) -> (n: size_t, err: errno_t) { - err = wasi_fd_write(fd, iovs, iovs_len, &n) + err = wasi_fd_write(fd, raw_data(iovs), len(iovs), &n) return } /** @@ -1661,17 +1489,13 @@ sock_recv :: proc "c" ( /** * List of scatter/gather vectors to which to store data. */ - ri_data: [^]iovec_t, - /** - * The length of the array pointed to by `ri_data`. - */ - ri_data_len: size_t, + ri_data: []iovec_t, /** * Message flags. */ ri_flags: riflags_t, ) -> (n: size_t, flags: roflags_t, err: errno_t) { - err = wasi_sock_recv(fd, ri_data, ri_data_len, ri_flags, &n, &flags) + err = wasi_sock_recv(fd, raw_data(ri_data), len(ri_data), ri_flags, &n, &flags) return } /** @@ -1686,20 +1510,182 @@ sock_send :: proc "c" ( /** * List of scatter/gather vectors to which to retrieve data */ - si_data: [^]ciovec_t, - /** - * The length of the array pointed to by `si_data`. - */ - si_data_len: size_t, + si_data: []ciovec_t, /** * Message flags. */ si_flags: siflags_t, ) -> (n: size_t, err: errno_t) { - err = wasi_sock_send(fd, si_data, si_data_len, si_flags, &n) + err = wasi_sock_send(fd, raw_data(si_data), len(si_data), si_flags, &n) return } +/** + * Return a description of the given preopened file descriptor. + */ +fd_prestat_dir_name :: proc( + fd: fd_t, + /** + * A buffer into which to write the preopened directory name. + */ + path: string, +) -> errno_t { + return wasm_fd_prestat_dir_name(fd, raw_data(path), len(path)) +} +/** + * Create a directory. + * Note: This is similar to `mkdirat` in POSIX. + */ +path_create_directory :: proc( + fd: fd_t, + /** + * The path at which to create the directory. + */ + path: string, +) -> errno_t { + return wasm_path_create_directory(fd, raw_data(path), len(path)) +} +/** + * Adjust the timestamps of a file or directory. + * Note: This is similar to `utimensat` in POSIX. + */ +path_filestat_set_times :: proc( + fd: fd_t, + /** + * Flags determining the method of how the path is resolved. + */ + flags: lookupflags_t, + /** + * The path of the file or directory to operate on. + */ + path: string, + /** + * The desired values of the data access timestamp. + */ + atim: timestamp_t, + /** + * The desired values of the data modification timestamp. + */ + mtim: timestamp_t, + /** + * A bitmask indicating which timestamps to adjust. + */ + fst_flags: fstflags_t, +) -> errno_t { + return wasm_path_filestat_set_times(fd, flags, raw_data(path), len(path), atim, mtim, fst_flags) +} +/** + * Remove a directory. + * Return `errno::notempty` if the directory is not empty. + * Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + */ +path_remove_directory :: proc( + fd: fd_t, + /** + * The path to a directory to remove. + */ + path: string, +) -> errno_t { + return wasm_path_remove_directory(fd, raw_data(path), len(path)) +} +/** + * Create a hard link. + * Note: This is similar to `linkat` in POSIX. + */ +path_link :: proc( + old_fd: fd_t, + /** + * Flags determining the method of how the path is resolved. + */ + old_flags: lookupflags_t, + /** + * The source path from which to link. + */ + old_path: string, + /** + * The working directory at which the resolution of the new path starts. + */ + new_fd: fd_t, + /** + * The destination path at which to create the hard link. + */ + new_path: string, +) -> errno_t { + return wasm_path_link(old_fd, old_flags, raw_data(old_path), len(old_path), new_fd, raw_data(new_path), len(new_path)) +} + +/** + * Rename a file or directory. + * Note: This is similar to `renameat` in POSIX. + */ +path_rename :: proc( + fd: fd_t, + /** + * The source path of the file or directory to rename. + */ + old_path: string, + /** + * The working directory at which the resolution of the new path starts. + */ + new_fd: fd_t, + /** + * The destination path to which to rename the file or directory. + */ + new_path: string, +) -> errno_t { + return wasm_path_rename(fd, raw_data(old_path), len(old_path), new_fd, raw_data(new_path), len(new_path)) +} +/** + * Create a symbolic link. + * Note: This is similar to `symlinkat` in POSIX. + */ +path_symlink :: proc( + /** + * The contents of the symbolic link. + */ + old_path: string, + fd: fd_t, + /** + * The destination path at which to create the symbolic link. + */ + new_path: string, +) -> errno_t { + return wasm_path_symlink(raw_data(old_path), len(old_path), fd, raw_data(new_path), len(new_path)) +} +/** + * Unlink a file. + * Return `errno::isdir` if the path refers to a directory. + * Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + */ +path_unlink_file :: proc( + fd: fd_t, + /** + * The path to a file to unlink. + */ + path: string, +) -> errno_t { + return wasm_path_unlink_file(fd, raw_data(path), len(path)) +} +/** + * Write high-quality random data into a buffer. + * This function blocks when the implementation is unable to immediately + * provide sufficient high-quality random data. + * This function may execute slowly, so when large mounts of random data are + * required, it's advisable to use this function to seed a pseudo-random + * number generator, rather than to provide the random data directly. + */ +random_get :: proc( + /** + * The buffer to fill with random data. + */ + buf: []u8, +) -> errno_t { + return wasm_random_get(raw_data(buf), len(buf)) +} + + + + @(default_calling_convention="c") foreign wasi { @(link_name="args_sizes_get") @@ -1795,7 +1781,7 @@ foreign wasi { /** * The path of the file or directory to inspect. */ - path: [^]byte, + path: [^]u8, path_len: size_t, retptr0: ^filestat_t, ) -> errno_t --- @@ -1803,7 +1789,7 @@ foreign wasi { wasi_path_open :: proc( fd: fd_t, dirflags: lookupflags_t, - path: [^]byte, + path: [^]u8, path_len: size_t, oflags: oflags_t, fs_rights_base: rights_t, @@ -1814,7 +1800,7 @@ foreign wasi { @(link_name="path_readlink") wasi_path_readlink :: proc( fd: fd_t, - path: [^]byte, + path: [^]u8, path_len: size_t, buf: [^]u8, buf_len: size_t, @@ -1844,4 +1830,70 @@ foreign wasi { si_flags: siflags_t, retptr0: ^size_t, ) -> errno_t --- + @(link_name="fd_prestat_dir_name") + wasm_fd_prestat_dir_name :: proc( + fd: fd_t, + path: [^]u8, + path_len: size_t, + ) -> errno_t --- + @(link_name="path_create_directory") + wasm_path_create_directory :: proc( + fd: fd_t, + path: [^]u8, + path_len: size_t, + ) -> errno_t --- + @(link_name="path_filestat_set_times") + wasm_path_filestat_set_times :: proc( + fd: fd_t, + flags: lookupflags_t, + path: [^]u8, + path_len: size_t, + atim: timestamp_t, + mtim: timestamp_t, + fst_flags: fstflags_t, + ) -> errno_t --- + @(link_name="path_remove_directory") + wasm_path_remove_directory :: proc( + fd: fd_t, + path: [^]u8, + path_len: size_t, + ) -> errno_t --- + @(link_name="path_link") + wasm_path_link :: proc( + old_fd: fd_t, + old_flags: lookupflags_t, + old_path: [^]u8, + old_path_len: size_t, + new_fd: fd_t, + new_path: [^]u8, + new_path_len: size_t, + ) -> errno_t --- + @(link_name="path_rename") + wasm_path_rename :: proc( + fd: fd_t, + old_path: [^]u8, + old_path_len: size_t, + new_fd: fd_t, + new_path: [^]u8, + new_path_len: size_t, + ) -> errno_t --- + @(link_name="path_symlink") + wasm_path_symlink :: proc( + old_path: [^]u8, + old_path_len: size_t, + fd: fd_t, + new_path: [^]u8, + new_path_len: size_t, + ) -> errno_t --- + @(link_name="path_unlink_file") + wasm_path_unlink_file :: proc( + fd: fd_t, + path: [^]u8, + path_len: size_t, + ) -> errno_t --- + @(link_name="random_get") + wasm_random_get :: proc( + buf: [^]u8, + buf_len: size_t, + ) -> errno_t --- }