3 * @brief Public header for libpreopen
5 * Copyright (c) 2016 Stanley Uche Godfrey
6 * Copyright (c) 2016, 2018 Jonathan Anderson
9 * This software was developed at Memorial University under the
10 * NSERC Discovery program (RGPIN-2015-06048).
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 #ifdef __wasilibc_unmodified_upstream
38 #include <sys/cdefs.h>
40 #include <sys/capsicum.h>
49 * @brief A mapping from paths to pre-opened directories.
51 * This type is opaque to clients, but it is reference-counted and can be
52 * thought of as containing a set (with no particular ordering guarantees)
53 * of path->dirfd mappings.
57 #ifdef __wasilibc_unmodified_upstream
59 * A callback that can be used to inpect the contents of a @ref po_map.
61 * This callback can be invoked by iteration code to expose elements of a
62 * @ref po_map (in no particular order).
64 * @returns whether or not to continue iterating over the @ref po_map
66 typedef bool (po_map_iter_cb
)(const char *dirname
, int dirfd
, cap_rights_t
);
69 * A simple @ref po_map_iter_cb that will print a @ref po_map's entries,
72 po_map_iter_cb po_print_entry
;
76 * A filesystem path, relative to a directory descriptor.
79 /** The directory the path is relative to */
82 /** The path, relative to the directory represented by @ref dirfd */
83 const char *relative_path
;
85 #ifdef __wasilibc_unmodified_upstream
87 // This functionality is exposed in a libc header, so include that header
88 // and use its declarations.
89 #include <wasi/libc-find-relpath.h>
93 * Create a @ref po_map of at least the specified capacity.
95 * The returned @ref po_map will have a reference count of 1.
97 #ifdef __wasilibc_unmodified_upstream
101 struct po_map
* po_map_create(int capacity
);
104 * Release a reference to a @ref po_map.
106 * This may cause memory to be freed.
108 #ifdef __wasilibc_unmodified_upstream
112 void po_map_release(struct po_map
*);
114 #ifdef __wasilibc_unmodified_upstream
116 * Iterate over a @ref po_map, invoking a callback for each element in the map.
118 * This function will cause @b callback to be invoked repeatedly, in no
119 * particular order, until the entire map has been iterated over or until the
120 * callback returns `false`.
122 * @return number of elements iterated over
124 size_t po_map_foreach(const struct po_map
*, po_map_iter_cb
);
128 * Add an already-opened directory to a @ref po_map.
130 * @param map the map to add the path->fd mapping to
131 * @param path the path that will map to this directory
132 * (which may or may not be the path used to open it)
133 * @param fd the directory descriptor (must be a directory!)
135 #ifdef __wasilibc_unmodified_upstream
139 struct po_map
* po_add(struct po_map
*map
, const char *path
, int fd
);
141 #ifdef __wasilibc_unmodified_upstream
143 * Pre-open a path and store it in a @ref po_map for later use.
145 * @param map the map to add the path->fd mapping to
146 * @param path the path to pre-open (which may be a directory if
147 * `O_DIRECTORY` is passed via @b flags)
148 * @param flags flags to pass to `open(2)` / `openat(2)`
149 * @param ... optional file mode, as accepted by `open(2)`
151 * @returns the file descriptor of the opened directory or -1 if
152 * @b path is not a directory or cannot be opened or if
153 * the @ref po_map cannot store the directory (e.g., resizing fails)
155 int po_preopen(struct po_map
*map
, const char *path
, int flags
, ...);
159 * Find a directory whose path is a prefix of @b path and (on platforms that
160 * support Capsicum) that has the rights required by @b rights.
162 * @param map the map to look for a directory in
163 * @param path the path we want to find a pre-opened prefix for
164 * @param rights if non-NULL on a platform with Capsicum support,
165 * the rights any directory descriptor must have to
167 * @returns a @ref po_relpath containing the descriptor of the best-match
168 * directory in the map (or -1 if none was found) and the remaining
169 * path, relative to the file (or undefined if no match found)
171 #ifdef __wasilibc_unmodified_upstream
172 struct po_relpath
po_find(struct po_map
*map
, const char *path
,
173 cap_rights_t
*rights
);
175 static struct po_relpath
po_find(struct po_map
*map
, const char *path
,
176 __wasi_rights_t rights_base
, __wasi_rights_t rights_inheriting
);
179 #ifdef __wasilibc_unmodified_upstream
181 * Retrieve a message from with the last libpreopen error.
183 * @returns NULL if there are no errors, null-terminated string otherwise
185 const char* po_last_error(void);
188 * Pack a `struct po_map` into a shared memory segment.
190 * To inherit a `po_map` across the process execution boundary, it needs to be
191 * packed into an inheritable form such as a shared memory segment. This can
192 * then be unpacked in the child process for direct access.
194 * @param map the map to pack into shared memory
196 * @returns a file descriptor of a shared memory segment
199 int po_pack(struct po_map
*map
);
202 * Unpack a `struct po_map` from a file.
204 * Using the representation generated by `po_pack`, unpack a `po_map`
205 * and make it available for normal usage.
207 * @param fd a file containing a packed `po_map` representation
209 struct po_map
* po_unpack(int fd
);
214 #endif /* !LIBPO_H */