Skip to content

Commit 33da0d0

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

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
@@ -260,8 +260,11 @@ typedef struct zephyr_fs_desc {
260260

261261
// definition of zephyr_handle
262262
typedef struct zephyr_handle {
263-
int fd;
264-
bool is_sock;
263+
int fd; // virtual fd number (0=stdin, 1=stdout, 2=stderr) or desc_array
264+
// index
265+
bool is_sock; // true if this is a socket
266+
bool is_stdio; // true if this is a stdio handle (stdin/stdout/stderr)
267+
int raw_fd; // real OS file descriptor for stdio, or -1 if using defaults
265268
} zephyr_handle;
266269

267270
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>
@@ -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
594603
os_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
634644
os_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
670685
os_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
702735
os_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)
12101264
bool
12111265
os_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

12161270
bool
12171271
os_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

12221276
bool
12231277
os_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
}

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)