]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
2f368e4a ZJS |
2 | #pragma once |
3 | ||
2f368e4a ZJS |
4 | /* Missing glibc definitions to access certain kernel APIs */ |
5 | ||
e2d94d0c | 6 | #include <errno.h> |
36dd5ffd | 7 | #include <fcntl.h> |
420297c9 LP |
8 | #if HAVE_LINUX_TIME_TYPES_H |
9 | /* This header defines __kernel_timespec for us, but is only available since Linux 5.1, hence conditionally | |
10 | * include this. */ | |
11 | #include <linux/time_types.h> | |
12 | #endif | |
5f152f43 | 13 | #include <signal.h> |
36dd5ffd | 14 | #include <sys/syscall.h> |
71e5200f | 15 | #include <sys/types.h> |
5f152f43 | 16 | #include <sys/wait.h> |
851d66fa YW |
17 | #include <unistd.h> |
18 | ||
19 | #ifdef ARCH_MIPS | |
20 | #include <asm/sgidefs.h> | |
21 | #endif | |
71e5200f | 22 | |
4768cc45 | 23 | #include "macro.h" |
d7276b61 | 24 | #include "missing_keyctl.h" |
e01819f8 | 25 | #include "missing_stat.h" |
35b42e56 | 26 | #include "missing_syscall_def.h" |
d7276b61 | 27 | |
851d66fa YW |
28 | /* linux/kcmp.h */ |
29 | #ifndef KCMP_FILE /* 3f4994cfc15f38a3159c6e3a4b3ab2e1481a6b02 (3.19) */ | |
30 | #define KCMP_FILE 0 | |
31 | #endif | |
32 | ||
35b42e56 ZJS |
33 | /* ======================================================================= */ |
34 | ||
c21566d9 AM |
35 | #if !HAVE_FCHMODAT2 |
36 | static inline int missing_fchmodat2(int dirfd, const char *path, mode_t mode, int flags) { | |
37 | # ifdef __NR_fchmodat2 | |
38 | return syscall(__NR_fchmodat2, dirfd, path, mode, flags); | |
39 | # else | |
40 | errno = ENOSYS; | |
41 | return -1; | |
42 | # endif | |
43 | } | |
44 | ||
45 | # define fchmodat2 missing_fchmodat2 | |
46 | #endif | |
47 | ||
48 | /* ======================================================================= */ | |
49 | ||
4b9545f1 | 50 | #if !HAVE_PIVOT_ROOT |
5187dd2c | 51 | static inline int missing_pivot_root(const char *new_root, const char *put_old) { |
d06f3829 | 52 | return syscall(__NR_pivot_root, new_root, put_old); |
2f368e4a | 53 | } |
5187dd2c ZJS |
54 | |
55 | # define pivot_root missing_pivot_root | |
2f368e4a ZJS |
56 | #endif |
57 | ||
58 | /* ======================================================================= */ | |
59 | ||
51fe206f ZJS |
60 | #if !HAVE_IOPRIO_GET |
61 | static inline int missing_ioprio_get(int which, int who) { | |
62 | return syscall(__NR_ioprio_get, which, who); | |
63 | } | |
64 | ||
65 | # define ioprio_get missing_ioprio_get | |
66 | #endif | |
67 | ||
68 | /* ======================================================================= */ | |
69 | ||
70 | #if !HAVE_IOPRIO_SET | |
71 | static inline int missing_ioprio_set(int which, int who, int ioprio) { | |
72 | return syscall(__NR_ioprio_set, which, who, ioprio); | |
73 | } | |
74 | ||
75 | # define ioprio_set missing_ioprio_set | |
76 | #endif | |
77 | ||
78 | /* ======================================================================= */ | |
79 | ||
5134e18e | 80 | #if !HAVE_MEMFD_CREATE |
5187dd2c | 81 | static inline int missing_memfd_create(const char *name, unsigned int flags) { |
2f368e4a ZJS |
82 | # ifdef __NR_memfd_create |
83 | return syscall(__NR_memfd_create, name, flags); | |
84 | # else | |
85 | errno = ENOSYS; | |
86 | return -1; | |
87 | # endif | |
88 | } | |
5187dd2c ZJS |
89 | |
90 | # define memfd_create missing_memfd_create | |
2f368e4a ZJS |
91 | #endif |
92 | ||
93 | /* ======================================================================= */ | |
94 | ||
5134e18e | 95 | #if !HAVE_GETRANDOM |
289b41aa MG |
96 | /* glibc says getrandom() returns ssize_t */ |
97 | static inline ssize_t missing_getrandom(void *buffer, size_t count, unsigned flags) { | |
2f368e4a ZJS |
98 | # ifdef __NR_getrandom |
99 | return syscall(__NR_getrandom, buffer, count, flags); | |
100 | # else | |
101 | errno = ENOSYS; | |
102 | return -1; | |
103 | # endif | |
104 | } | |
5187dd2c ZJS |
105 | |
106 | # define getrandom missing_getrandom | |
2f368e4a ZJS |
107 | #endif |
108 | ||
109 | /* ======================================================================= */ | |
110 | ||
5134e18e | 111 | /* The syscall has been defined since forever, but the glibc wrapper was missing. */ |
4b9545f1 | 112 | #if !HAVE_GETTID |
5187dd2c | 113 | static inline pid_t missing_gettid(void) { |
5134e18e | 114 | # if defined __NR_gettid && __NR_gettid >= 0 |
d06f3829 | 115 | return (pid_t) syscall(__NR_gettid); |
5134e18e ZJS |
116 | # else |
117 | # error "__NR_gettid not defined" | |
118 | # endif | |
2f368e4a | 119 | } |
5187dd2c ZJS |
120 | |
121 | # define gettid missing_gettid | |
2f368e4a ZJS |
122 | #endif |
123 | ||
124 | /* ======================================================================= */ | |
125 | ||
5134e18e | 126 | #if !HAVE_NAME_TO_HANDLE_AT |
2f368e4a ZJS |
127 | struct file_handle { |
128 | unsigned int handle_bytes; | |
129 | int handle_type; | |
130 | unsigned char f_handle[0]; | |
131 | }; | |
132 | ||
5187dd2c | 133 | static inline int missing_name_to_handle_at(int fd, const char *name, struct file_handle *handle, int *mnt_id, int flags) { |
2f368e4a ZJS |
134 | # ifdef __NR_name_to_handle_at |
135 | return syscall(__NR_name_to_handle_at, fd, name, handle, mnt_id, flags); | |
136 | # else | |
137 | errno = ENOSYS; | |
138 | return -1; | |
139 | # endif | |
140 | } | |
5187dd2c ZJS |
141 | |
142 | # define name_to_handle_at missing_name_to_handle_at | |
2f368e4a ZJS |
143 | #endif |
144 | ||
145 | /* ======================================================================= */ | |
146 | ||
5134e18e | 147 | #if !HAVE_SETNS |
5187dd2c | 148 | static inline int missing_setns(int fd, int nstype) { |
2f368e4a ZJS |
149 | # ifdef __NR_setns |
150 | return syscall(__NR_setns, fd, nstype); | |
151 | # else | |
152 | errno = ENOSYS; | |
153 | return -1; | |
154 | # endif | |
155 | } | |
5187dd2c ZJS |
156 | |
157 | # define setns missing_setns | |
2f368e4a ZJS |
158 | #endif |
159 | ||
160 | /* ======================================================================= */ | |
161 | ||
2f368e4a ZJS |
162 | static inline pid_t raw_getpid(void) { |
163 | #if defined(__alpha__) | |
164 | return (pid_t) syscall(__NR_getxpid); | |
165 | #else | |
166 | return (pid_t) syscall(__NR_getpid); | |
167 | #endif | |
168 | } | |
169 | ||
170 | /* ======================================================================= */ | |
171 | ||
5134e18e | 172 | #if !HAVE_RENAMEAT2 |
5187dd2c | 173 | static inline int missing_renameat2(int oldfd, const char *oldname, int newfd, const char *newname, unsigned flags) { |
2f368e4a ZJS |
174 | # ifdef __NR_renameat2 |
175 | return syscall(__NR_renameat2, oldfd, oldname, newfd, newname, flags); | |
176 | # else | |
177 | errno = ENOSYS; | |
178 | return -1; | |
179 | # endif | |
180 | } | |
5187dd2c ZJS |
181 | |
182 | # define renameat2 missing_renameat2 | |
2f368e4a ZJS |
183 | #endif |
184 | ||
185 | /* ======================================================================= */ | |
186 | ||
4b9545f1 | 187 | #if !HAVE_KCMP |
5187dd2c | 188 | static inline int missing_kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, unsigned long idx2) { |
fb4b0465 | 189 | # if defined __NR_kcmp && __NR_kcmp >= 0 |
2f368e4a ZJS |
190 | return syscall(__NR_kcmp, pid1, pid2, type, idx1, idx2); |
191 | # else | |
192 | errno = ENOSYS; | |
193 | return -1; | |
194 | # endif | |
195 | } | |
5187dd2c ZJS |
196 | |
197 | # define kcmp missing_kcmp | |
2f368e4a ZJS |
198 | #endif |
199 | ||
200 | /* ======================================================================= */ | |
201 | ||
4b9545f1 | 202 | #if !HAVE_KEYCTL |
851d66fa | 203 | static inline long missing_keyctl(int cmd, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) { |
fb4b0465 | 204 | # if defined __NR_keyctl && __NR_keyctl >= 0 |
2f368e4a ZJS |
205 | return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5); |
206 | # else | |
207 | errno = ENOSYS; | |
208 | return -1; | |
209 | # endif | |
5187dd2c ZJS |
210 | |
211 | # define keyctl missing_keyctl | |
2f368e4a ZJS |
212 | } |
213 | ||
5187dd2c | 214 | static inline key_serial_t missing_add_key(const char *type, const char *description, const void *payload, size_t plen, key_serial_t ringid) { |
fb4b0465 | 215 | # if defined __NR_add_key && __NR_add_key >= 0 |
2f368e4a ZJS |
216 | return syscall(__NR_add_key, type, description, payload, plen, ringid); |
217 | # else | |
218 | errno = ENOSYS; | |
219 | return -1; | |
220 | # endif | |
5187dd2c ZJS |
221 | |
222 | # define add_key missing_add_key | |
2f368e4a ZJS |
223 | } |
224 | ||
5187dd2c | 225 | static inline key_serial_t missing_request_key(const char *type, const char *description, const char * callout_info, key_serial_t destringid) { |
fb4b0465 | 226 | # if defined __NR_request_key && __NR_request_key >= 0 |
2f368e4a ZJS |
227 | return syscall(__NR_request_key, type, description, callout_info, destringid); |
228 | # else | |
229 | errno = ENOSYS; | |
230 | return -1; | |
231 | # endif | |
5187dd2c ZJS |
232 | |
233 | # define request_key missing_request_key | |
2f368e4a ZJS |
234 | } |
235 | #endif | |
236 | ||
237 | /* ======================================================================= */ | |
238 | ||
5134e18e | 239 | #if !HAVE_COPY_FILE_RANGE |
5187dd2c ZJS |
240 | static inline ssize_t missing_copy_file_range(int fd_in, loff_t *off_in, |
241 | int fd_out, loff_t *off_out, | |
242 | size_t len, | |
243 | unsigned int flags) { | |
2f368e4a ZJS |
244 | # ifdef __NR_copy_file_range |
245 | return syscall(__NR_copy_file_range, fd_in, off_in, fd_out, off_out, len, flags); | |
246 | # else | |
247 | errno = ENOSYS; | |
248 | return -1; | |
249 | # endif | |
250 | } | |
5187dd2c ZJS |
251 | |
252 | # define copy_file_range missing_copy_file_range | |
2f368e4a | 253 | #endif |
71e5200f | 254 | |
213f2883 ZJS |
255 | /* ======================================================================= */ |
256 | ||
5134e18e | 257 | #if !HAVE_BPF |
71e5200f DM |
258 | union bpf_attr; |
259 | ||
5187dd2c | 260 | static inline int missing_bpf(int cmd, union bpf_attr *attr, size_t size) { |
71e5200f DM |
261 | #ifdef __NR_bpf |
262 | return (int) syscall(__NR_bpf, cmd, attr, size); | |
263 | #else | |
264 | errno = ENOSYS; | |
265 | return -1; | |
266 | #endif | |
267 | } | |
268 | ||
5187dd2c | 269 | # define bpf missing_bpf |
71e5200f | 270 | #endif |
213f2883 ZJS |
271 | |
272 | /* ======================================================================= */ | |
273 | ||
5187dd2c | 274 | #if !HAVE_STATX |
5134e18e ZJS |
275 | struct statx; |
276 | ||
5187dd2c | 277 | static inline ssize_t missing_statx(int dfd, const char *filename, unsigned flags, unsigned int mask, struct statx *buffer) { |
4c2e1b39 LP |
278 | # ifdef __NR_statx |
279 | return syscall(__NR_statx, dfd, filename, flags, mask, buffer); | |
280 | # else | |
281 | errno = ENOSYS; | |
282 | return -1; | |
283 | # endif | |
284 | } | |
5134e18e ZJS |
285 | #endif |
286 | ||
287 | /* This typedef is supposed to be always defined. */ | |
288 | typedef struct statx struct_statx; | |
5187dd2c | 289 | |
5134e18e | 290 | #if !HAVE_STATX |
69b3fa14 | 291 | # define statx(dfd, filename, flags, mask, buffer) missing_statx(dfd, filename, flags, mask, buffer) |
4c2e1b39 | 292 | #endif |
b070c7c0 | 293 | |
5134e18e | 294 | /* ======================================================================= */ |
b070c7c0 | 295 | |
5134e18e | 296 | #if !HAVE_SET_MEMPOLICY |
b070c7c0 MS |
297 | enum { |
298 | MPOL_DEFAULT, | |
299 | MPOL_PREFERRED, | |
300 | MPOL_BIND, | |
301 | MPOL_INTERLEAVE, | |
302 | MPOL_LOCAL, | |
303 | }; | |
304 | ||
305 | static inline long missing_set_mempolicy(int mode, const unsigned long *nodemask, | |
306 | unsigned long maxnode) { | |
307 | long i; | |
fb4b0465 | 308 | # if defined __NR_set_mempolicy && __NR_set_mempolicy >= 0 |
b070c7c0 MS |
309 | i = syscall(__NR_set_mempolicy, mode, nodemask, maxnode); |
310 | # else | |
311 | errno = ENOSYS; | |
312 | i = -1; | |
313 | # endif | |
314 | return i; | |
315 | } | |
316 | ||
317 | # define set_mempolicy missing_set_mempolicy | |
318 | #endif | |
319 | ||
b070c7c0 MS |
320 | #if !HAVE_GET_MEMPOLICY |
321 | static inline long missing_get_mempolicy(int *mode, unsigned long *nodemask, | |
322 | unsigned long maxnode, void *addr, | |
323 | unsigned long flags) { | |
324 | long i; | |
0e682411 | 325 | # if defined __NR_get_mempolicy && __NR_get_mempolicy >= 0 |
b070c7c0 MS |
326 | i = syscall(__NR_get_mempolicy, mode, nodemask, maxnode, addr, flags); |
327 | # else | |
328 | errno = ENOSYS; | |
329 | i = -1; | |
330 | # endif | |
331 | return i; | |
332 | } | |
333 | ||
faeae444 | 334 | # define get_mempolicy missing_get_mempolicy |
b070c7c0 | 335 | #endif |
5f152f43 | 336 | |
5134e18e ZJS |
337 | /* ======================================================================= */ |
338 | ||
5134e18e | 339 | #if !HAVE_PIDFD_SEND_SIGNAL |
faeae444 | 340 | static inline int missing_pidfd_send_signal(int fd, int sig, siginfo_t *info, unsigned flags) { |
ba28df77 | 341 | # ifdef __NR_pidfd_send_signal |
5f152f43 | 342 | return syscall(__NR_pidfd_send_signal, fd, sig, info, flags); |
23654cee | 343 | # else |
5f152f43 LP |
344 | errno = ENOSYS; |
345 | return -1; | |
23654cee ZJS |
346 | # endif |
347 | } | |
faeae444 ZJS |
348 | |
349 | # define pidfd_send_signal missing_pidfd_send_signal | |
5f152f43 | 350 | #endif |
23654cee | 351 | |
5134e18e | 352 | #if !HAVE_PIDFD_OPEN |
faeae444 | 353 | static inline int missing_pidfd_open(pid_t pid, unsigned flags) { |
23654cee ZJS |
354 | # ifdef __NR_pidfd_open |
355 | return syscall(__NR_pidfd_open, pid, flags); | |
356 | # else | |
357 | errno = ENOSYS; | |
358 | return -1; | |
359 | # endif | |
5f152f43 | 360 | } |
faeae444 ZJS |
361 | |
362 | # define pidfd_open missing_pidfd_open | |
5f152f43 | 363 | #endif |
5ead4e85 | 364 | |
5134e18e ZJS |
365 | /* ======================================================================= */ |
366 | ||
5ead4e85 | 367 | #if !HAVE_RT_SIGQUEUEINFO |
faeae444 | 368 | static inline int missing_rt_sigqueueinfo(pid_t tgid, int sig, siginfo_t *info) { |
5134e18e | 369 | # if defined __NR_rt_sigqueueinfo && __NR_rt_sigqueueinfo >= 0 |
5ead4e85 | 370 | return syscall(__NR_rt_sigqueueinfo, tgid, sig, info); |
5134e18e ZJS |
371 | # else |
372 | # error "__NR_rt_sigqueueinfo not defined" | |
373 | # endif | |
5ead4e85 | 374 | } |
faeae444 ZJS |
375 | |
376 | # define rt_sigqueueinfo missing_rt_sigqueueinfo | |
5ead4e85 | 377 | #endif |
441e0fdb | 378 | |
8939eeae | 379 | /* ======================================================================= */ |
a5421953 DDM |
380 | |
381 | #if !HAVE_RT_TGSIGQUEUEINFO | |
382 | static inline int missing_rt_tgsigqueueinfo(pid_t tgid, pid_t tid, int sig, siginfo_t *info) { | |
383 | # if defined __NR_rt_tgsigqueueinfo && __NR_rt_tgsigqueueinfo >= 0 | |
384 | return syscall(__NR_rt_tgsigqueueinfo, tgid, tid, sig, info); | |
385 | # else | |
386 | # error "__NR_rt_tgsigqueueinfo not defined" | |
387 | # endif | |
388 | } | |
389 | ||
390 | # define rt_tgsigqueueinfo missing_rt_tgsigqueueinfo | |
391 | #endif | |
392 | ||
393 | /* ======================================================================= */ | |
b8bcd4c6 | 394 | |
8939eeae ZJS |
395 | #if !HAVE_EXECVEAT |
396 | static inline int missing_execveat(int dirfd, const char *pathname, | |
397 | char *const argv[], char *const envp[], | |
398 | int flags) { | |
399 | # if defined __NR_execveat && __NR_execveat >= 0 | |
400 | return syscall(__NR_execveat, dirfd, pathname, argv, envp, flags); | |
401 | # else | |
402 | errno = ENOSYS; | |
403 | return -1; | |
404 | # endif | |
405 | } | |
b8bcd4c6 | 406 | |
8939eeae ZJS |
407 | # undef AT_EMPTY_PATH |
408 | # define AT_EMPTY_PATH 0x1000 | |
409 | # define execveat missing_execveat | |
410 | #endif | |
411 | ||
441e0fdb LP |
412 | /* ======================================================================= */ |
413 | ||
441e0fdb | 414 | #if !HAVE_CLOSE_RANGE |
39d69836 | 415 | static inline int missing_close_range(unsigned first_fd, unsigned end_fd, unsigned flags) { |
441e0fdb LP |
416 | # ifdef __NR_close_range |
417 | /* Kernel-side the syscall expects fds as unsigned integers (just like close() actually), while | |
39d69836 LP |
418 | * userspace exclusively uses signed integers for fds. glibc chose to expose it 1:1 however, hence we |
419 | * do so here too, even if we end up passing signed fds to it most of the time. */ | |
441e0fdb | 420 | return syscall(__NR_close_range, |
39d69836 LP |
421 | first_fd, |
422 | end_fd, | |
441e0fdb LP |
423 | flags); |
424 | # else | |
425 | errno = ENOSYS; | |
426 | return -1; | |
427 | # endif | |
428 | } | |
429 | ||
430 | # define close_range missing_close_range | |
431 | #endif | |
420297c9 LP |
432 | |
433 | /* ======================================================================= */ | |
434 | ||
84e8edec LP |
435 | #if !HAVE_MOUNT_SETATTR |
436 | ||
437 | #if !HAVE_STRUCT_MOUNT_ATTR | |
438 | struct mount_attr { | |
439 | uint64_t attr_set; | |
440 | uint64_t attr_clr; | |
441 | uint64_t propagation; | |
442 | uint64_t userns_fd; | |
443 | }; | |
444 | #else | |
445 | struct mount_attr; | |
446 | #endif | |
447 | ||
0764e3a3 YW |
448 | #ifndef MOUNT_ATTR_RDONLY |
449 | #define MOUNT_ATTR_RDONLY 0x00000001 /* Mount read-only */ | |
450 | #endif | |
451 | ||
452 | #ifndef MOUNT_ATTR_NOSUID | |
453 | #define MOUNT_ATTR_NOSUID 0x00000002 /* Ignore suid and sgid bits */ | |
454 | #endif | |
455 | ||
456 | #ifndef MOUNT_ATTR_NODEV | |
457 | #define MOUNT_ATTR_NODEV 0x00000004 /* Disallow access to device special files */ | |
458 | #endif | |
459 | ||
460 | #ifndef MOUNT_ATTR_NOEXEC | |
461 | #define MOUNT_ATTR_NOEXEC 0x00000008 /* Disallow program execution */ | |
462 | #endif | |
463 | ||
464 | #ifndef MOUNT_ATTR__ATIME | |
465 | #define MOUNT_ATTR__ATIME 0x00000070 /* Setting on how atime should be updated */ | |
466 | #endif | |
467 | ||
468 | #ifndef MOUNT_ATTR_RELATIME | |
469 | #define MOUNT_ATTR_RELATIME 0x00000000 /* - Update atime relative to mtime/ctime. */ | |
470 | #endif | |
471 | ||
472 | #ifndef MOUNT_ATTR_NOATIME | |
473 | #define MOUNT_ATTR_NOATIME 0x00000010 /* - Do not update access times. */ | |
474 | #endif | |
475 | ||
476 | #ifndef MOUNT_ATTR_STRICTATIME | |
477 | #define MOUNT_ATTR_STRICTATIME 0x00000020 /* - Always perform atime updates */ | |
478 | #endif | |
479 | ||
480 | #ifndef MOUNT_ATTR_NODIRATIME | |
481 | #define MOUNT_ATTR_NODIRATIME 0x00000080 /* Do not update directory access times */ | |
482 | #endif | |
483 | ||
84e8edec | 484 | #ifndef MOUNT_ATTR_IDMAP |
0764e3a3 | 485 | #define MOUNT_ATTR_IDMAP 0x00100000 /* Idmap mount to @userns_fd in struct mount_attr. */ |
84e8edec LP |
486 | #endif |
487 | ||
4f5644db | 488 | #ifndef MOUNT_ATTR_NOSYMFOLLOW |
0764e3a3 | 489 | #define MOUNT_ATTR_NOSYMFOLLOW 0x00200000 /* Do not follow symlinks */ |
4f5644db LP |
490 | #endif |
491 | ||
0764e3a3 YW |
492 | #ifndef MOUNT_ATTR_SIZE_VER0 |
493 | #define MOUNT_ATTR_SIZE_VER0 32 /* sizeof first published struct */ | |
84e8edec LP |
494 | #endif |
495 | ||
0764e3a3 YW |
496 | #ifndef AT_RECURSIVE |
497 | #define AT_RECURSIVE 0x8000 | |
4f5644db LP |
498 | #endif |
499 | ||
84e8edec LP |
500 | static inline int missing_mount_setattr( |
501 | int dfd, | |
502 | const char *path, | |
503 | unsigned flags, | |
504 | struct mount_attr *attr, | |
505 | size_t size) { | |
506 | ||
507 | # if defined __NR_mount_setattr && __NR_mount_setattr >= 0 | |
508 | return syscall(__NR_mount_setattr, dfd, path, flags, attr, size); | |
509 | # else | |
510 | errno = ENOSYS; | |
511 | return -1; | |
512 | # endif | |
513 | } | |
514 | ||
515 | # define mount_setattr missing_mount_setattr | |
516 | #endif | |
517 | ||
518 | /* ======================================================================= */ | |
519 | ||
520 | #if !HAVE_OPEN_TREE | |
521 | ||
522 | #ifndef OPEN_TREE_CLONE | |
523 | #define OPEN_TREE_CLONE 1 | |
524 | #endif | |
525 | ||
526 | #ifndef OPEN_TREE_CLOEXEC | |
527 | #define OPEN_TREE_CLOEXEC O_CLOEXEC | |
528 | #endif | |
529 | ||
530 | static inline int missing_open_tree( | |
531 | int dfd, | |
532 | const char *filename, | |
533 | unsigned flags) { | |
534 | ||
535 | # if defined __NR_open_tree && __NR_open_tree >= 0 | |
536 | return syscall(__NR_open_tree, dfd, filename, flags); | |
537 | # else | |
538 | errno = ENOSYS; | |
539 | return -1; | |
540 | # endif | |
541 | } | |
542 | ||
543 | # define open_tree missing_open_tree | |
544 | #endif | |
545 | ||
546 | /* ======================================================================= */ | |
547 | ||
7c83d42e LB |
548 | #ifndef MOVE_MOUNT_BENEATH |
549 | #define MOVE_MOUNT_BENEATH 0x00000200 | |
550 | #endif | |
551 | ||
84e8edec LP |
552 | #if !HAVE_MOVE_MOUNT |
553 | ||
554 | #ifndef MOVE_MOUNT_F_EMPTY_PATH | |
555 | #define MOVE_MOUNT_F_EMPTY_PATH 0x00000004 /* Empty from path permitted */ | |
556 | #endif | |
557 | ||
608c3b02 RN |
558 | #ifndef MOVE_MOUNT_T_EMPTY_PATH |
559 | #define MOVE_MOUNT_T_EMPTY_PATH 0x00000040 /* Empty to path permitted */ | |
560 | #endif | |
561 | ||
84e8edec LP |
562 | static inline int missing_move_mount( |
563 | int from_dfd, | |
564 | const char *from_pathname, | |
565 | int to_dfd, | |
566 | const char *to_pathname, | |
567 | unsigned flags) { | |
568 | ||
569 | # if defined __NR_move_mount && __NR_move_mount >= 0 | |
570 | return syscall(__NR_move_mount, from_dfd, from_pathname, to_dfd, to_pathname, flags); | |
571 | # else | |
572 | errno = ENOSYS; | |
573 | return -1; | |
574 | # endif | |
575 | } | |
576 | ||
577 | # define move_mount missing_move_mount | |
578 | #endif | |
aab35b1e LP |
579 | |
580 | /* ======================================================================= */ | |
581 | ||
1c265fcd DDM |
582 | #if !HAVE_FSOPEN |
583 | ||
584 | #ifndef FSOPEN_CLOEXEC | |
585 | #define FSOPEN_CLOEXEC 0x00000001 | |
586 | #endif | |
587 | ||
588 | static inline int missing_fsopen(const char *fsname, unsigned flags) { | |
589 | # if defined __NR_fsopen && __NR_fsopen >= 0 | |
590 | return syscall(__NR_fsopen, fsname, flags); | |
591 | # else | |
592 | errno = ENOSYS; | |
593 | return -1; | |
594 | # endif | |
595 | } | |
596 | ||
597 | # define fsopen missing_fsopen | |
598 | #endif | |
599 | ||
600 | /* ======================================================================= */ | |
601 | ||
602 | #if !HAVE_FSCONFIG | |
603 | ||
c115e161 LP |
604 | #ifndef FSCONFIG_SET_FLAG |
605 | #define FSCONFIG_SET_FLAG 0 /* Set parameter, supplying no value */ | |
606 | #endif | |
607 | ||
1c265fcd DDM |
608 | #ifndef FSCONFIG_SET_STRING |
609 | #define FSCONFIG_SET_STRING 1 /* Set parameter, supplying a string value */ | |
610 | #endif | |
611 | ||
c115e161 LP |
612 | #ifndef FSCONFIG_SET_FD |
613 | #define FSCONFIG_SET_FD 5 /* Set parameter, supplying an object by fd */ | |
614 | #endif | |
615 | ||
616 | #ifndef FSCONFIG_CMD_CREATE | |
617 | #define FSCONFIG_CMD_CREATE 6 /* Invoke superblock creation */ | |
618 | #endif | |
619 | ||
1c265fcd DDM |
620 | static inline int missing_fsconfig(int fd, unsigned cmd, const char *key, const void *value, int aux) { |
621 | # if defined __NR_fsconfig && __NR_fsconfig >= 0 | |
622 | return syscall(__NR_fsconfig, fd, cmd, key, value, aux); | |
623 | # else | |
624 | errno = ENOSYS; | |
625 | return -1; | |
626 | # endif | |
627 | } | |
628 | ||
629 | # define fsconfig missing_fsconfig | |
630 | #endif | |
631 | ||
632 | /* ======================================================================= */ | |
633 | ||
34a9da0d LP |
634 | #if !HAVE_FSMOUNT |
635 | ||
636 | #ifndef FSMOUNT_CLOEXEC | |
637 | #define FSMOUNT_CLOEXEC 0x00000001 | |
638 | #endif | |
639 | ||
640 | static inline int missing_fsmount(int fd, unsigned flags, unsigned ms_flags) { | |
641 | # if defined __NR_fsmount && __NR_fsmount >= 0 | |
642 | return syscall(__NR_fsmount, fd, flags, ms_flags); | |
643 | # else | |
644 | errno = ENOSYS; | |
645 | return -1; | |
646 | # endif | |
647 | } | |
648 | ||
649 | # define fsmount missing_fsmount | |
650 | #endif | |
651 | ||
652 | /* ======================================================================= */ | |
653 | ||
aab35b1e LP |
654 | #if !HAVE_GETDENTS64 |
655 | ||
656 | static inline ssize_t missing_getdents64(int fd, void *buffer, size_t length) { | |
657 | # if defined __NR_getdents64 && __NR_getdents64 >= 0 | |
658 | return syscall(__NR_getdents64, fd, buffer, length); | |
659 | # else | |
660 | errno = ENOSYS; | |
661 | return -1; | |
662 | # endif | |
663 | } | |
664 | ||
665 | # define getdents64 missing_getdents64 | |
666 | #endif | |
840ac5cd LB |
667 | |
668 | /* ======================================================================= */ | |
669 | ||
670 | /* glibc does not provide clone() on ia64, only clone2(). Not only that, but it also doesn't provide a | |
671 | * prototype, only the symbol in the shared library (it provides a prototype for clone(), but not the | |
672 | * symbol in the shared library). */ | |
673 | #if defined(__ia64__) | |
674 | int __clone2(int (*fn)(void *), void *stack_base, size_t stack_size, int flags, void *arg); | |
675 | #define HAVE_CLONE 0 | |
676 | #else | |
677 | /* We know that everywhere else clone() is available, so we don't bother with a meson check (that takes time | |
678 | * at build time) and just define it. Once the kernel drops ia64 support, we can drop this too. */ | |
679 | #define HAVE_CLONE 1 | |
680 | #endif |