Skip to content
This repository was archived by the owner on Oct 13, 2023. It is now read-only.

Commit f7d095e

Browse files
committed
Implement fd_filestat_set_size, fd_pread, and fd_pwrite.
1 parent fca5c0e commit f7d095e

File tree

1 file changed

+79
-7
lines changed

1 file changed

+79
-7
lines changed

src/lib.rs

Lines changed: 79 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,14 @@ pub unsafe extern "C" fn fd_filestat_get(fd: Fd, buf: *mut Filestat) -> Errno {
342342
/// Note: This is similar to `ftruncate` in POSIX.
343343
#[no_mangle]
344344
pub unsafe extern "C" fn fd_filestat_set_size(fd: Fd, size: Filesize) -> Errno {
345-
unreachable()
345+
match Descriptor::get(fd) {
346+
Descriptor::File(file) => match wasi_filesystem::set_size(file.fd, size) {
347+
Ok(()) => ERRNO_SUCCESS,
348+
Err(err) => errno_from_wasi_filesystem(err),
349+
},
350+
Descriptor::Log => ERRNO_SPIPE,
351+
Descriptor::Closed => ERRNO_BADF,
352+
}
346353
}
347354

348355
/// Adjust the timestamps of an open file or directory.
@@ -385,12 +392,44 @@ pub unsafe extern "C" fn fd_filestat_set_times(
385392
#[no_mangle]
386393
pub unsafe extern "C" fn fd_pread(
387394
fd: Fd,
388-
iovs_ptr: *const Iovec,
389-
iovs_len: usize,
395+
mut iovs_ptr: *const Iovec,
396+
mut iovs_len: usize,
390397
offset: Filesize,
391398
nread: *mut Size,
392399
) -> Errno {
393-
unreachable()
400+
// Advance to the first non-empty buffer.
401+
while iovs_len != 0 && (*iovs_ptr).buf_len == 0 {
402+
iovs_ptr = iovs_ptr.add(1);
403+
iovs_len -= 1;
404+
}
405+
if iovs_len == 0 {
406+
*nread = 0;
407+
return ERRNO_SUCCESS;
408+
}
409+
410+
match Descriptor::get(fd) {
411+
Descriptor::File(file) => {
412+
let ptr = (*iovs_ptr).buf;
413+
let len = (*iovs_ptr).buf_len;
414+
415+
register_buffer(ptr, len);
416+
417+
// We can cast between a `usize`-sized value and `usize`.
418+
let read_len = len as _;
419+
let result = wasi_filesystem::pread(file.fd, read_len, offset);
420+
match result {
421+
Ok(data) => {
422+
assert_eq!(data.as_ptr(), ptr);
423+
assert!(data.len() <= len);
424+
*nread = data.len();
425+
forget(data);
426+
ERRNO_SUCCESS
427+
}
428+
Err(err) => errno_from_wasi_filesystem(err),
429+
}
430+
}
431+
Descriptor::Closed | Descriptor::Log => ERRNO_BADF,
432+
}
394433
}
395434

396435
/// Return a description of the given preopened file descriptor.
@@ -410,12 +449,45 @@ pub unsafe extern "C" fn fd_prestat_dir_name(fd: Fd, path: *mut u8, path_len: Si
410449
#[no_mangle]
411450
pub unsafe extern "C" fn fd_pwrite(
412451
fd: Fd,
413-
iovs_ptr: *const Ciovec,
414-
iovs_len: usize,
452+
mut iovs_ptr: *const Ciovec,
453+
mut iovs_len: usize,
415454
offset: Filesize,
416455
nwritten: *mut Size,
417456
) -> Errno {
418-
unreachable()
457+
// Advance to the first non-empty buffer.
458+
while iovs_len != 0 && (*iovs_ptr).buf_len == 0 {
459+
iovs_ptr = iovs_ptr.add(1);
460+
iovs_len -= 1;
461+
}
462+
if iovs_len == 0 {
463+
*nwritten = 0;
464+
return ERRNO_SUCCESS;
465+
}
466+
467+
let ptr = (*iovs_ptr).buf;
468+
let len = (*iovs_ptr).buf_len;
469+
470+
match Descriptor::get(fd) {
471+
Descriptor::File(file) => {
472+
let result = wasi_filesystem::pwrite(file.fd, slice::from_raw_parts(ptr, len), offset);
473+
474+
match result {
475+
Ok(bytes) => {
476+
*nwritten = bytes as usize;
477+
ERRNO_SUCCESS
478+
}
479+
Err(err) => errno_from_wasi_filesystem(err),
480+
}
481+
}
482+
Descriptor::Log => {
483+
let bytes = slice::from_raw_parts(ptr, len);
484+
let context: [u8; 3] = [b'I', b'/', b'O'];
485+
wasi_logging::log(wasi_logging::Level::Info, &context, bytes);
486+
*nwritten = len;
487+
ERRNO_SUCCESS
488+
}
489+
Descriptor::Closed => ERRNO_BADF,
490+
}
419491
}
420492

421493
/// Read from a file descriptor.

0 commit comments

Comments
 (0)