-
Notifications
You must be signed in to change notification settings - Fork 237
Wasip3: File handing implementation #720
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
0e71103
52a0ed8
fa754c6
34f61ac
148eeec
59cf7c4
df8de9c
4e05725
7479355
4e40dc1
fd41aed
5fd60a2
3f3e5ac
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,6 +31,10 @@ static_assert(DT_REG == __WASI_FILETYPE_REGULAR_FILE, "Value mismatch"); | |
| static_assert(DT_UNKNOWN == __WASI_FILETYPE_UNKNOWN, "Value mismatch"); | ||
| #endif | ||
|
|
||
| #ifdef __wasip3__ | ||
| #include <wasi/wasip3_block.h> | ||
| #endif | ||
|
|
||
| // Grows a buffer to be large enough to hold a certain amount of data. | ||
| #define GROW(buffer, buffer_size, target_size) \ | ||
| do { \ | ||
|
|
@@ -140,12 +144,13 @@ struct dirent *readdir(DIR *dirp) { | |
| } | ||
| } | ||
|
|
||
| #elif defined(__wasip2__) | ||
| #elif defined(__wasip2__) || defined(__wasip3__) | ||
|
|
||
| static int ensure_has_directory_stream(DIR *dirp, filesystem_borrow_descriptor_t *handle) { | ||
| if (fd_to_file_handle(dirp->fd, handle) < 0) | ||
| return -1; | ||
|
|
||
| #ifdef __wasip2__ | ||
| if (dirp->stream.__handle != 0) | ||
| return 0; | ||
|
|
||
|
|
@@ -157,6 +162,12 @@ static int ensure_has_directory_stream(DIR *dirp, filesystem_borrow_descriptor_t | |
| translate_error(error_code); | ||
| return -1; | ||
| } | ||
| #elif defined(__wasip3__) | ||
| if (dirp->stream.f0 == 0) { | ||
| wasip3_subtask_status_t status = filesystem_method_descriptor_read_directory(*handle, &dirp->stream); | ||
| wasip3_subtask_block_on(status); | ||
| } | ||
| #endif | ||
| return 0; | ||
| } | ||
|
|
||
|
|
@@ -173,13 +184,24 @@ static struct dirent *readdir_next(DIR *dirp) { | |
| if (dirp->offset == 0) { | ||
| dirp->offset += 1; | ||
| GROW(dirp->dirent, dirp->dirent_size, offsetof(struct dirent, d_name) + 2); | ||
| #ifdef __wasip2__ | ||
| bool ok = filesystem_method_descriptor_metadata_hash(dir_handle, | ||
| &metadata, | ||
| &error_code); | ||
| if (!ok) { | ||
| translate_error(error_code); | ||
| return NULL; | ||
| } | ||
| #else | ||
| filesystem_result_metadata_hash_value_error_code_t result; | ||
| wasip3_subtask_status_t status = filesystem_method_descriptor_metadata_hash(dir_handle, &result); | ||
| wasip3_subtask_block_on(status); | ||
| if (result.is_err) { | ||
| translate_error(result.val.err); | ||
| return NULL; | ||
| } | ||
| metadata = result.val.ok; | ||
| #endif | ||
| dirp->dirent->d_ino = metadata.lower; | ||
| dirp->dirent->d_type = DT_DIR; | ||
| dirp->dirent->d_name[0] = '.'; | ||
|
|
@@ -200,6 +222,7 @@ static struct dirent *readdir_next(DIR *dirp) { | |
| return dirp->dirent; | ||
| } | ||
|
|
||
| #ifdef __wasip2__ | ||
| filesystem_borrow_directory_entry_stream_t stream = filesystem_borrow_directory_entry_stream(dirp->stream); | ||
| filesystem_option_directory_entry_t dir_entry_optional; | ||
| bool ok = filesystem_method_directory_entry_stream_read_directory_entry(stream, | ||
|
|
@@ -216,6 +239,14 @@ static struct dirent *readdir_next(DIR *dirp) { | |
|
|
||
| filesystem_directory_entry_t dir_entry = dir_entry_optional.val; | ||
|
|
||
| #elif defined(__wasip3__) | ||
| filesystem_directory_entry_t dir_entry; | ||
| wasip3_waitable_status_t status = filesystem_stream_directory_entry_read(dirp->stream.f0, &dir_entry, 1); | ||
| ssize_t amount = wasip3_waitable_block_on(status, dirp->stream.f0); | ||
| if (amount<1) | ||
| return NULL; | ||
|
Comment on lines
+246
to
+247
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Upon reaching end-of-stream this'll want to block on the future-of-result to see if an error is going to be returned |
||
| #endif | ||
|
|
||
| // Ensure that the dirent is large enough to fit the filename | ||
| size_t the_size = offsetof(struct dirent, d_name); | ||
| GROW(dirp->dirent, dirp->dirent_size, the_size + dir_entry.name.len + 1); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is preexisting, but I'm realizing now that this I'll file an issue to fix that. |
||
|
|
@@ -227,6 +258,7 @@ static struct dirent *readdir_next(DIR *dirp) { | |
|
|
||
| // Fill out `d_ino` with the metadata hash. | ||
| filesystem_path_flags_t path_flags = 0; // Don't follow symlinks | ||
| #ifdef __wasip2__ | ||
| ok = filesystem_method_descriptor_metadata_hash_at(dir_handle, | ||
| path_flags, | ||
| &dir_entry.name, | ||
|
|
@@ -237,6 +269,17 @@ static struct dirent *readdir_next(DIR *dirp) { | |
| translate_error(error_code); | ||
| return NULL; | ||
| } | ||
| #else | ||
| filesystem_result_metadata_hash_value_error_code_t result; | ||
| status = filesystem_method_descriptor_metadata_hash_at(dir_handle, path_flags, dir_entry.name, &result); | ||
| wasip3_subtask_block_on(status); | ||
| //wasip3_string_free(&dir_entry.name); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Debugging perhaps? (I think this is needed right?) |
||
| if (result.is_err) { | ||
| translate_error(result.val.err); | ||
| return NULL; | ||
| } | ||
| metadata = result.val.ok; | ||
| #endif | ||
| dirp->dirent->d_ino = metadata.lower; | ||
| dirp->offset += 1; | ||
|
|
||
|
|
@@ -251,13 +294,6 @@ struct dirent *readdir(DIR *dirp) { | |
| } | ||
| return result; | ||
| } | ||
| #elif defined(__wasip3__) | ||
| struct dirent *readdir(DIR *dirp) { | ||
| // TODO(wasip3) | ||
| errno = ENOTSUP; | ||
| free(dirp); | ||
| return NULL; | ||
| } | ||
| #else | ||
| # error "Unknown WASI version" | ||
| #endif | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,7 +18,14 @@ void rewinddir(DIR *dirp) { | |
| dirp->skip = 0; | ||
| dirp->offset = 0; | ||
| #elif defined(__wasip3__) | ||
| dirp->stream = 0; | ||
| if (dirp->stream.f0 != 0) { | ||
| filesystem_stream_directory_entry_drop_readable(dirp->stream.f0); | ||
| dirp->stream.f0 = 0; | ||
| } | ||
|
Comment on lines
+21
to
+24
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Like below could this update the wasip2 branch above too to close the previous handle if present? |
||
| if (dirp->stream.f1 != 0) { | ||
| filesystem_future_result_void_error_code_drop_readable(dirp->stream.f1); | ||
| dirp->stream.f1 = 0; | ||
| } | ||
| dirp->skip = 0; | ||
| dirp->offset = 0; | ||
| #else | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,7 +18,14 @@ void seekdir(DIR *dirp, long loc) { | |
| dirp->skip = loc; | ||
| dirp->offset = 0; | ||
| #elif defined(__wasip3__) | ||
| dirp->stream = 0; | ||
| if (dirp->stream.f0 != 0) { | ||
| filesystem_stream_directory_entry_drop_readable(dirp->stream.f0); | ||
| dirp->stream.f0 = 0; | ||
| } | ||
|
Comment on lines
+21
to
+24
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is actually a bug of the wasip2 implementation where it doesn't close the previous handle on a call to |
||
| if (dirp->stream.f1 != 0) { | ||
| filesystem_future_result_void_error_code_drop_readable(dirp->stream.f1); | ||
| dirp->stream.f1 = 0; | ||
| } | ||
| dirp->skip = loc; | ||
| dirp->offset = 0; | ||
| #else | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/ssize_t/size_t/