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>
@@ -397,6 +398,8 @@ os_open_preopendir(const char *path, os_file_handle *out)
397398
398399 (* out )-> fd = index ;
399400 (* out )-> is_sock = false;
401+ (* out )-> is_stdio = false;
402+ (* out )-> raw_fd = -1 ;
400403
401404 strncpy (prestat_dir , path , MAX_FILE_NAME + 1 );
402405 prestat_dir [MAX_FILE_NAME ] = '\0' ;
@@ -511,6 +514,8 @@ os_openat(os_file_handle handle, const char *path, __wasi_oflags_t oflags,
511514
512515 (* out )-> fd = index ;
513516 (* out )-> is_sock = false;
517+ (* out )-> is_stdio = false;
518+ (* out )-> raw_fd = -1 ;
514519
515520 return __WASI_ESUCCESS ;
516521}
@@ -568,8 +573,12 @@ os_close(os_file_handle handle, bool is_stdio)
568573 int rc ;
569574 struct zephyr_fs_desc * ptr = NULL ;
570575
571- if (is_stdio )
576+ if (is_stdio ) {
577+ /* Don't close the underlying fd - the caller owns it.
578+ * Just free the handle struct. */
579+ BH_FREE (handle );
572580 return __WASI_ESUCCESS ;
581+ }
573582
574583 if (handle -> is_sock ) {
575584 rc = zsock_close (handle -> fd );
@@ -594,7 +603,8 @@ __wasi_errno_t
594603os_preadv (os_file_handle handle , const struct __wasi_iovec_t * iov , int iovcnt ,
595604 __wasi_filesize_t offset , size_t * nread )
596605{
597- if (handle -> fd == STDIN_FILENO ) {
606+ /* Positional read is not supported on stdio handles */
607+ if (handle -> is_stdio ) {
598608 return __WASI_ENOSYS ;
599609 }
600610
@@ -634,6 +644,11 @@ __wasi_errno_t
634644os_pwritev (os_file_handle handle , const struct __wasi_ciovec_t * iov , int iovcnt ,
635645 __wasi_filesize_t offset , size_t * nwritten )
636646{
647+ /* Positional write is not supported on stdio handles */
648+ if (handle -> is_stdio ) {
649+ return __WASI_ENOSYS ;
650+ }
651+
637652 struct zephyr_fs_desc * ptr = NULL ;
638653 ssize_t total_written = 0 ;
639654
@@ -670,9 +685,29 @@ __wasi_errno_t
670685os_readv (os_file_handle handle , const struct __wasi_iovec_t * iov , int iovcnt ,
671686 size_t * nread )
672687{
673- struct zephyr_fs_desc * ptr = NULL ;
674688 ssize_t total_read = 0 ;
675689
690+ /* Handle stdio (stdin/stdout/stderr) */
691+ if (handle -> is_stdio ) {
692+ if (handle -> raw_fd >= 0 ) {
693+ /* Use the real OS file descriptor */
694+ for (int i = 0 ; i < iovcnt ; i ++ ) {
695+ ssize_t bytes_read =
696+ read (handle -> raw_fd , iov [i ].buf , iov [i ].buf_len );
697+ if (bytes_read < 0 )
698+ return convert_errno (errno );
699+ total_read += bytes_read ;
700+ if ((size_t )bytes_read < iov [i ].buf_len )
701+ break ;
702+ }
703+ }
704+ /* else: no real fd, return 0 bytes (EOF) */
705+ * nread = total_read ;
706+ return __WASI_ESUCCESS ;
707+ }
708+
709+ struct zephyr_fs_desc * ptr = NULL ;
710+
676711 GET_FILE_SYSTEM_DESCRIPTOR (handle -> fd , ptr );
677712
678713 // Read data into each buffer
@@ -696,21 +731,34 @@ os_readv(os_file_handle handle, const struct __wasi_iovec_t *iov, int iovcnt,
696731 return __WASI_ESUCCESS ;
697732}
698733
699- /* With wasi-libc we need to redirect write on stdout/err to printf */
700- // TODO: handle write on stdin
701734__wasi_errno_t
702735os_writev (os_file_handle handle , const struct __wasi_ciovec_t * iov , int iovcnt ,
703736 size_t * nwritten )
704737{
705738 ssize_t total_written = 0 ;
706739
707- if (os_is_virtual_fd (handle -> fd )) {
708- FILE * fd = (handle -> fd == STDERR_FILENO ) ? stderr : stdout ;
709- for (int i = 0 ; i < iovcnt ; i ++ ) {
710- ssize_t bytes_written = fwrite (iov [i ].buf , 1 , iov [i ].buf_len , fd );
711- if (bytes_written < 0 )
712- return convert_errno (- bytes_written );
713- total_written += bytes_written ;
740+ /* Handle stdio (stdin/stdout/stderr) */
741+ if (handle -> is_stdio ) {
742+ if (handle -> raw_fd >= 0 ) {
743+ /* Use the real OS file descriptor */
744+ for (int i = 0 ; i < iovcnt ; i ++ ) {
745+ ssize_t bytes_written =
746+ write (handle -> raw_fd , iov [i ].buf , iov [i ].buf_len );
747+ if (bytes_written < 0 )
748+ return convert_errno (errno );
749+ total_written += bytes_written ;
750+ }
751+ }
752+ else {
753+ /* No real fd: fall back to fwrite on stdout/stderr */
754+ FILE * f = (handle -> fd == STDERR_FILENO ) ? stderr : stdout ;
755+ for (int i = 0 ; i < iovcnt ; i ++ ) {
756+ ssize_t bytes_written =
757+ fwrite (iov [i ].buf , 1 , iov [i ].buf_len , f );
758+ if (bytes_written < 0 )
759+ return convert_errno (- bytes_written );
760+ total_written += bytes_written ;
761+ }
714762 }
715763
716764 * nwritten = total_written ;
@@ -991,6 +1039,8 @@ os_convert_stdin_handle(os_raw_file_handle raw_stdin)
9911039
9921040 handle -> fd = STDIN_FILENO ;
9931041 handle -> is_sock = false;
1042+ handle -> is_stdio = true;
1043+ handle -> raw_fd = raw_stdin >= 0 ? raw_stdin : -1 ;
9941044 return handle ;
9951045}
9961046
@@ -1003,6 +1053,8 @@ os_convert_stdout_handle(os_raw_file_handle raw_stdout)
10031053
10041054 handle -> fd = STDOUT_FILENO ;
10051055 handle -> is_sock = false;
1056+ handle -> is_stdio = true;
1057+ handle -> raw_fd = raw_stdout >= 0 ? raw_stdout : -1 ;
10061058 return handle ;
10071059}
10081060
@@ -1015,6 +1067,8 @@ os_convert_stderr_handle(os_raw_file_handle raw_stderr)
10151067
10161068 handle -> fd = STDERR_FILENO ;
10171069 handle -> is_sock = false;
1070+ handle -> is_stdio = true;
1071+ handle -> raw_fd = raw_stderr >= 0 ? raw_stderr : -1 ;
10181072 return handle ;
10191073}
10201074
@@ -1210,17 +1264,17 @@ os_compare_file_handle(os_file_handle handle1, os_file_handle handle2)
12101264bool
12111265os_is_stdin_handle (os_file_handle handle )
12121266{
1213- return ( handle == ( os_file_handle ) stdin ) ;
1267+ return handle != NULL && handle -> is_stdio && handle -> fd == STDIN_FILENO ;
12141268}
12151269
12161270bool
12171271os_is_stdout_handle (os_file_handle handle )
12181272{
1219- return ( handle == ( os_file_handle ) stdout ) ;
1273+ return handle != NULL && handle -> is_stdio && handle -> fd == STDOUT_FILENO ;
12201274}
12211275
12221276bool
12231277os_is_stderr_handle (os_file_handle handle )
12241278{
1225- return ( handle == ( os_file_handle ) stderr ) ;
1279+ return handle != NULL && handle -> is_stdio && handle -> fd == STDERR_FILENO ;
12261280}
0 commit comments