@@ -342,7 +342,14 @@ pub unsafe extern "C" fn fd_filestat_get(fd: Fd, buf: *mut Filestat) -> Errno {
342
342
/// Note: This is similar to `ftruncate` in POSIX.
343
343
#[ no_mangle]
344
344
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
+ }
346
353
}
347
354
348
355
/// Adjust the timestamps of an open file or directory.
@@ -385,12 +392,44 @@ pub unsafe extern "C" fn fd_filestat_set_times(
385
392
#[ no_mangle]
386
393
pub unsafe extern "C" fn fd_pread (
387
394
fd : Fd ,
388
- iovs_ptr : * const Iovec ,
389
- iovs_len : usize ,
395
+ mut iovs_ptr : * const Iovec ,
396
+ mut iovs_len : usize ,
390
397
offset : Filesize ,
391
398
nread : * mut Size ,
392
399
) -> 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
+ }
394
433
}
395
434
396
435
/// 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
410
449
#[ no_mangle]
411
450
pub unsafe extern "C" fn fd_pwrite (
412
451
fd : Fd ,
413
- iovs_ptr : * const Ciovec ,
414
- iovs_len : usize ,
452
+ mut iovs_ptr : * const Ciovec ,
453
+ mut iovs_len : usize ,
415
454
offset : Filesize ,
416
455
nwritten : * mut Size ,
417
456
) -> 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
+ }
419
491
}
420
492
421
493
/// Read from a file descriptor.
0 commit comments