]> git.proxmox.com Git - wasi-libc.git/blob - libc-bottom-half/libpreopen/include/libpreopen.h
Provide a public interface to preopened directory lookups. (#10)
[wasi-libc.git] / libc-bottom-half / libpreopen / include / libpreopen.h
1 /**
2 * @file libpreopen.h
3 * @brief Public header for libpreopen
4 *
5 * Copyright (c) 2016 Stanley Uche Godfrey
6 * Copyright (c) 2016, 2018 Jonathan Anderson
7 * All rights reserved.
8 *
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
13 * are met:
14 *
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.
20 *
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
31 * SUCH DAMAGE.
32 */
33
34 #ifndef LIBPO_H
35 #define LIBPO_H
36
37 #ifdef __wasilibc_unmodified_upstream
38 #include <sys/cdefs.h>
39 #endif
40 #include <sys/capsicum.h>
41
42 #include <stdbool.h>
43
44
45 __BEGIN_DECLS
46
47 /**
48 * @struct po_map
49 * @brief A mapping from paths to pre-opened directories.
50 *
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.
54 */
55 struct po_map;
56
57 #ifdef __wasilibc_unmodified_upstream
58 /**
59 * A callback that can be used to inpect the contents of a @ref po_map.
60 *
61 * This callback can be invoked by iteration code to expose elements of a
62 * @ref po_map (in no particular order).
63 *
64 * @returns whether or not to continue iterating over the @ref po_map
65 */
66 typedef bool (po_map_iter_cb)(const char *dirname, int dirfd, cap_rights_t);
67
68 /**
69 * A simple @ref po_map_iter_cb that will print a @ref po_map's entries,
70 * one per line.
71 */
72 po_map_iter_cb po_print_entry;
73 #endif
74
75 /**
76 * A filesystem path, relative to a directory descriptor.
77 */
78 struct po_relpath {
79 /** The directory the path is relative to */
80 int dirfd;
81
82 /** The path, relative to the directory represented by @ref dirfd */
83 const char *relative_path;
84 };
85 #ifdef __wasilibc_unmodified_upstream
86 #else
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>
90 #endif
91
92 /**
93 * Create a @ref po_map of at least the specified capacity.
94 *
95 * The returned @ref po_map will have a reference count of 1.
96 */
97 #ifdef __wasilibc_unmodified_upstream
98 #else
99 static
100 #endif
101 struct po_map* po_map_create(int capacity);
102
103 /**
104 * Release a reference to a @ref po_map.
105 *
106 * This may cause memory to be freed.
107 */
108 #ifdef __wasilibc_unmodified_upstream
109 #else
110 static
111 #endif
112 void po_map_release(struct po_map *);
113
114 #ifdef __wasilibc_unmodified_upstream
115 /**
116 * Iterate over a @ref po_map, invoking a callback for each element in the map.
117 *
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`.
121 *
122 * @return number of elements iterated over
123 */
124 size_t po_map_foreach(const struct po_map*, po_map_iter_cb);
125 #endif
126
127 /**
128 * Add an already-opened directory to a @ref po_map.
129 *
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!)
134 */
135 #ifdef __wasilibc_unmodified_upstream
136 #else
137 static
138 #endif
139 struct po_map* po_add(struct po_map *map, const char *path, int fd);
140
141 #ifdef __wasilibc_unmodified_upstream
142 /**
143 * Pre-open a path and store it in a @ref po_map for later use.
144 *
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)`
150 *
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)
154 */
155 int po_preopen(struct po_map *map, const char *path, int flags, ...);
156 #endif
157
158 /**
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.
161 *
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
166 * qualify as a match
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)
170 */
171 #ifdef __wasilibc_unmodified_upstream
172 struct po_relpath po_find(struct po_map *map, const char *path,
173 cap_rights_t *rights);
174 #else
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);
177 #endif
178
179 #ifdef __wasilibc_unmodified_upstream
180 /**
181 * Retrieve a message from with the last libpreopen error.
182 *
183 * @returns NULL if there are no errors, null-terminated string otherwise
184 */
185 const char* po_last_error(void);
186
187 /**
188 * Pack a `struct po_map` into a shared memory segment.
189 *
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.
193 *
194 * @param map the map to pack into shared memory
195 *
196 * @returns a file descriptor of a shared memory segment
197 * (or -1 on error)
198 */
199 int po_pack(struct po_map *map);
200
201 /**
202 * Unpack a `struct po_map` from a file.
203 *
204 * Using the representation generated by `po_pack`, unpack a `po_map`
205 * and make it available for normal usage.
206 *
207 * @param fd a file containing a packed `po_map` representation
208 */
209 struct po_map* po_unpack(int fd);
210 #endif
211
212 __END_DECLS
213
214 #endif /* !LIBPO_H */
215