• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

systemd / systemd / 13230889329

09 Feb 2025 10:44PM UTC coverage: 71.84% (+0.06%) from 71.781%
13230889329

push

github

poettering
update TODO

293659 of 408770 relevant lines covered (71.84%)

715508.47 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.21
/src/basic/missing_syscall.h
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2
#pragma once
3

4
/* Missing glibc definitions to access certain kernel APIs */
5

6
#include <errno.h>
7
#include <fcntl.h>
8
#include <linux/time_types.h>
9
#include <signal.h>
10
#include <sys/syscall.h>
11
#include <sys/types.h>
12
#include <sys/wait.h>
13
#include <unistd.h>
14

15
#ifdef ARCH_MIPS
16
#include <asm/sgidefs.h>
17
#endif
18

19
#include "macro.h"
20
#include "missing_keyctl.h"
21
#include "missing_sched.h"
22
#include "missing_stat.h"
23
#include "missing_syscall_def.h"
24

25
/* ======================================================================= */
26

27
#if !HAVE_FCHMODAT2
28
static inline int missing_fchmodat2(int dirfd, const char *path, mode_t mode, int flags) {
24,783✔
29
#  ifdef __NR_fchmodat2
30
        return syscall(__NR_fchmodat2, dirfd, path, mode, flags);
24,783✔
31
#  else
32
        errno = ENOSYS;
33
        return -1;
34
#  endif
35
}
36

37
#  define fchmodat2 missing_fchmodat2
38
#endif
39

40
/* ======================================================================= */
41

42
#if !HAVE_PIVOT_ROOT
43
static inline int missing_pivot_root(const char *new_root, const char *put_old) {
2,859✔
44
        return syscall(__NR_pivot_root, new_root, put_old);
2,859✔
45
}
46

47
#  define pivot_root missing_pivot_root
48
#endif
49

50
/* ======================================================================= */
51

52
#if !HAVE_IOPRIO_GET
53
static inline int missing_ioprio_get(int which, int who) {
2,194✔
54
        return syscall(__NR_ioprio_get, which, who);
2,194✔
55
}
56

57
#  define ioprio_get missing_ioprio_get
58
#endif
59

60
/* ======================================================================= */
61

62
#if !HAVE_IOPRIO_SET
63
static inline int missing_ioprio_set(int which, int who, int ioprio) {
6✔
64
        return syscall(__NR_ioprio_set, which, who, ioprio);
6✔
65
}
66

67
#  define ioprio_set missing_ioprio_set
68
#endif
69

70
/* ======================================================================= */
71

72
#if !HAVE_MEMFD_CREATE
73
static inline int missing_memfd_create(const char *name, unsigned int flags) {
74
        return syscall(__NR_memfd_create, name, flags);
75
}
76

77
#  define memfd_create missing_memfd_create
78
#endif
79

80
/* ======================================================================= */
81

82
#if !HAVE_GETRANDOM
83
/* glibc says getrandom() returns ssize_t */
84
static inline ssize_t missing_getrandom(void *buffer, size_t count, unsigned flags) {
85
        return syscall(__NR_getrandom, buffer, count, flags);
86
}
87

88
#  define getrandom missing_getrandom
89
#endif
90

91
/* ======================================================================= */
92

93
/* The syscall has been defined since forever, but the glibc wrapper was missing. */
94
#if !HAVE_GETTID
95
static inline pid_t missing_gettid(void) {
96
#  if defined __NR_gettid && __NR_gettid >= 0
97
        return (pid_t) syscall(__NR_gettid);
98
#  else
99
#    error "__NR_gettid not defined"
100
#  endif
101
}
102

103
#  define gettid missing_gettid
104
#endif
105

106
/* ======================================================================= */
107

108
#if !HAVE_NAME_TO_HANDLE_AT
109
struct file_handle {
110
        unsigned int handle_bytes;
111
        int handle_type;
112
        unsigned char f_handle[0];
113
};
114

115
static inline int missing_name_to_handle_at(int fd, const char *name, struct file_handle *handle, int *mnt_id, int flags) {
116
#  ifdef __NR_name_to_handle_at
117
        return syscall(__NR_name_to_handle_at, fd, name, handle, mnt_id, flags);
118
#  else
119
        errno = ENOSYS;
120
        return -1;
121
#  endif
122
}
123

124
#  define name_to_handle_at missing_name_to_handle_at
125
#endif
126

127
/* ======================================================================= */
128

129
#if !HAVE_SETNS
130
static inline int missing_setns(int fd, int nstype) {
131
        return syscall(__NR_setns, fd, nstype);
132
}
133

134
#  define setns missing_setns
135
#endif
136

137
/* ======================================================================= */
138

139
static inline pid_t raw_getpid(void) {
132,703✔
140
#if defined(__alpha__)
141
        return (pid_t) syscall(__NR_getxpid);
142
#else
143
        return (pid_t) syscall(__NR_getpid);
132,703✔
144
#endif
145
}
146

147
/* ======================================================================= */
148

149
#if !HAVE_RENAMEAT2
150
static inline int missing_renameat2(int oldfd, const char *oldname, int newfd, const char *newname, unsigned flags) {
151
        return syscall(__NR_renameat2, oldfd, oldname, newfd, newname, flags);
152
}
153

154
#  define renameat2 missing_renameat2
155
#endif
156

157
/* ======================================================================= */
158

159
#if !HAVE_KCMP
160
static inline int missing_kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, unsigned long idx2) {
7,333✔
161
        return syscall(__NR_kcmp, pid1, pid2, type, idx1, idx2);
7,333✔
162
}
163

164
#  define kcmp missing_kcmp
165
#endif
166

167
/* ======================================================================= */
168

169
#if !HAVE_KEYCTL
170
static inline long missing_keyctl(int cmd, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) {
17,926✔
171
        return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5);
17,926✔
172

173
#  define keyctl missing_keyctl
174
}
175

176
static inline key_serial_t missing_add_key(const char *type, const char *description, const void *payload, size_t plen, key_serial_t ringid) {
6,511✔
177
        return syscall(__NR_add_key, type, description, payload, plen, ringid);
6,511✔
178

179
#  define add_key missing_add_key
180
}
181

182
static inline key_serial_t missing_request_key(const char *type, const char *description, const char * callout_info, key_serial_t destringid) {
12✔
183
        return syscall(__NR_request_key, type, description, callout_info, destringid);
12✔
184

185
#  define request_key missing_request_key
186
}
187
#endif
188

189
/* ======================================================================= */
190

191
#if !HAVE_COPY_FILE_RANGE
192
static inline ssize_t missing_copy_file_range(int fd_in, loff_t *off_in,
193
                                              int fd_out, loff_t *off_out,
194
                                              size_t len,
195
                                              unsigned int flags) {
196
#  ifdef __NR_copy_file_range
197
        return syscall(__NR_copy_file_range, fd_in, off_in, fd_out, off_out, len, flags);
198
#  else
199
        errno = ENOSYS;
200
        return -1;
201
#  endif
202
}
203

204
#  define copy_file_range missing_copy_file_range
205
#endif
206

207
/* ======================================================================= */
208

209
#if !HAVE_BPF
210
union bpf_attr;
211

212
static inline int missing_bpf(int cmd, union bpf_attr *attr, size_t size) {
2,909✔
213
#ifdef __NR_bpf
214
        return (int) syscall(__NR_bpf, cmd, attr, size);
2,909✔
215
#else
216
        errno = ENOSYS;
217
        return -1;
218
#endif
219
}
220

221
#  define bpf missing_bpf
222
#endif
223

224
/* ======================================================================= */
225

226
#if !HAVE_STATX
227
struct statx;
228

229
static inline ssize_t missing_statx(int dfd, const char *filename, unsigned flags, unsigned int mask, struct statx *buffer) {
230
#  ifdef __NR_statx
231
        return syscall(__NR_statx, dfd, filename, flags, mask, buffer);
232
#  else
233
        errno = ENOSYS;
234
        return -1;
235
#  endif
236
}
237
#endif
238

239
/* This typedef is supposed to be always defined. */
240
typedef struct statx struct_statx;
241

242
#if !HAVE_STATX
243
#  define statx(dfd, filename, flags, mask, buffer) missing_statx(dfd, filename, flags, mask, buffer)
244
#endif
245

246
/* ======================================================================= */
247

248
#if !HAVE_SET_MEMPOLICY
249
enum {
250
        MPOL_DEFAULT,
251
        MPOL_PREFERRED,
252
        MPOL_BIND,
253
        MPOL_INTERLEAVE,
254
        MPOL_LOCAL,
255
};
256

257
static inline long missing_set_mempolicy(int mode, const unsigned long *nodemask,
17✔
258
                           unsigned long maxnode) {
259
        long i;
17✔
260
#  if defined __NR_set_mempolicy && __NR_set_mempolicy >= 0
261
        i = syscall(__NR_set_mempolicy, mode, nodemask, maxnode);
17✔
262
#  else
263
        errno = ENOSYS;
264
        i = -1;
265
#  endif
266
        return i;
17✔
267
}
268

269
#  define set_mempolicy missing_set_mempolicy
270
#endif
271

272
#if !HAVE_GET_MEMPOLICY
273
static inline long missing_get_mempolicy(int *mode, unsigned long *nodemask,
19✔
274
                           unsigned long maxnode, void *addr,
275
                           unsigned long flags) {
276
        long i;
19✔
277
#  if defined __NR_get_mempolicy && __NR_get_mempolicy >= 0
278
        i = syscall(__NR_get_mempolicy, mode, nodemask, maxnode, addr, flags);
19✔
279
#  else
280
        errno = ENOSYS;
281
        i = -1;
282
#  endif
283
        return i;
19✔
284
}
285

286
#  define get_mempolicy missing_get_mempolicy
287
#endif
288

289
/* ======================================================================= */
290

291
#if !HAVE_PIDFD_SEND_SIGNAL
292
static inline int missing_pidfd_send_signal(int fd, int sig, siginfo_t *info, unsigned flags) {
293
        return syscall(__NR_pidfd_send_signal, fd, sig, info, flags);
294
}
295

296
#  define pidfd_send_signal missing_pidfd_send_signal
297
#endif
298

299
#if !HAVE_PIDFD_OPEN
300
static inline int missing_pidfd_open(pid_t pid, unsigned flags) {
301
        return syscall(__NR_pidfd_open, pid, flags);
302
}
303

304
#  define pidfd_open missing_pidfd_open
305
#endif
306

307
/* ======================================================================= */
308

309
#if !HAVE_RT_SIGQUEUEINFO
310
static inline int missing_rt_sigqueueinfo(pid_t tgid, int sig, siginfo_t *info) {
×
311
#  if defined __NR_rt_sigqueueinfo && __NR_rt_sigqueueinfo >= 0
312
        return syscall(__NR_rt_sigqueueinfo, tgid, sig, info);
×
313
#  else
314
#    error "__NR_rt_sigqueueinfo not defined"
315
#  endif
316
}
317

318
#  define rt_sigqueueinfo missing_rt_sigqueueinfo
319
#endif
320

321
/* ======================================================================= */
322

323
#if !HAVE_RT_TGSIGQUEUEINFO
324
static inline int missing_rt_tgsigqueueinfo(pid_t tgid, pid_t tid, int sig, siginfo_t *info) {
×
325
#  if defined __NR_rt_tgsigqueueinfo && __NR_rt_tgsigqueueinfo >= 0
326
        return syscall(__NR_rt_tgsigqueueinfo, tgid, tid, sig, info);
×
327
#  else
328
#    error "__NR_rt_tgsigqueueinfo not defined"
329
#  endif
330
}
331

332
#  define rt_tgsigqueueinfo missing_rt_tgsigqueueinfo
333
#endif
334

335
/* ======================================================================= */
336

337
#if !HAVE_EXECVEAT
338
static inline int missing_execveat(int dirfd, const char *pathname,
339
                                   char *const argv[], char *const envp[],
340
                                   int flags) {
341
#  if defined __NR_execveat && __NR_execveat >= 0
342
        return syscall(__NR_execveat, dirfd, pathname, argv, envp, flags);
343
#  else
344
        errno = ENOSYS;
345
        return -1;
346
#  endif
347
}
348

349
#  undef AT_EMPTY_PATH
350
#  define AT_EMPTY_PATH 0x1000
351
#  define execveat missing_execveat
352
#endif
353

354
/* ======================================================================= */
355

356
#if !HAVE_CLOSE_RANGE
357
static inline int missing_close_range(unsigned first_fd, unsigned end_fd, unsigned flags) {
358
#  ifdef __NR_close_range
359
        /* Kernel-side the syscall expects fds as unsigned integers (just like close() actually), while
360
         * userspace exclusively uses signed integers for fds. glibc chose to expose it 1:1 however, hence we
361
         * do so here too, even if we end up passing signed fds to it most of the time. */
362
        return syscall(__NR_close_range,
363
                       first_fd,
364
                       end_fd,
365
                       flags);
366
#  else
367
        errno = ENOSYS;
368
        return -1;
369
#  endif
370
}
371

372
#  define close_range missing_close_range
373
#endif
374

375
/* ======================================================================= */
376

377
#if !HAVE_MOUNT_SETATTR
378

379
#if !HAVE_STRUCT_MOUNT_ATTR
380
struct mount_attr {
381
        uint64_t attr_set;
382
        uint64_t attr_clr;
383
        uint64_t propagation;
384
        uint64_t userns_fd;
385
};
386
#else
387
struct mount_attr;
388
#endif
389

390
#ifndef MOUNT_ATTR_RDONLY
391
#define MOUNT_ATTR_RDONLY       0x00000001 /* Mount read-only */
392
#endif
393

394
#ifndef MOUNT_ATTR_NOSUID
395
#define MOUNT_ATTR_NOSUID       0x00000002 /* Ignore suid and sgid bits */
396
#endif
397

398
#ifndef MOUNT_ATTR_NODEV
399
#define MOUNT_ATTR_NODEV        0x00000004 /* Disallow access to device special files */
400
#endif
401

402
#ifndef MOUNT_ATTR_NOEXEC
403
#define MOUNT_ATTR_NOEXEC       0x00000008 /* Disallow program execution */
404
#endif
405

406
#ifndef MOUNT_ATTR__ATIME
407
#define MOUNT_ATTR__ATIME       0x00000070 /* Setting on how atime should be updated */
408
#endif
409

410
#ifndef MOUNT_ATTR_RELATIME
411
#define MOUNT_ATTR_RELATIME     0x00000000 /* - Update atime relative to mtime/ctime. */
412
#endif
413

414
#ifndef MOUNT_ATTR_NOATIME
415
#define MOUNT_ATTR_NOATIME      0x00000010 /* - Do not update access times. */
416
#endif
417

418
#ifndef MOUNT_ATTR_STRICTATIME
419
#define MOUNT_ATTR_STRICTATIME  0x00000020 /* - Always perform atime updates */
420
#endif
421

422
#ifndef MOUNT_ATTR_NODIRATIME
423
#define MOUNT_ATTR_NODIRATIME   0x00000080 /* Do not update directory access times */
424
#endif
425

426
#ifndef MOUNT_ATTR_IDMAP
427
#define MOUNT_ATTR_IDMAP        0x00100000 /* Idmap mount to @userns_fd in struct mount_attr. */
428
#endif
429

430
#ifndef MOUNT_ATTR_NOSYMFOLLOW
431
#define MOUNT_ATTR_NOSYMFOLLOW  0x00200000 /* Do not follow symlinks */
432
#endif
433

434
#ifndef MOUNT_ATTR_SIZE_VER0
435
#define MOUNT_ATTR_SIZE_VER0    32 /* sizeof first published struct */
436
#endif
437

438
#ifndef AT_RECURSIVE
439
#define AT_RECURSIVE 0x8000
440
#endif
441

442
static inline int missing_mount_setattr(
443
                int dfd,
444
                const char *path,
445
                unsigned flags,
446
                struct mount_attr *attr,
447
                size_t size) {
448

449
#  if defined __NR_mount_setattr && __NR_mount_setattr >= 0
450
        return syscall(__NR_mount_setattr, dfd, path, flags, attr, size);
451
#  else
452
        errno = ENOSYS;
453
        return -1;
454
#  endif
455
}
456

457
#  define mount_setattr missing_mount_setattr
458
#endif
459

460
/* ======================================================================= */
461

462
#if !HAVE_OPEN_TREE
463

464
#ifndef OPEN_TREE_CLONE
465
#define OPEN_TREE_CLONE 1
466
#endif
467

468
#ifndef OPEN_TREE_CLOEXEC
469
#define OPEN_TREE_CLOEXEC O_CLOEXEC
470
#endif
471

472
static inline int missing_open_tree(
473
                int dfd,
474
                const char *filename,
475
                unsigned flags) {
476

477
#  if defined __NR_open_tree && __NR_open_tree >= 0
478
        return syscall(__NR_open_tree, dfd, filename, flags);
479
#  else
480
        errno = ENOSYS;
481
        return -1;
482
#  endif
483
}
484

485
#  define open_tree missing_open_tree
486
#endif
487

488
/* ======================================================================= */
489

490
#ifndef MOVE_MOUNT_BENEATH
491
#define MOVE_MOUNT_BENEATH 0x00000200
492
#endif
493

494
#if !HAVE_MOVE_MOUNT
495

496
#ifndef MOVE_MOUNT_F_EMPTY_PATH
497
#define MOVE_MOUNT_F_EMPTY_PATH 0x00000004 /* Empty from path permitted */
498
#endif
499

500
#ifndef MOVE_MOUNT_T_EMPTY_PATH
501
#define MOVE_MOUNT_T_EMPTY_PATH 0x00000040 /* Empty to path permitted */
502
#endif
503

504
static inline int missing_move_mount(
505
                int from_dfd,
506
                const char *from_pathname,
507
                int to_dfd,
508
                const char *to_pathname,
509
                unsigned flags) {
510

511
#  if defined __NR_move_mount && __NR_move_mount >= 0
512
        return syscall(__NR_move_mount, from_dfd, from_pathname, to_dfd, to_pathname, flags);
513
#  else
514
        errno = ENOSYS;
515
        return -1;
516
#  endif
517
}
518

519
#  define move_mount missing_move_mount
520
#endif
521

522
/* ======================================================================= */
523

524
#if !HAVE_FSOPEN
525

526
#ifndef FSOPEN_CLOEXEC
527
#define FSOPEN_CLOEXEC 0x00000001
528
#endif
529

530
static inline int missing_fsopen(const char *fsname, unsigned flags) {
531
#  if defined __NR_fsopen && __NR_fsopen >= 0
532
        return syscall(__NR_fsopen, fsname, flags);
533
#  else
534
        errno = ENOSYS;
535
        return -1;
536
#  endif
537
}
538

539
#  define fsopen missing_fsopen
540
#endif
541

542
/* ======================================================================= */
543

544
#if !HAVE_FSCONFIG
545

546
#ifndef FSCONFIG_SET_FLAG
547
#define FSCONFIG_SET_FLAG 0 /* Set parameter, supplying no value */
548
#endif
549

550
#ifndef FSCONFIG_SET_STRING
551
#define FSCONFIG_SET_STRING 1 /* Set parameter, supplying a string value */
552
#endif
553

554
#ifndef FSCONFIG_SET_FD
555
#define FSCONFIG_SET_FD 5 /* Set parameter, supplying an object by fd */
556
#endif
557

558
#ifndef FSCONFIG_CMD_CREATE
559
#define FSCONFIG_CMD_CREATE 6 /* Invoke superblock creation */
560
#endif
561

562
static inline int missing_fsconfig(int fd, unsigned cmd, const char *key, const void *value, int aux) {
563
#  if defined __NR_fsconfig && __NR_fsconfig >= 0
564
        return syscall(__NR_fsconfig, fd, cmd, key, value, aux);
565
#  else
566
        errno = ENOSYS;
567
        return -1;
568
#  endif
569
}
570

571
#  define fsconfig missing_fsconfig
572
#endif
573

574
/* ======================================================================= */
575

576
#if !HAVE_FSMOUNT
577

578
#ifndef FSMOUNT_CLOEXEC
579
#define FSMOUNT_CLOEXEC 0x00000001
580
#endif
581

582
static inline int missing_fsmount(int fd, unsigned flags, unsigned ms_flags) {
583
#  if defined __NR_fsmount && __NR_fsmount >= 0
584
        return syscall(__NR_fsmount, fd, flags, ms_flags);
585
#  else
586
        errno = ENOSYS;
587
        return -1;
588
#  endif
589
}
590

591
#  define fsmount missing_fsmount
592
#endif
593

594
/* ======================================================================= */
595

596
#if !HAVE_GETDENTS64
597

598
static inline ssize_t missing_getdents64(int fd, void *buffer, size_t length) {
599
#  if defined __NR_getdents64 && __NR_getdents64 >= 0
600
        return syscall(__NR_getdents64, fd, buffer, length);
601
#  else
602
        errno = ENOSYS;
603
        return -1;
604
#  endif
605
}
606

607
#  define getdents64 missing_getdents64
608
#endif
609

610
/* ======================================================================= */
611

612
#if !HAVE_SCHED_SETATTR
613

614
static inline ssize_t missing_sched_setattr(pid_t pid, struct sched_attr *attr, unsigned int flags) {
615
        return syscall(__NR_sched_setattr, pid, attr, flags);
616
}
617

618
#  define sched_setattr missing_sched_setattr
619
#endif
620

621
/* ======================================================================= */
622

623
/* glibc does not provide clone() on ia64, only clone2(). Not only that, but it also doesn't provide a
624
 * prototype, only the symbol in the shared library (it provides a prototype for clone(), but not the
625
 * symbol in the shared library). */
626
#if defined(__ia64__)
627
int __clone2(int (*fn)(void *), void *stack_base, size_t stack_size, int flags, void *arg);
628
#define HAVE_CLONE 0
629
#else
630
/* We know that everywhere else clone() is available, so we don't bother with a meson check (that takes time
631
 * at build time) and just define it. Once the kernel drops ia64 support, we can drop this too. */
632
#define HAVE_CLONE 1
633
#endif
634

635
/* ======================================================================= */
636

637
#if !HAVE_QUOTACTL_FD
638

639
static inline int missing_quotactl_fd(int fd, int cmd, int id, void *addr) {
312✔
640
#  ifdef __NR_quotactl_fd
641
        return syscall(__NR_quotactl_fd, fd, cmd, id, addr);
312✔
642
#  else
643
        errno = ENOSYS;
644
        return -1;
645
#  endif
646
}
647

648
#  define quotactl_fd missing_quotactl_fd
649
#endif
650

651
/* ======================================================================= */
652

653
#if !HAVE_SETXATTRAT
654
struct xattr_args {
655
        _align_(8) uint64_t value;
656
        uint32_t size;
657
        uint32_t flags;
658
};
659

660
static inline int missing_setxattrat(int fd, const char *path, int at_flags, const char *name, const struct xattr_args *args, size_t size) {
1✔
661
#  ifdef __NR_setxattrat
662
        return syscall(__NR_setxattrat, fd, path, at_flags, name, args, size);
1✔
663
#  else
664
        errno = ENOSYS;
665
        return -1;
666
#  endif
667
}
668

669
#  define setxattrat missing_setxattrat
670
#endif
671

672
#if !HAVE_REMOVEXATTRAT
673
static inline int missing_removexattrat(int fd, const char *path, int at_flags, const char *name) {
×
674
#  ifdef __NR_removexattrat
675
        return syscall(__NR_removexattrat, fd, path, at_flags, name);
×
676
#  else
677
        errno = ENOSYS;
678
        return -1;
679
#  endif
680
}
681

682
#  define removexattrat missing_removexattrat
683
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc