99
1010#include <string.h>
1111#include <stdlib.h>
12+ #include <unistd.h>
1213
1314#include <zephyr/fs/fs.h>
1415#include <zephyr/fs/fs_interface.h>
@@ -399,6 +400,8 @@ os_open_preopendir(const char *path, os_file_handle *out)
399400
400401 (* out )-> fd = index ;
401402 (* out )-> is_sock = false;
403+ (* out )-> is_stdio = false;
404+ (* out )-> raw_fd = -1 ;
402405
403406 strncpy (prestat_dir , path , MAX_FILE_NAME + 1 );
404407 prestat_dir [MAX_FILE_NAME ] = '\0' ;
@@ -514,6 +517,8 @@ os_openat(os_file_handle handle, const char *path, __wasi_oflags_t oflags,
514517
515518 (* out )-> fd = index ;
516519 (* out )-> is_sock = false;
520+ (* out )-> is_stdio = false;
521+ (* out )-> raw_fd = -1 ;
517522
518523 return __WASI_ESUCCESS ;
519524}
@@ -571,8 +576,12 @@ os_close(os_file_handle handle, bool is_stdio)
571576 int rc ;
572577 struct zephyr_fs_desc * ptr = NULL ;
573578
574- if (is_stdio )
579+ if (is_stdio ) {
580+ /* Don't close the underlying fd - the caller owns it.
581+ * Just free the handle struct. */
582+ BH_FREE (handle );
575583 return __WASI_ESUCCESS ;
584+ }
576585
577586 if (handle -> is_sock ) {
578587 rc = zsock_close (handle -> fd );
@@ -597,7 +606,8 @@ __wasi_errno_t
597606os_preadv (os_file_handle handle , const struct __wasi_iovec_t * iov , int iovcnt ,
598607 __wasi_filesize_t offset , size_t * nread )
599608{
600- if (handle -> fd == STDIN_FILENO ) {
609+ /* Positional read is not supported on stdio handles */
610+ if (handle -> is_stdio ) {
601611 return __WASI_ENOSYS ;
602612 }
603613
@@ -638,6 +648,11 @@ __wasi_errno_t
638648os_pwritev (os_file_handle handle , const struct __wasi_ciovec_t * iov , int iovcnt ,
639649 __wasi_filesize_t offset , size_t * nwritten )
640650{
651+ /* Positional write is not supported on stdio handles */
652+ if (handle -> is_stdio ) {
653+ return __WASI_ENOSYS ;
654+ }
655+
641656 struct zephyr_fs_desc * ptr = NULL ;
642657 ssize_t total_written = 0 ;
643658
@@ -675,9 +690,29 @@ __wasi_errno_t
675690os_readv (os_file_handle handle , const struct __wasi_iovec_t * iov , int iovcnt ,
676691 size_t * nread )
677692{
678- struct zephyr_fs_desc * ptr = NULL ;
679693 ssize_t total_read = 0 ;
680694
695+ /* Handle stdio (stdin/stdout/stderr) */
696+ if (handle -> is_stdio ) {
697+ if (handle -> raw_fd >= 0 ) {
698+ /* Use the real OS file descriptor */
699+ for (int i = 0 ; i < iovcnt ; i ++ ) {
700+ ssize_t bytes_read =
701+ read (handle -> raw_fd , iov [i ].buf , iov [i ].buf_len );
702+ if (bytes_read < 0 )
703+ return convert_errno (errno );
704+ total_read += bytes_read ;
705+ if ((size_t )bytes_read < iov [i ].buf_len )
706+ break ;
707+ }
708+ }
709+ /* else: no real fd, return 0 bytes (EOF) */
710+ * nread = total_read ;
711+ return __WASI_ESUCCESS ;
712+ }
713+
714+ struct zephyr_fs_desc * ptr = NULL ;
715+
681716 GET_FILE_SYSTEM_DESCRIPTOR (handle -> fd , ptr );
682717
683718 // Read data into each buffer
@@ -702,21 +737,34 @@ os_readv(os_file_handle handle, const struct __wasi_iovec_t *iov, int iovcnt,
702737 return __WASI_ESUCCESS ;
703738}
704739
705- /* With wasi-libc we need to redirect write on stdout/err to printf */
706- // TODO: handle write on stdin
707740__wasi_errno_t
708741os_writev (os_file_handle handle , const struct __wasi_ciovec_t * iov , int iovcnt ,
709742 size_t * nwritten )
710743{
711744 ssize_t total_written = 0 ;
712745
713- if (os_is_virtual_fd (handle -> fd )) {
714- FILE * fd = (handle -> fd == STDERR_FILENO ) ? stderr : stdout ;
715- for (int i = 0 ; i < iovcnt ; i ++ ) {
716- ssize_t bytes_written = fwrite (iov [i ].buf , 1 , iov [i ].buf_len , fd );
717- if (bytes_written < 0 )
718- return convert_errno (- bytes_written );
719- total_written += bytes_written ;
746+ /* Handle stdio (stdin/stdout/stderr) */
747+ if (handle -> is_stdio ) {
748+ if (handle -> raw_fd >= 0 ) {
749+ /* Use the real OS file descriptor */
750+ for (int i = 0 ; i < iovcnt ; i ++ ) {
751+ ssize_t bytes_written =
752+ write (handle -> raw_fd , iov [i ].buf , iov [i ].buf_len );
753+ if (bytes_written < 0 )
754+ return convert_errno (errno );
755+ total_written += bytes_written ;
756+ }
757+ }
758+ else {
759+ /* No real fd: fall back to fwrite on stdout/stderr */
760+ FILE * f = (handle -> fd == STDERR_FILENO ) ? stderr : stdout ;
761+ for (int i = 0 ; i < iovcnt ; i ++ ) {
762+ ssize_t bytes_written =
763+ fwrite (iov [i ].buf , 1 , iov [i ].buf_len , f );
764+ if (bytes_written < 0 )
765+ return convert_errno (- bytes_written );
766+ total_written += bytes_written ;
767+ }
720768 }
721769
722770 * nwritten = total_written ;
@@ -1004,6 +1052,8 @@ os_convert_stdin_handle(os_raw_file_handle raw_stdin)
10041052
10051053 handle -> fd = STDIN_FILENO ;
10061054 handle -> is_sock = false;
1055+ handle -> is_stdio = true;
1056+ handle -> raw_fd = raw_stdin >= 0 ? raw_stdin : -1 ;
10071057 return handle ;
10081058}
10091059
@@ -1016,6 +1066,8 @@ os_convert_stdout_handle(os_raw_file_handle raw_stdout)
10161066
10171067 handle -> fd = STDOUT_FILENO ;
10181068 handle -> is_sock = false;
1069+ handle -> is_stdio = true;
1070+ handle -> raw_fd = raw_stdout >= 0 ? raw_stdout : -1 ;
10191071 return handle ;
10201072}
10211073
@@ -1028,6 +1080,8 @@ os_convert_stderr_handle(os_raw_file_handle raw_stderr)
10281080
10291081 handle -> fd = STDERR_FILENO ;
10301082 handle -> is_sock = false;
1083+ handle -> is_stdio = true;
1084+ handle -> raw_fd = raw_stderr >= 0 ? raw_stderr : -1 ;
10311085 return handle ;
10321086}
10331087
@@ -1223,17 +1277,17 @@ os_compare_file_handle(os_file_handle handle1, os_file_handle handle2)
12231277bool
12241278os_is_stdin_handle (os_file_handle handle )
12251279{
1226- return ( handle == ( os_file_handle ) stdin ) ;
1280+ return handle != NULL && handle -> is_stdio && handle -> fd == STDIN_FILENO ;
12271281}
12281282
12291283bool
12301284os_is_stdout_handle (os_file_handle handle )
12311285{
1232- return ( handle == ( os_file_handle ) stdout ) ;
1286+ return handle != NULL && handle -> is_stdio && handle -> fd == STDOUT_FILENO ;
12331287}
12341288
12351289bool
12361290os_is_stderr_handle (os_file_handle handle )
12371291{
1238- return ( handle == ( os_file_handle ) stderr ) ;
1292+ return handle != NULL && handle -> is_stdio && handle -> fd == STDERR_FILENO ;
12391293}
0 commit comments