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>
@@ -371,6 +372,8 @@ os_open_preopendir(const char *path, os_file_handle *out)
371372
372373 (* out )-> fd = index ;
373374 (* out )-> is_sock = false;
375+ (* out )-> is_stdio = false;
376+ (* out )-> raw_fd = -1 ;
374377
375378 strncpy (prestat_dir , path , MAX_FILE_NAME + 1 );
376379 prestat_dir [MAX_FILE_NAME ] = '\0' ;
@@ -486,6 +489,8 @@ os_openat(os_file_handle handle, const char *path, __wasi_oflags_t oflags,
486489
487490 (* out )-> fd = index ;
488491 (* out )-> is_sock = false;
492+ (* out )-> is_stdio = false;
493+ (* out )-> raw_fd = -1 ;
489494
490495 return __WASI_ESUCCESS ;
491496}
@@ -543,8 +548,12 @@ os_close(os_file_handle handle, bool is_stdio)
543548 int rc ;
544549 struct zephyr_fs_desc * ptr = NULL ;
545550
546- if (is_stdio )
551+ if (is_stdio ) {
552+ /* Don't close the underlying fd - the caller owns it.
553+ * Just free the handle struct. */
554+ BH_FREE (handle );
547555 return __WASI_ESUCCESS ;
556+ }
548557
549558 if (handle -> is_sock ) {
550559 rc = zsock_close (handle -> fd );
@@ -569,7 +578,8 @@ __wasi_errno_t
569578os_preadv (os_file_handle handle , const struct __wasi_iovec_t * iov , int iovcnt ,
570579 __wasi_filesize_t offset , size_t * nread )
571580{
572- if (handle -> fd == STDIN_FILENO ) {
581+ /* Positional read is not supported on stdio handles */
582+ if (handle -> is_stdio ) {
573583 return __WASI_ENOSYS ;
574584 }
575585
@@ -610,6 +620,11 @@ __wasi_errno_t
610620os_pwritev (os_file_handle handle , const struct __wasi_ciovec_t * iov , int iovcnt ,
611621 __wasi_filesize_t offset , size_t * nwritten )
612622{
623+ /* Positional write is not supported on stdio handles */
624+ if (handle -> is_stdio ) {
625+ return __WASI_ENOSYS ;
626+ }
627+
613628 struct zephyr_fs_desc * ptr = NULL ;
614629 ssize_t total_written = 0 ;
615630
@@ -647,9 +662,29 @@ __wasi_errno_t
647662os_readv (os_file_handle handle , const struct __wasi_iovec_t * iov , int iovcnt ,
648663 size_t * nread )
649664{
650- struct zephyr_fs_desc * ptr = NULL ;
651665 ssize_t total_read = 0 ;
652666
667+ /* Handle stdio (stdin/stdout/stderr) */
668+ if (handle -> is_stdio ) {
669+ if (handle -> raw_fd >= 0 ) {
670+ /* Use the real OS file descriptor */
671+ for (int i = 0 ; i < iovcnt ; i ++ ) {
672+ ssize_t bytes_read =
673+ read (handle -> raw_fd , iov [i ].buf , iov [i ].buf_len );
674+ if (bytes_read < 0 )
675+ return convert_errno (errno );
676+ total_read += bytes_read ;
677+ if ((size_t )bytes_read < iov [i ].buf_len )
678+ break ;
679+ }
680+ }
681+ /* else: no real fd, return 0 bytes (EOF) */
682+ * nread = total_read ;
683+ return __WASI_ESUCCESS ;
684+ }
685+
686+ struct zephyr_fs_desc * ptr = NULL ;
687+
653688 GET_FILE_SYSTEM_DESCRIPTOR (handle -> fd , ptr );
654689
655690 // Read data into each buffer
@@ -674,21 +709,34 @@ os_readv(os_file_handle handle, const struct __wasi_iovec_t *iov, int iovcnt,
674709 return __WASI_ESUCCESS ;
675710}
676711
677- /* With wasi-libc we need to redirect write on stdout/err to printf */
678- // TODO: handle write on stdin
679712__wasi_errno_t
680713os_writev (os_file_handle handle , const struct __wasi_ciovec_t * iov , int iovcnt ,
681714 size_t * nwritten )
682715{
683716 ssize_t total_written = 0 ;
684717
685- if (os_is_virtual_fd (handle -> fd )) {
686- FILE * fd = (handle -> fd == STDERR_FILENO ) ? stderr : stdout ;
687- for (int i = 0 ; i < iovcnt ; i ++ ) {
688- ssize_t bytes_written = fwrite (iov [i ].buf , 1 , iov [i ].buf_len , fd );
689- if (bytes_written < 0 )
690- return convert_errno (- bytes_written );
691- total_written += bytes_written ;
718+ /* Handle stdio (stdin/stdout/stderr) */
719+ if (handle -> is_stdio ) {
720+ if (handle -> raw_fd >= 0 ) {
721+ /* Use the real OS file descriptor */
722+ for (int i = 0 ; i < iovcnt ; i ++ ) {
723+ ssize_t bytes_written =
724+ write (handle -> raw_fd , iov [i ].buf , iov [i ].buf_len );
725+ if (bytes_written < 0 )
726+ return convert_errno (errno );
727+ total_written += bytes_written ;
728+ }
729+ }
730+ else {
731+ /* No real fd: fall back to fwrite on stdout/stderr */
732+ FILE * f = (handle -> fd == STDERR_FILENO ) ? stderr : stdout ;
733+ for (int i = 0 ; i < iovcnt ; i ++ ) {
734+ ssize_t bytes_written =
735+ fwrite (iov [i ].buf , 1 , iov [i ].buf_len , f );
736+ if (bytes_written < 0 )
737+ return convert_errno (- bytes_written );
738+ total_written += bytes_written ;
739+ }
692740 }
693741
694742 * nwritten = total_written ;
@@ -976,6 +1024,8 @@ os_convert_stdin_handle(os_raw_file_handle raw_stdin)
9761024
9771025 handle -> fd = STDIN_FILENO ;
9781026 handle -> is_sock = false;
1027+ handle -> is_stdio = true;
1028+ handle -> raw_fd = raw_stdin >= 0 ? raw_stdin : -1 ;
9791029 return handle ;
9801030}
9811031
@@ -988,6 +1038,8 @@ os_convert_stdout_handle(os_raw_file_handle raw_stdout)
9881038
9891039 handle -> fd = STDOUT_FILENO ;
9901040 handle -> is_sock = false;
1041+ handle -> is_stdio = true;
1042+ handle -> raw_fd = raw_stdout >= 0 ? raw_stdout : -1 ;
9911043 return handle ;
9921044}
9931045
@@ -1000,6 +1052,8 @@ os_convert_stderr_handle(os_raw_file_handle raw_stderr)
10001052
10011053 handle -> fd = STDERR_FILENO ;
10021054 handle -> is_sock = false;
1055+ handle -> is_stdio = true;
1056+ handle -> raw_fd = raw_stderr >= 0 ? raw_stderr : -1 ;
10031057 return handle ;
10041058}
10051059
@@ -1195,17 +1249,17 @@ os_compare_file_handle(os_file_handle handle1, os_file_handle handle2)
11951249bool
11961250os_is_stdin_handle (os_file_handle handle )
11971251{
1198- return ( handle == ( os_file_handle ) stdin ) ;
1252+ return handle != NULL && handle -> is_stdio && handle -> fd == STDIN_FILENO ;
11991253}
12001254
12011255bool
12021256os_is_stdout_handle (os_file_handle handle )
12031257{
1204- return ( handle == ( os_file_handle ) stdout ) ;
1258+ return handle != NULL && handle -> is_stdio && handle -> fd == STDOUT_FILENO ;
12051259}
12061260
12071261bool
12081262os_is_stderr_handle (os_file_handle handle )
12091263{
1210- return ( handle == ( os_file_handle ) stderr ) ;
1264+ return handle != NULL && handle -> is_stdio && handle -> fd == STDERR_FILENO ;
12111265}
0 commit comments