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