]>
Commit | Line | Data |
---|---|---|
f2e779e5 DG |
1 | // Handle AT_FDCWD and absolute paths for the *at functions. |
2 | // | |
3 | // In the case of an AT_FDCWD file descriptor or an absolute path, call the | |
4 | // corresponding non-`at` function. This will send it through the libpreopen | |
5 | // wrappers to convert the path into a directory file descriptor and relative | |
6 | // path before translating it into the corresponding `__wasilibc_nocwd_*at` | |
7 | // function, which then calls the appropriate WASI function. | |
8 | ||
9 | #include <fcntl.h> | |
10 | #include <stdio.h> | |
11 | #include <unistd.h> | |
12 | #include <dirent.h> | |
13 | #include <sys/types.h> | |
14 | #include <sys/stat.h> | |
15 | #include <wasi/libc.h> | |
16 | #include <wasi/libc-nocwd.h> | |
17 | ||
18 | // If the platform doesn't define O_TMPFILE, we don't need to worry about it. | |
19 | #ifndef O_TMPFILE | |
20 | #define O_TMPFILE 0 | |
21 | #endif | |
22 | ||
23 | int openat(int dirfd, const char *pathname, int flags, ...) { | |
24 | if (dirfd == AT_FDCWD || pathname[0] == '/') { | |
25 | return open(pathname, flags); | |
26 | } | |
27 | ||
28 | return __wasilibc_nocwd_openat_nomode(dirfd, pathname, flags); | |
29 | } | |
30 | ||
31 | int symlinkat(const char *target, int dirfd, const char *linkpath) { | |
32 | if (dirfd == AT_FDCWD || linkpath[0] == '/') { | |
33 | return symlink(target, linkpath); | |
34 | } | |
35 | ||
36 | return __wasilibc_nocwd_symlinkat(target, dirfd, linkpath); | |
37 | } | |
38 | ||
39 | ssize_t readlinkat(int dirfd, const char *__restrict pathname, char *__restrict buf, size_t bufsiz) { | |
40 | if (dirfd == AT_FDCWD || pathname[0] == '/') { | |
41 | return readlink(pathname, buf, bufsiz); | |
42 | } | |
43 | ||
44 | return __wasilibc_nocwd_readlinkat(dirfd, pathname, buf, bufsiz); | |
45 | } | |
46 | ||
47 | int mkdirat(int dirfd, const char *pathname, mode_t mode) { | |
48 | if (dirfd == AT_FDCWD || pathname[0] == '/') { | |
49 | return mkdir(pathname, mode); | |
50 | } | |
51 | ||
52 | return __wasilibc_nocwd_mkdirat_nomode(dirfd, pathname); | |
53 | } | |
54 | ||
55 | DIR *opendirat(int dirfd, const char *path) { | |
56 | if (dirfd == AT_FDCWD || path[0] == '/') { | |
57 | return opendir(path); | |
58 | } | |
59 | ||
60 | return __wasilibc_nocwd_opendirat(dirfd, path); | |
61 | } | |
62 | ||
63 | int scandirat(int dirfd, const char *dirp, struct dirent ***namelist, | |
64 | int (*filter)(const struct dirent *), | |
65 | int (*compar)(const struct dirent **, const struct dirent **)) { | |
66 | if (dirfd == AT_FDCWD || dirp[0] == '/') { | |
67 | return scandir(dirp, namelist, filter, compar); | |
68 | } | |
69 | ||
70 | return __wasilibc_nocwd_scandirat(dirfd, dirp, namelist, filter, compar); | |
71 | } | |
72 | ||
73 | int faccessat(int dirfd, const char *pathname, int mode, int flags) { | |
74 | if (dirfd == AT_FDCWD || pathname[0] == '/') { | |
75 | return __wasilibc_access(pathname, mode, flags); | |
76 | } | |
77 | ||
78 | return __wasilibc_nocwd_faccessat(dirfd, pathname, mode, flags); | |
79 | } | |
80 | ||
81 | int fstatat(int dirfd, const char *__restrict pathname, struct stat *__restrict statbuf, int flags) { | |
82 | if (dirfd == AT_FDCWD || pathname[0] == '/') { | |
83 | return __wasilibc_stat(pathname, statbuf, flags); | |
84 | } | |
85 | ||
86 | return __wasilibc_nocwd_fstatat(dirfd, pathname, statbuf, flags); | |
87 | } | |
88 | ||
89 | int utimensat(int dirfd, const char *pathname, const struct timespec times[2], int flags) { | |
90 | if (dirfd == AT_FDCWD || pathname[0] == '/') { | |
91 | return __wasilibc_utimens(pathname, times, flags); | |
92 | } | |
93 | ||
94 | return __wasilibc_nocwd_utimensat(dirfd, pathname, times, flags); | |
95 | } | |
96 | ||
97 | int linkat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath, int flags) { | |
98 | if ((olddirfd == AT_FDCWD || oldpath[0] == '/') && | |
99 | (newdirfd == AT_FDCWD || newpath[0] == '/')) { | |
100 | return __wasilibc_link(oldpath, newpath, flags); | |
101 | } | |
102 | if (olddirfd == AT_FDCWD || oldpath[0] == '/') { | |
103 | return __wasilibc_link_newat(oldpath, newdirfd, newpath, flags); | |
104 | } | |
105 | if (newdirfd == AT_FDCWD || newpath[0] == '/') { | |
106 | return __wasilibc_link_oldat(olddirfd, oldpath, newpath, flags); | |
107 | } | |
108 | ||
109 | return __wasilibc_nocwd_linkat(olddirfd, oldpath, newdirfd, newpath, flags); | |
110 | } | |
111 | ||
112 | int renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) { | |
113 | if ((olddirfd == AT_FDCWD || oldpath[0] == '/') && | |
114 | (newdirfd == AT_FDCWD || newpath[0] == '/')) { | |
115 | return rename(oldpath, newpath); | |
116 | } | |
117 | if (olddirfd == AT_FDCWD || oldpath[0] == '/') { | |
118 | return __wasilibc_rename_newat(oldpath, newdirfd, newpath); | |
119 | } | |
120 | if (newdirfd == AT_FDCWD || newpath[0] == '/') { | |
121 | return __wasilibc_rename_oldat(olddirfd, oldpath, newpath); | |
122 | } | |
123 | ||
124 | return __wasilibc_nocwd_renameat(olddirfd, oldpath, newdirfd, newpath); | |
125 | } | |
126 | ||
127 | int __wasilibc_unlinkat(int dirfd, const char *path) { | |
128 | if (dirfd == AT_FDCWD || path[0] == '/') { | |
129 | return unlink(path); | |
130 | } | |
131 | ||
132 | return __wasilibc_nocwd___wasilibc_unlinkat(dirfd, path); | |
133 | } | |
134 | ||
135 | int __wasilibc_rmdirat(int dirfd, const char *path) { | |
136 | if (dirfd == AT_FDCWD || path[0] == '/') { | |
137 | return rmdir(path); | |
138 | } | |
139 | ||
140 | return __wasilibc_nocwd___wasilibc_rmdirat(dirfd, path); | |
141 | } |