Skip to content

Commit da964d2

Browse files
committed
fix(zephyr): stdio handling
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
1 parent bc63d24 commit da964d2

3 files changed

Lines changed: 78 additions & 17 deletions

File tree

core/shared/platform/zephyr/platform_internal.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,8 +278,11 @@ typedef struct zephyr_fs_desc {
278278

279279
// definition of zephyr_handle
280280
typedef struct zephyr_handle {
281-
int fd;
282-
bool is_sock;
281+
int fd; // virtual fd number (0=stdin, 1=stdout, 2=stderr) or desc_array
282+
// index
283+
bool is_sock; // true if this is a socket
284+
bool is_stdio; // true if this is a stdio handle (stdin/stdout/stderr)
285+
int raw_fd; // real OS file descriptor for stdio, or -1 if using defaults
283286
} zephyr_handle;
284287

285288
typedef struct zephyr_handle *os_file_handle;

core/shared/platform/zephyr/zephyr_file.c

Lines changed: 69 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
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
597606
os_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
638648
os_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
675690
os_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
708741
os_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)
12231277
bool
12241278
os_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

12291283
bool
12301284
os_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

12351289
bool
12361290
os_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
}

core/shared/platform/zephyr/zephyr_socket.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ os_socket_create(bh_socket_t *sock, bool is_ipv4, bool is_tcp)
209209
}
210210

211211
(*sock)->is_sock = true;
212+
(*sock)->is_stdio = false;
213+
(*sock)->raw_fd = -1;
212214

213215
if ((*sock)->fd == -1) {
214216
BH_FREE(*sock);
@@ -300,6 +302,8 @@ os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr,
300302
}
301303

302304
(*sock)->is_sock = true;
305+
(*sock)->is_stdio = false;
306+
(*sock)->raw_fd = -1;
303307

304308
return BHT_OK;
305309
}

0 commit comments

Comments
 (0)