Skip to content

Commit 240549f

Browse files
committed
Add system calls for describing preopened directory handles.
1 parent 236f025 commit 240549f

File tree

6 files changed

+89
-2
lines changed

6 files changed

+89
-2
lines changed

expected/wasm32-wasi/predefined-macros.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3523,6 +3523,7 @@
35233523
#define __WASI_O_DIRECTORY (UINT16_C(0x0002))
35243524
#define __WASI_O_EXCL (UINT16_C(0x0004))
35253525
#define __WASI_O_TRUNC (UINT16_C(0x0008))
3526+
#define __WASI_PREOPENTYPE_DIR (UINT8_C(0))
35263527
#define __WASI_RIGHT_FD_ADVISE (UINT64_C(0x0000000000000080))
35273528
#define __WASI_RIGHT_FD_ALLOCATE (UINT64_C(0x0000000000000100))
35283529
#define __WASI_RIGHT_FD_DATASYNC (UINT64_C(0x0000000000000001))

expected/wasm32-wasi/undefined-symbols.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ __wasi_fd_filestat_get
3939
__wasi_fd_filestat_set_size
4040
__wasi_fd_filestat_set_times
4141
__wasi_fd_pread
42+
__wasi_fd_prestat_dir_name
43+
__wasi_fd_prestat_get
4244
__wasi_fd_pwrite
4345
__wasi_fd_read
4446
__wasi_fd_readdir

libc-bottom-half/crt/crt1.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <stdlib.h>
22
#include <sysexits.h>
33
#include <wasi/core.h>
4+
#include <wasi/libc.h>
45

56
extern char **__environ;
67
extern void __wasm_call_ctors(void);
@@ -64,7 +65,53 @@ static __wasi_errno_t populate_environ(void) {
6465
return __wasi_environ_get(__environ, environ_buf);
6566
}
6667

68+
static __wasi_errno_t populate_libpreopen(void) {
69+
__wasilibc_init_preopen();
70+
71+
// Skip stdin, stdout, and stderr, and count up until we reach an invalid
72+
// file descriptor.
73+
for (__wasi_fd_t fd = 3; fd != 0; ++fd) {
74+
__wasi_prestat_t prestat;
75+
__wasi_errno_t ret = __wasi_fd_prestat_get(fd, &prestat);
76+
if (ret == __WASI_EBADF)
77+
break;
78+
if (ret != __WASI_ESUCCESS)
79+
return ret;
80+
switch (prestat.pr_type) {
81+
case __WASI_PREOPENTYPE_DIR: {
82+
char *path = malloc(prestat.u.dir.pr_name_len + 1);
83+
if (path == NULL)
84+
return __WASI_ENOMEM;
85+
86+
ret = __wasi_fd_prestat_dir_name(fd, path, prestat.u.dir.pr_name_len);
87+
if (ret != __WASI_ESUCCESS) {
88+
free(path);
89+
return ret;
90+
}
91+
path[prestat.u.dir.pr_name_len] = '\0';
92+
93+
if (__wasilibc_register_preopened_fd(fd, path) != 0) {
94+
free(path);
95+
return __WASI_ENOMEM;
96+
}
97+
98+
free(path);
99+
break;
100+
}
101+
default:
102+
break;
103+
}
104+
}
105+
106+
return __WASI_ESUCCESS;
107+
}
108+
67109
void _start(void) {
110+
/* Record the preopened resources. */
111+
if (populate_libpreopen() != __WASI_ESUCCESS) {
112+
_Exit(EX_OSERR);
113+
}
114+
68115
/* Fill in the environment from WASI syscalls. */
69116
if (populate_environ() != __WASI_ESUCCESS) {
70117
_Exit(EX_OSERR);

libc-bottom-half/headers/public/wasi/core.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,9 @@ typedef uint8_t __wasi_whence_t;
270270
#define __WASI_WHENCE_END (UINT8_C(1))
271271
#define __WASI_WHENCE_SET (UINT8_C(2))
272272

273+
typedef uint8_t __wasi_preopentype_t;
274+
#define __WASI_PREOPENTYPE_DIR (UINT8_C(0))
275+
273276
typedef struct __wasi_dirent_t {
274277
__wasi_dircookie_t d_next;
275278
__wasi_inode_t d_ino;
@@ -304,6 +307,28 @@ _Static_assert(
304307
_Static_assert(sizeof(__wasi_event_t) == 32, "non-wasi data layout");
305308
_Static_assert(_Alignof(__wasi_event_t) == 8, "non-wasi data layout");
306309

310+
typedef struct __wasi_prestat_t {
311+
__wasi_preopentype_t pr_type;
312+
union __wasi_prestat_u {
313+
struct __wasi_prestat_u_dir_t {
314+
size_t pr_name_len;
315+
} dir;
316+
} u;
317+
} __wasi_prestat_t;
318+
_Static_assert(offsetof(__wasi_prestat_t, pr_type) == 0, "non-wasi data layout");
319+
_Static_assert(sizeof(void *) != 4 ||
320+
offsetof(__wasi_prestat_t, u.dir.pr_name_len) == 4, "non-wasi data layout");
321+
_Static_assert(sizeof(void *) != 8 ||
322+
offsetof(__wasi_prestat_t, u.dir.pr_name_len) == 8, "non-wasi data layout");
323+
_Static_assert(sizeof(void *) != 4 ||
324+
sizeof(__wasi_prestat_t) == 8, "non-wasi data layout");
325+
_Static_assert(sizeof(void *) != 8 ||
326+
sizeof(__wasi_prestat_t) == 16, "non-wasi data layout");
327+
_Static_assert(sizeof(void *) != 4 ||
328+
_Alignof(__wasi_prestat_t) == 4, "non-wasi data layout");
329+
_Static_assert(sizeof(void *) != 8 ||
330+
_Alignof(__wasi_prestat_t) == 8, "non-wasi data layout");
331+
307332
typedef struct __wasi_fdstat_t {
308333
__wasi_filetype_t fs_filetype;
309334
__wasi_fdflags_t fs_flags;
@@ -457,6 +482,17 @@ __wasi_errno_t __wasi_environ_sizes_get(
457482
size_t *environ_buf_size
458483
) __WASI_SYSCALL_NAME(environ_sizes_get) __attribute__((__warn_unused_result__));
459484

485+
__wasi_errno_t __wasi_fd_prestat_get(
486+
__wasi_fd_t fd,
487+
__wasi_prestat_t *buf
488+
) __WASI_SYSCALL_NAME(fd_prestat_get) __attribute__((__warn_unused_result__));
489+
490+
__wasi_errno_t __wasi_fd_prestat_dir_name(
491+
__wasi_fd_t fd,
492+
char *path,
493+
size_t path_len
494+
) __WASI_SYSCALL_NAME(fd_prestat_dir_name) __attribute__((__warn_unused_result__));
495+
460496
__wasi_errno_t __wasi_fd_close(
461497
__wasi_fd_t fd
462498
) __WASI_SYSCALL_NAME(fd_close) __attribute__((__warn_unused_result__));

libc-bottom-half/headers/public/wasi/libc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
extern "C" {
66
#endif
77

8+
void __wasilibc_init_preopen(void);
89
int __wasilibc_register_preopened_fd(int fd, const char *path);
910
int __wasilibc_fd_renumber(int fd, int newfd);
1011
int __wasilibc_rmfileat(int fd, const char *path);

libc-top-half/musl/src/stdio/fopen.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ FILE *fopen(const char *restrict filename, const char *restrict mode)
2828
fd = open(filename, flags, 0666);
2929
#endif
3030
if (fd < 0) return 0;
31-
if (flags & O_CLOEXEC)
3231
#ifdef __wasilibc_unmodified_upstream
32+
if (flags & O_CLOEXEC)
3333
__syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC);
3434
#else
35-
/* Avoid __syscall, but also, FD_CLOEXEC is not supported in WASI. */
35+
/* Avoid __syscall, but also, FD_CLOEXEC is not supported in WASI. */
3636
#endif
3737

3838
f = __fdopen(fd, mode);

0 commit comments

Comments
 (0)