]>
Commit | Line | Data |
---|---|---|
320054e8 DG |
1 | // Copyright (c) 2015-2016 Nuxi, https://nuxi.nl/ |
2 | // | |
3 | // SPDX-License-Identifier: BSD-2-Clause | |
4 | ||
320054e8 | 5 | #include <assert.h> |
446cb3f1 | 6 | #include <wasi/api.h> |
a94d2d04 | 7 | #include <wasi/libc.h> |
320054e8 DG |
8 | #include <errno.h> |
9 | #include <fcntl.h> | |
10 | #include <string.h> | |
11 | ||
446cb3f1 DG |
12 | static_assert(O_APPEND == __WASI_FDFLAGS_APPEND, "Value mismatch"); |
13 | static_assert(O_DSYNC == __WASI_FDFLAGS_DSYNC, "Value mismatch"); | |
14 | static_assert(O_NONBLOCK == __WASI_FDFLAGS_NONBLOCK, "Value mismatch"); | |
15 | static_assert(O_RSYNC == __WASI_FDFLAGS_RSYNC, "Value mismatch"); | |
16 | static_assert(O_SYNC == __WASI_FDFLAGS_SYNC, "Value mismatch"); | |
320054e8 | 17 | |
446cb3f1 DG |
18 | static_assert(O_CREAT >> 12 == __WASI_OFLAGS_CREAT, "Value mismatch"); |
19 | static_assert(O_DIRECTORY >> 12 == __WASI_OFLAGS_DIRECTORY, "Value mismatch"); | |
20 | static_assert(O_EXCL >> 12 == __WASI_OFLAGS_EXCL, "Value mismatch"); | |
21 | static_assert(O_TRUNC >> 12 == __WASI_OFLAGS_TRUNC, "Value mismatch"); | |
320054e8 | 22 | |
f2e779e5 | 23 | int __wasilibc_nocwd_openat_nomode(int fd, const char *path, int oflag) { |
320054e8 DG |
24 | // Compute rights corresponding with the access modes provided. |
25 | // Attempt to obtain all rights, except the ones that contradict the | |
26 | // access mode provided to openat(). | |
320054e8 | 27 | __wasi_rights_t max = |
446cb3f1 DG |
28 | ~(__WASI_RIGHTS_FD_DATASYNC | __WASI_RIGHTS_FD_READ | |
29 | __WASI_RIGHTS_FD_WRITE | __WASI_RIGHTS_FD_ALLOCATE | | |
f2e779e5 | 30 | __WASI_RIGHTS_FD_READDIR | __WASI_RIGHTS_FD_FILESTAT_SET_SIZE); |
320054e8 DG |
31 | switch (oflag & O_ACCMODE) { |
32 | case O_RDONLY: | |
33 | case O_RDWR: | |
34 | case O_WRONLY: | |
35 | if ((oflag & O_RDONLY) != 0) { | |
446cb3f1 | 36 | max |= __WASI_RIGHTS_FD_READ | __WASI_RIGHTS_FD_READDIR; |
320054e8 DG |
37 | } |
38 | if ((oflag & O_WRONLY) != 0) { | |
446cb3f1 DG |
39 | max |= __WASI_RIGHTS_FD_DATASYNC | __WASI_RIGHTS_FD_WRITE | |
40 | __WASI_RIGHTS_FD_ALLOCATE | | |
41 | __WASI_RIGHTS_FD_FILESTAT_SET_SIZE; | |
320054e8 DG |
42 | } |
43 | break; | |
44 | case O_EXEC: | |
320054e8 DG |
45 | break; |
46 | case O_SEARCH: | |
47 | break; | |
48 | default: | |
49 | errno = EINVAL; | |
50 | return -1; | |
51 | } | |
320054e8 DG |
52 | |
53 | // Ensure that we can actually obtain the minimal rights needed. | |
54 | __wasi_fdstat_t fsb_cur; | |
320054e8 | 55 | __wasi_errno_t error = __wasi_fd_fdstat_get(fd, &fsb_cur); |
320054e8 DG |
56 | if (error != 0) { |
57 | errno = error; | |
58 | return -1; | |
59 | } | |
320054e8 DG |
60 | |
61 | // Path lookup properties. | |
320054e8 | 62 | __wasi_lookupflags_t lookup_flags = 0; |
320054e8 | 63 | if ((oflag & O_NOFOLLOW) == 0) |
446cb3f1 | 64 | lookup_flags |= __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW; |
320054e8 DG |
65 | |
66 | // Open file with appropriate rights. | |
320054e8 DG |
67 | __wasi_fdflags_t fs_flags = oflag & 0xfff; |
68 | __wasi_rights_t fs_rights_base = max & fsb_cur.fs_rights_inheriting; | |
69 | __wasi_rights_t fs_rights_inheriting = fsb_cur.fs_rights_inheriting; | |
70 | __wasi_fd_t newfd; | |
2b7e73ae | 71 | error = __wasi_path_open(fd, lookup_flags, path, |
320054e8 DG |
72 | (oflag >> 12) & 0xfff, |
73 | fs_rights_base, fs_rights_inheriting, fs_flags, | |
74 | &newfd); | |
320054e8 | 75 | if (error != 0) { |
320054e8 DG |
76 | return -1; |
77 | } | |
78 | return newfd; | |
79 | } |