Skip to content

Commit 288f165

Browse files
alexcrichtondicej
andauthored
wasip3: Get pread/pwrite working (WebAssembly#759)
This is different than wasip2 so needed some custom implementations. --------- Co-authored-by: Joel Dice <joel.dice@akamai.com>
1 parent 13491a5 commit 288f165

4 files changed

Lines changed: 72 additions & 16 deletions

File tree

libc-bottom-half/cloudlibc/src/libc/unistd/pread.c

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
#include <common/errors.h>
1313
#endif
1414

15+
#ifdef __wasip3__
16+
#include <wasi/wasip3_block.h>
17+
#endif
18+
1519
ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset) {
1620
if (offset < 0) {
1721
errno = EINVAL;
@@ -66,12 +70,38 @@ ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset) {
6670

6771
return bytes_read;
6872
#elif defined(__wasip3__)
69-
(void) fildes;
70-
(void) buf;
71-
(void) nbyte;
72-
// TODO(wasip3)
73-
errno = ENOTSUP;
74-
return -1;
73+
filesystem_borrow_descriptor_t file_handle;
74+
if (fd_to_file_handle(fildes, &file_handle) < 0)
75+
return -1;
76+
77+
// Use `read-via-stream` to acquire a stream of data at this specified file
78+
// offset, then issue a read and wait for it to finish.
79+
filesystem_tuple2_stream_u8_future_result_void_error_code_t io;
80+
filesystem_method_descriptor_read_via_stream(file_handle, offset, &io);
81+
bool closed;
82+
size_t ret = __wasilibc_stream_block_on(
83+
filesystem_stream_u8_read(io.f0, buf, nbyte),
84+
io.f0,
85+
&closed);
86+
filesystem_stream_u8_drop_readable(io.f0);
87+
88+
// If zero bytes were read then read the provided future to see
89+
// what happened. Otherwise close the future as we won't be reading the
90+
// result.
91+
if (ret == 0) {
92+
filesystem_result_void_error_code_t result;
93+
__wasilibc_future_block_on(
94+
filesystem_future_result_void_error_code_read(io.f1, &result),
95+
io.f1);
96+
filesystem_future_result_void_error_code_drop_readable(io.f1);
97+
if (result.is_err) {
98+
translate_error(result.val.err);
99+
return -1;
100+
}
101+
} else {
102+
filesystem_future_result_void_error_code_drop_readable(io.f1);
103+
}
104+
return ret;
75105
#else
76106
# error "Unknown WASI version"
77107
#endif

libc-bottom-half/cloudlibc/src/libc/unistd/pwrite.c

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
#include <common/errors.h>
1212
#endif
1313

14+
#ifdef __wasip3__
15+
#include <wasi/wasip3_block.h>
16+
#endif
17+
1418
ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset) {
1519
if (offset < 0) {
1620
errno = EINVAL;
@@ -62,12 +66,34 @@ ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset) {
6266

6367
return bytes_written;
6468
#elif defined(__wasip3__)
65-
(void) fildes;
66-
(void) buf;
67-
(void) nbyte;
68-
// TODO(wasip3)
69-
errno = ENOTSUP;
70-
return -1;
69+
filesystem_borrow_descriptor_t file_handle;
70+
if (fd_to_file_handle(fildes, &file_handle) < 0)
71+
return -1;
72+
73+
// Create a read/write stream, use `write-via-stream` to start writing,
74+
// then perform the write to see how much was accepted.
75+
filesystem_stream_u8_writer_t writer;
76+
filesystem_stream_u8_t reader = filesystem_stream_u8_new(&writer);
77+
filesystem_result_void_error_code_t result;
78+
wasip3_subtask_status_t subtask_status =
79+
filesystem_method_descriptor_write_via_stream(file_handle, reader, offset, &result);
80+
bool closed;
81+
size_t ret = __wasilibc_stream_block_on(
82+
filesystem_stream_u8_write(writer, buf, nbyte),
83+
writer,
84+
&closed);
85+
filesystem_stream_u8_drop_writable(writer);
86+
87+
// Wait for the subtask to resolve now that the writer half is closed and if
88+
// we failed to write bytes (0 bytes written) and the result is an error we
89+
// can return -1.
90+
if (WASIP3_SUBTASK_STATE(subtask_status) != WASIP3_SUBTASK_RETURNED)
91+
__wasilibc_subtask_block_on_and_drop(WASIP3_SUBTASK_HANDLE(subtask_status));
92+
if (ret == 0 && result.is_err) {
93+
translate_error(result.val.err);
94+
return -1;
95+
}
96+
return ret;
7197
#else
7298
# error "Unsupported WASI version"
7399
#endif

test/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,8 @@ add_wasilibc_test(memcmp.c LDFLAGS -Wl,--stack-first -Wl,--initial-memory=327680
290290
add_wasilibc_test(opendir.c FS ARGV /)
291291
add_wasilibc_test(open_relative_path.c FS ARGV /)
292292
add_wasilibc_test(poll.c FS FAILP3)
293-
add_wasilibc_test(preadvwritev.c FS FAILP3)
294-
add_wasilibc_test(preadwrite.c FS FAILP3)
293+
add_wasilibc_test(preadvwritev.c FS)
294+
add_wasilibc_test(preadwrite.c FS)
295295
add_wasilibc_test(readlink.c FS)
296296
add_wasilibc_test(readv.c FS)
297297
add_wasilibc_test(rename.c FS)

test/src/sleep.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
#endif
2121

2222
int main(void) {
23-
// Sleep for a total of 2 seconds
24-
unsigned int seconds_to_sleep = 2;
23+
// Sleep for a total of 1 second
24+
unsigned int seconds_to_sleep = 1;
2525

2626
struct timespec start_time, end_time;
2727
clock_gettime(CLOCK, &start_time);

0 commit comments

Comments
 (0)