Skip to content

Commit 70b45b2

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

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>
@@ -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
569578
os_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
610620
os_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
647662
os_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
680713
os_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)
11951249
bool
11961250
os_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

12011255
bool
12021256
os_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

12071261
bool
12081262
os_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
}

core/shared/platform/zephyr/zephyr_socket.c

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

205205
(*sock)->is_sock = true;
206+
(*sock)->is_stdio = false;
207+
(*sock)->raw_fd = -1;
206208

207209
if ((*sock)->fd == -1) {
208210
BH_FREE(*sock);
@@ -294,6 +296,8 @@ os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr,
294296
}
295297

296298
(*sock)->is_sock = true;
299+
(*sock)->is_stdio = false;
300+
(*sock)->raw_fd = -1;
297301

298302
return BHT_OK;
299303
}

0 commit comments

Comments
 (0)