]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/missing_syscall.h
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 /* Missing glibc definitions to access certain kernel APIs */
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
11 #include <linux/time_types.h>
14 #include <sys/syscall.h>
15 #include <sys/types.h>
20 #include <asm/sgidefs.h>
24 #include "missing_keyctl.h"
25 #include "missing_stat.h"
26 #include "missing_syscall_def.h"
29 #ifndef KCMP_FILE /* 3f4994cfc15f38a3159c6e3a4b3ab2e1481a6b02 (3.19) */
33 /* ======================================================================= */
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
);
45 # define fchmodat2 missing_fchmodat2
48 /* ======================================================================= */
51 static inline int missing_pivot_root(const char *new_root
, const char *put_old
) {
52 return syscall(__NR_pivot_root
, new_root
, put_old
);
55 # define pivot_root missing_pivot_root
58 /* ======================================================================= */
61 static inline int missing_ioprio_get(int which
, int who
) {
62 return syscall(__NR_ioprio_get
, which
, who
);
65 # define ioprio_get missing_ioprio_get
68 /* ======================================================================= */
71 static inline int missing_ioprio_set(int which
, int who
, int ioprio
) {
72 return syscall(__NR_ioprio_set
, which
, who
, ioprio
);
75 # define ioprio_set missing_ioprio_set
78 /* ======================================================================= */
80 #if !HAVE_MEMFD_CREATE
81 static inline int missing_memfd_create(const char *name
, unsigned int flags
) {
82 # ifdef __NR_memfd_create
83 return syscall(__NR_memfd_create
, name
, flags
);
90 # define memfd_create missing_memfd_create
93 /* ======================================================================= */
96 /* glibc says getrandom() returns ssize_t */
97 static inline ssize_t
missing_getrandom(void *buffer
, size_t count
, unsigned flags
) {
98 # ifdef __NR_getrandom
99 return syscall(__NR_getrandom
, buffer
, count
, flags
);
106 # define getrandom missing_getrandom
109 /* ======================================================================= */
111 /* The syscall has been defined since forever, but the glibc wrapper was missing. */
113 static inline pid_t
missing_gettid(void) {
114 # if defined __NR_gettid && __NR_gettid >= 0
115 return (pid_t
) syscall(__NR_gettid
);
117 # error "__NR_gettid not defined"
121 # define gettid missing_gettid
124 /* ======================================================================= */
126 #if !HAVE_NAME_TO_HANDLE_AT
128 unsigned int handle_bytes
;
130 unsigned char f_handle
[0];
133 static inline int missing_name_to_handle_at(int fd
, const char *name
, struct file_handle
*handle
, int *mnt_id
, int flags
) {
134 # ifdef __NR_name_to_handle_at
135 return syscall(__NR_name_to_handle_at
, fd
, name
, handle
, mnt_id
, flags
);
142 # define name_to_handle_at missing_name_to_handle_at
145 /* ======================================================================= */
148 static inline int missing_setns(int fd
, int nstype
) {
150 return syscall(__NR_setns
, fd
, nstype
);
157 # define setns missing_setns
160 /* ======================================================================= */
162 static inline pid_t
raw_getpid(void) {
163 #if defined(__alpha__)
164 return (pid_t
) syscall(__NR_getxpid
);
166 return (pid_t
) syscall(__NR_getpid
);
170 /* ======================================================================= */
173 static inline int missing_renameat2(int oldfd
, const char *oldname
, int newfd
, const char *newname
, unsigned flags
) {
174 # ifdef __NR_renameat2
175 return syscall(__NR_renameat2
, oldfd
, oldname
, newfd
, newname
, flags
);
182 # define renameat2 missing_renameat2
185 /* ======================================================================= */
188 static inline int missing_kcmp(pid_t pid1
, pid_t pid2
, int type
, unsigned long idx1
, unsigned long idx2
) {
189 # if defined __NR_kcmp && __NR_kcmp >= 0
190 return syscall(__NR_kcmp
, pid1
, pid2
, type
, idx1
, idx2
);
197 # define kcmp missing_kcmp
200 /* ======================================================================= */
203 static inline long missing_keyctl(int cmd
, unsigned long arg2
, unsigned long arg3
, unsigned long arg4
, unsigned long arg5
) {
204 # if defined __NR_keyctl && __NR_keyctl >= 0
205 return syscall(__NR_keyctl
, cmd
, arg2
, arg3
, arg4
, arg5
);
211 # define keyctl missing_keyctl
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
) {
215 # if defined __NR_add_key && __NR_add_key >= 0
216 return syscall(__NR_add_key
, type
, description
, payload
, plen
, ringid
);
222 # define add_key missing_add_key
225 static inline key_serial_t
missing_request_key(const char *type
, const char *description
, const char * callout_info
, key_serial_t destringid
) {
226 # if defined __NR_request_key && __NR_request_key >= 0
227 return syscall(__NR_request_key
, type
, description
, callout_info
, destringid
);
233 # define request_key missing_request_key
237 /* ======================================================================= */
239 #if !HAVE_COPY_FILE_RANGE
240 static inline ssize_t
missing_copy_file_range(int fd_in
, loff_t
*off_in
,
241 int fd_out
, loff_t
*off_out
,
243 unsigned int flags
) {
244 # ifdef __NR_copy_file_range
245 return syscall(__NR_copy_file_range
, fd_in
, off_in
, fd_out
, off_out
, len
, flags
);
252 # define copy_file_range missing_copy_file_range
255 /* ======================================================================= */
260 static inline int missing_bpf(int cmd
, union bpf_attr
*attr
, size_t size
) {
262 return (int) syscall(__NR_bpf
, cmd
, attr
, size
);
269 # define bpf missing_bpf
272 /* ======================================================================= */
277 static inline ssize_t
missing_statx(int dfd
, const char *filename
, unsigned flags
, unsigned int mask
, struct statx
*buffer
) {
279 return syscall(__NR_statx
, dfd
, filename
, flags
, mask
, buffer
);
287 /* This typedef is supposed to be always defined. */
288 typedef struct statx struct_statx
;
291 # define statx(dfd, filename, flags, mask, buffer) missing_statx(dfd, filename, flags, mask, buffer)
294 /* ======================================================================= */
296 #if !HAVE_SET_MEMPOLICY
305 static inline long missing_set_mempolicy(int mode
, const unsigned long *nodemask
,
306 unsigned long maxnode
) {
308 # if defined __NR_set_mempolicy && __NR_set_mempolicy >= 0
309 i
= syscall(__NR_set_mempolicy
, mode
, nodemask
, maxnode
);
317 # define set_mempolicy missing_set_mempolicy
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
) {
325 # if defined __NR_get_mempolicy && __NR_get_mempolicy >= 0
326 i
= syscall(__NR_get_mempolicy
, mode
, nodemask
, maxnode
, addr
, flags
);
334 # define get_mempolicy missing_get_mempolicy
337 /* ======================================================================= */
339 #if !HAVE_PIDFD_SEND_SIGNAL
340 static inline int missing_pidfd_send_signal(int fd
, int sig
, siginfo_t
*info
, unsigned flags
) {
341 # ifdef __NR_pidfd_send_signal
342 return syscall(__NR_pidfd_send_signal
, fd
, sig
, info
, flags
);
349 # define pidfd_send_signal missing_pidfd_send_signal
353 static inline int missing_pidfd_open(pid_t pid
, unsigned flags
) {
354 # ifdef __NR_pidfd_open
355 return syscall(__NR_pidfd_open
, pid
, flags
);
362 # define pidfd_open missing_pidfd_open
365 /* ======================================================================= */
367 #if !HAVE_RT_SIGQUEUEINFO
368 static inline int missing_rt_sigqueueinfo(pid_t tgid
, int sig
, siginfo_t
*info
) {
369 # if defined __NR_rt_sigqueueinfo && __NR_rt_sigqueueinfo >= 0
370 return syscall(__NR_rt_sigqueueinfo
, tgid
, sig
, info
);
372 # error "__NR_rt_sigqueueinfo not defined"
376 # define rt_sigqueueinfo missing_rt_sigqueueinfo
379 /* ======================================================================= */
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
);
386 # error "__NR_rt_tgsigqueueinfo not defined"
390 # define rt_tgsigqueueinfo missing_rt_tgsigqueueinfo
393 /* ======================================================================= */
396 static inline int missing_execveat(int dirfd
, const char *pathname
,
397 char *const argv
[], char *const envp
[],
399 # if defined __NR_execveat && __NR_execveat >= 0
400 return syscall(__NR_execveat
, dirfd
, pathname
, argv
, envp
, flags
);
407 # undef AT_EMPTY_PATH
408 # define AT_EMPTY_PATH 0x1000
409 # define execveat missing_execveat
412 /* ======================================================================= */
414 #if !HAVE_CLOSE_RANGE
415 static inline int missing_close_range(unsigned first_fd
, unsigned end_fd
, unsigned flags
) {
416 # ifdef __NR_close_range
417 /* Kernel-side the syscall expects fds as unsigned integers (just like close() actually), while
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. */
420 return syscall(__NR_close_range
,
430 # define close_range missing_close_range
433 /* ======================================================================= */
435 #if !HAVE_MOUNT_SETATTR
437 #if !HAVE_STRUCT_MOUNT_ATTR
441 uint64_t propagation
;
448 #ifndef MOUNT_ATTR_RDONLY
449 #define MOUNT_ATTR_RDONLY 0x00000001 /* Mount read-only */
452 #ifndef MOUNT_ATTR_NOSUID
453 #define MOUNT_ATTR_NOSUID 0x00000002 /* Ignore suid and sgid bits */
456 #ifndef MOUNT_ATTR_NODEV
457 #define MOUNT_ATTR_NODEV 0x00000004 /* Disallow access to device special files */
460 #ifndef MOUNT_ATTR_NOEXEC
461 #define MOUNT_ATTR_NOEXEC 0x00000008 /* Disallow program execution */
464 #ifndef MOUNT_ATTR__ATIME
465 #define MOUNT_ATTR__ATIME 0x00000070 /* Setting on how atime should be updated */
468 #ifndef MOUNT_ATTR_RELATIME
469 #define MOUNT_ATTR_RELATIME 0x00000000 /* - Update atime relative to mtime/ctime. */
472 #ifndef MOUNT_ATTR_NOATIME
473 #define MOUNT_ATTR_NOATIME 0x00000010 /* - Do not update access times. */
476 #ifndef MOUNT_ATTR_STRICTATIME
477 #define MOUNT_ATTR_STRICTATIME 0x00000020 /* - Always perform atime updates */
480 #ifndef MOUNT_ATTR_NODIRATIME
481 #define MOUNT_ATTR_NODIRATIME 0x00000080 /* Do not update directory access times */
484 #ifndef MOUNT_ATTR_IDMAP
485 #define MOUNT_ATTR_IDMAP 0x00100000 /* Idmap mount to @userns_fd in struct mount_attr. */
488 #ifndef MOUNT_ATTR_NOSYMFOLLOW
489 #define MOUNT_ATTR_NOSYMFOLLOW 0x00200000 /* Do not follow symlinks */
492 #ifndef MOUNT_ATTR_SIZE_VER0
493 #define MOUNT_ATTR_SIZE_VER0 32 /* sizeof first published struct */
497 #define AT_RECURSIVE 0x8000
500 static inline int missing_mount_setattr(
504 struct mount_attr
*attr
,
507 # if defined __NR_mount_setattr && __NR_mount_setattr >= 0
508 return syscall(__NR_mount_setattr
, dfd
, path
, flags
, attr
, size
);
515 # define mount_setattr missing_mount_setattr
518 /* ======================================================================= */
522 #ifndef OPEN_TREE_CLONE
523 #define OPEN_TREE_CLONE 1
526 #ifndef OPEN_TREE_CLOEXEC
527 #define OPEN_TREE_CLOEXEC O_CLOEXEC
530 static inline int missing_open_tree(
532 const char *filename
,
535 # if defined __NR_open_tree && __NR_open_tree >= 0
536 return syscall(__NR_open_tree
, dfd
, filename
, flags
);
543 # define open_tree missing_open_tree
546 /* ======================================================================= */
548 #ifndef MOVE_MOUNT_BENEATH
549 #define MOVE_MOUNT_BENEATH 0x00000200
554 #ifndef MOVE_MOUNT_F_EMPTY_PATH
555 #define MOVE_MOUNT_F_EMPTY_PATH 0x00000004 /* Empty from path permitted */
558 #ifndef MOVE_MOUNT_T_EMPTY_PATH
559 #define MOVE_MOUNT_T_EMPTY_PATH 0x00000040 /* Empty to path permitted */
562 static inline int missing_move_mount(
564 const char *from_pathname
,
566 const char *to_pathname
,
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
);
577 # define move_mount missing_move_mount
580 /* ======================================================================= */
584 #ifndef FSOPEN_CLOEXEC
585 #define FSOPEN_CLOEXEC 0x00000001
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
);
597 # define fsopen missing_fsopen
600 /* ======================================================================= */
604 #ifndef FSCONFIG_SET_FLAG
605 #define FSCONFIG_SET_FLAG 0 /* Set parameter, supplying no value */
608 #ifndef FSCONFIG_SET_STRING
609 #define FSCONFIG_SET_STRING 1 /* Set parameter, supplying a string value */
612 #ifndef FSCONFIG_SET_FD
613 #define FSCONFIG_SET_FD 5 /* Set parameter, supplying an object by fd */
616 #ifndef FSCONFIG_CMD_CREATE
617 #define FSCONFIG_CMD_CREATE 6 /* Invoke superblock creation */
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
);
629 # define fsconfig missing_fsconfig
632 /* ======================================================================= */
636 #ifndef FSMOUNT_CLOEXEC
637 #define FSMOUNT_CLOEXEC 0x00000001
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
);
649 # define fsmount missing_fsmount
652 /* ======================================================================= */
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
);
665 # define getdents64 missing_getdents64
668 /* ======================================================================= */
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
);
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. */