From f75610557d81b556700bb856f249fdfda9d15160 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 3 Apr 2019 14:00:59 -0700 Subject: [PATCH 1/3] Provide a public interface to preopened directory lookups. For users of especially non-C compilers, provide an API for looking up preopened directories. This is used internally in WASI libc to translate from eg. `open` to `openat`, but it can now also be used by user code. --- expected/wasm32-wasi/defined-symbols.txt | 1 + expected/wasm32-wasi/include-all.c | 1 + expected/wasm32-wasi/predefined-macros.txt | 1 + .../headers/public/wasi/libc-find-relpath.h | 36 +++++++++++++++++++ .../libpreopen/include/libpreopen.h | 7 ++++ .../libpreopen/lib/po_libc_wrappers.c | 7 ++++ 6 files changed, 53 insertions(+) create mode 100644 libc-bottom-half/headers/public/wasi/libc-find-relpath.h diff --git a/expected/wasm32-wasi/defined-symbols.txt b/expected/wasm32-wasi/defined-symbols.txt index 6c0dc4e24..716b119a8 100644 --- a/expected/wasm32-wasi/defined-symbols.txt +++ b/expected/wasm32-wasi/defined-symbols.txt @@ -242,6 +242,7 @@ __unlist_locked_file __uselocale __utc __wasilibc_fd_renumber +__wasilibc_find_relpath __wasilibc_init_preopen __wasilibc_register_preopened_fd __wasilibc_rmdirat diff --git a/expected/wasm32-wasi/include-all.c b/expected/wasm32-wasi/include-all.c index 8295222d1..62760dd2d 100644 --- a/expected/wasm32-wasi/include-all.c +++ b/expected/wasm32-wasi/include-all.c @@ -183,6 +183,7 @@ #include #include #include +#include #include #include #include diff --git a/expected/wasm32-wasi/predefined-macros.txt b/expected/wasm32-wasi/predefined-macros.txt index 7c89429ec..9b636b8d1 100644 --- a/expected/wasm32-wasi/predefined-macros.txt +++ b/expected/wasm32-wasi/predefined-macros.txt @@ -3622,6 +3622,7 @@ #define __va_copy(d,s) __builtin_va_copy(d,s) #define __wasi__ 1 #define __wasi_core_h +#define __wasi_libc_find_relpath_h #define __wasi_libc_h #define __wasilibc___errno_values_h #define __wasilibc___fd_set_h diff --git a/libc-bottom-half/headers/public/wasi/libc-find-relpath.h b/libc-bottom-half/headers/public/wasi/libc-find-relpath.h new file mode 100644 index 000000000..87ba546b3 --- /dev/null +++ b/libc-bottom-half/headers/public/wasi/libc-find-relpath.h @@ -0,0 +1,36 @@ +#ifndef __wasi_libc_find_relpath_h +#define __wasi_libc_find_relpath_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * A directory file descriptor plus a relative path within that directory. + */ +struct __wasilibc_relpath { + /** File descriptor for the directory the path is relative to */ + int dirfd; + + /** The relative path from that directory */ + const char *relative_path; +}; + +/** + * Look up the given path in the preopened directory map and return + * a file descriptor and relative path that can be used to access it. + * Ignore preopened directories which don't provide the specified + * rights. + * + * Returns a `__wasilibc_relpath` with a `dirfd` of -1 if no preopened + * directories were suitable. + */ +struct __wasilibc_relpath __wasilibc_find_relpath(const char *path, + __wasi_rights_t rights_base, + __wasi_rights_t rights_inheriting); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libc-bottom-half/libpreopen/include/libpreopen.h b/libc-bottom-half/libpreopen/include/libpreopen.h index 8185dcfa0..834990325 100644 --- a/libc-bottom-half/libpreopen/include/libpreopen.h +++ b/libc-bottom-half/libpreopen/include/libpreopen.h @@ -72,6 +72,7 @@ typedef bool (po_map_iter_cb)(const char *dirname, int dirfd, cap_rights_t); po_map_iter_cb po_print_entry; #endif +#ifdef __wasilibc_unmodified_upstream /** * A filesystem path, relative to a directory descriptor. */ @@ -82,6 +83,12 @@ struct po_relpath { /** The path, relative to the directory represented by @ref dirfd */ const char *relative_path; }; +#else +// This functionality is exposed in a libc header, so include that header +// and use its declarations. +#include +#define po_relpath __wasilibc_relpath +#endif /** * Create a @ref po_map of at least the specified capacity. diff --git a/libc-bottom-half/libpreopen/lib/po_libc_wrappers.c b/libc-bottom-half/libpreopen/lib/po_libc_wrappers.c index a6d444531..38baa23be 100644 --- a/libc-bottom-half/libpreopen/lib/po_libc_wrappers.c +++ b/libc-bottom-half/libpreopen/lib/po_libc_wrappers.c @@ -682,4 +682,11 @@ __wasilibc_register_preopened_fd(int fd, const char *path) return 0; } + +struct __wasilibc_relpath __wasilibc_find_relpath(const char *path, + __wasi_rights_t rights_base, + __wasi_rights_t rights_inheriting) +{ + return find_relative(path, rights_base, rights_inheriting); +} #endif From 5ecaad92e606f8b77e34e84248943ee21386b76f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 3 Apr 2019 20:03:26 -0700 Subject: [PATCH 2/3] Separate the error status from the returned value in __wasilibc_find_relpath. --- .../headers/public/wasi/libc-find-relpath.h | 19 ++++++++++--------- .../libpreopen/lib/po_libc_wrappers.c | 14 ++++++++++---- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/libc-bottom-half/headers/public/wasi/libc-find-relpath.h b/libc-bottom-half/headers/public/wasi/libc-find-relpath.h index 87ba546b3..169de8d9b 100644 --- a/libc-bottom-half/headers/public/wasi/libc-find-relpath.h +++ b/libc-bottom-half/headers/public/wasi/libc-find-relpath.h @@ -17,17 +17,18 @@ struct __wasilibc_relpath { }; /** - * Look up the given path in the preopened directory map and return - * a file descriptor and relative path that can be used to access it. - * Ignore preopened directories which don't provide the specified - * rights. + * Look up the given path in the preopened directory map and store + * a file descriptor and relative path that can be used to access it + * in *relpath. Ignore preopened directories which don't provide the + * specified rights. * - * Returns a `__wasilibc_relpath` with a `dirfd` of -1 if no preopened - * directories were suitable. + * Returns 0 if a suitable preopened directory was found, or -1 if + * no directories were suitable. */ -struct __wasilibc_relpath __wasilibc_find_relpath(const char *path, - __wasi_rights_t rights_base, - __wasi_rights_t rights_inheriting); +int __wasilibc_find_relpath(const char *path, + __wasi_rights_t rights_base, + __wasi_rights_t rights_inheriting, + struct __wasilibc_relpath *relpath); #ifdef __cplusplus } diff --git a/libc-bottom-half/libpreopen/lib/po_libc_wrappers.c b/libc-bottom-half/libpreopen/lib/po_libc_wrappers.c index 38baa23be..080c27503 100644 --- a/libc-bottom-half/libpreopen/lib/po_libc_wrappers.c +++ b/libc-bottom-half/libpreopen/lib/po_libc_wrappers.c @@ -683,10 +683,16 @@ __wasilibc_register_preopened_fd(int fd, const char *path) return 0; } -struct __wasilibc_relpath __wasilibc_find_relpath(const char *path, - __wasi_rights_t rights_base, - __wasi_rights_t rights_inheriting) +int __wasilibc_find_relpath(const char *path, + __wasi_rights_t rights_base, + __wasi_rights_t rights_inheriting, + struct __wasilibc_relpath *relpath) { - return find_relative(path, rights_base, rights_inheriting); + struct po_relpath rel = find_relative(path, rights_base, rights_inheriting); + if (rel.dirfd == -1) { + return -1; + } + *relpath = rel; + return 0; } #endif From 1a5dc49a6fb638087d1e3482e410d87eebf7b011 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 4 Apr 2019 20:06:08 -0700 Subject: [PATCH 3/3] Further simplify: avoid the __wasilibc_relpath struct altogether. Just return the file descriptor, and use an out parameter for the relative path. --- .../headers/public/wasi/libc-find-relpath.h | 24 +++++-------------- .../libpreopen/include/libpreopen.h | 3 +-- .../libpreopen/lib/po_libc_wrappers.c | 9 +++---- 3 files changed, 10 insertions(+), 26 deletions(-) diff --git a/libc-bottom-half/headers/public/wasi/libc-find-relpath.h b/libc-bottom-half/headers/public/wasi/libc-find-relpath.h index 169de8d9b..9f5fab3d8 100644 --- a/libc-bottom-half/headers/public/wasi/libc-find-relpath.h +++ b/libc-bottom-half/headers/public/wasi/libc-find-relpath.h @@ -6,29 +6,17 @@ extern "C" { #endif /** - * A directory file descriptor plus a relative path within that directory. - */ -struct __wasilibc_relpath { - /** File descriptor for the directory the path is relative to */ - int dirfd; - - /** The relative path from that directory */ - const char *relative_path; -}; - -/** - * Look up the given path in the preopened directory map and store - * a file descriptor and relative path that can be used to access it - * in *relpath. Ignore preopened directories which don't provide the - * specified rights. + * Look up the given path in the preopened directory map. If a suitable + * entry is found, return its directory file descriptor, and store the + * computed relative path in *relative_path. Ignore preopened directories + * which don't provide the specified rights. * - * Returns 0 if a suitable preopened directory was found, or -1 if - * no directories were suitable. + * Returns -1 if no directories were suitable. */ int __wasilibc_find_relpath(const char *path, __wasi_rights_t rights_base, __wasi_rights_t rights_inheriting, - struct __wasilibc_relpath *relpath); + const char **relative_path); #ifdef __cplusplus } diff --git a/libc-bottom-half/libpreopen/include/libpreopen.h b/libc-bottom-half/libpreopen/include/libpreopen.h index 834990325..9c86b9fe1 100644 --- a/libc-bottom-half/libpreopen/include/libpreopen.h +++ b/libc-bottom-half/libpreopen/include/libpreopen.h @@ -72,7 +72,6 @@ typedef bool (po_map_iter_cb)(const char *dirname, int dirfd, cap_rights_t); po_map_iter_cb po_print_entry; #endif -#ifdef __wasilibc_unmodified_upstream /** * A filesystem path, relative to a directory descriptor. */ @@ -83,11 +82,11 @@ struct po_relpath { /** The path, relative to the directory represented by @ref dirfd */ const char *relative_path; }; +#ifdef __wasilibc_unmodified_upstream #else // This functionality is exposed in a libc header, so include that header // and use its declarations. #include -#define po_relpath __wasilibc_relpath #endif /** diff --git a/libc-bottom-half/libpreopen/lib/po_libc_wrappers.c b/libc-bottom-half/libpreopen/lib/po_libc_wrappers.c index 080c27503..5aead7931 100644 --- a/libc-bottom-half/libpreopen/lib/po_libc_wrappers.c +++ b/libc-bottom-half/libpreopen/lib/po_libc_wrappers.c @@ -686,13 +686,10 @@ __wasilibc_register_preopened_fd(int fd, const char *path) int __wasilibc_find_relpath(const char *path, __wasi_rights_t rights_base, __wasi_rights_t rights_inheriting, - struct __wasilibc_relpath *relpath) + const char **relpath) { struct po_relpath rel = find_relative(path, rights_base, rights_inheriting); - if (rel.dirfd == -1) { - return -1; - } - *relpath = rel; - return 0; + *relpath = rel.relative_path; + return rel.dirfd; } #endif