Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/include/nolibc/sys.h
26288 views
1
/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
2
/*
3
* Syscall definitions for NOLIBC (those in man(2))
4
* Copyright (C) 2017-2021 Willy Tarreau <[email protected]>
5
*/
6
7
/* make sure to include all global symbols */
8
#include "nolibc.h"
9
10
#ifndef _NOLIBC_SYS_H
11
#define _NOLIBC_SYS_H
12
13
#include "std.h"
14
15
/* system includes */
16
#include <linux/unistd.h>
17
#include <linux/signal.h> /* for SIGCHLD */
18
#include <linux/termios.h>
19
#include <linux/mman.h>
20
#include <linux/fs.h>
21
#include <linux/loop.h>
22
#include <linux/time.h>
23
#include <linux/auxvec.h>
24
#include <linux/fcntl.h> /* for O_* and AT_* */
25
#include <linux/sched.h> /* for clone_args */
26
#include <linux/stat.h> /* for statx() */
27
28
#include "errno.h"
29
#include "stdarg.h"
30
#include "types.h"
31
32
33
/* Syscall return helper: takes the syscall value in argument and checks for an
34
* error in it. This may only be used with signed returns (int or long), but
35
* not with pointers. An error is any value < 0. When an error is encountered,
36
* -ret is set into errno and -1 is returned. Otherwise the returned value is
37
* passed as-is with its type preserved.
38
*/
39
40
#define __sysret(arg) \
41
({ \
42
__typeof__(arg) __sysret_arg = (arg); \
43
(__sysret_arg < 0) /* error ? */ \
44
? (({ SET_ERRNO(-__sysret_arg); }), -1) /* ret -1 with errno = -arg */ \
45
: __sysret_arg; /* return original value */ \
46
})
47
48
/* Syscall ENOSYS helper: Avoids unused-parameter warnings and provides a
49
* debugging hook.
50
*/
51
52
static __inline__ int __nolibc_enosys(const char *syscall, ...)
53
{
54
(void)syscall;
55
return -ENOSYS;
56
}
57
58
59
/* Functions in this file only describe syscalls. They're declared static so
60
* that the compiler usually decides to inline them while still being allowed
61
* to pass a pointer to one of their instances. Each syscall exists in two
62
* versions:
63
* - the "internal" ones, which matches the raw syscall interface at the
64
* kernel level, which may sometimes slightly differ from the documented
65
* libc-level ones. For example most of them return either a valid value
66
* or -errno. All of these are prefixed with "sys_". They may be called
67
* by non-portable applications if desired.
68
*
69
* - the "exported" ones, whose interface must closely match the one
70
* documented in man(2), that applications are supposed to expect. These
71
* ones rely on the internal ones, and set errno.
72
*
73
* Each syscall will be defined with the two functions, sorted in alphabetical
74
* order applied to the exported names.
75
*
76
* In case of doubt about the relevance of a function here, only those which
77
* set errno should be defined here. Wrappers like those appearing in man(3)
78
* should not be placed here.
79
*/
80
81
82
/*
83
* int brk(void *addr);
84
* void *sbrk(intptr_t inc)
85
*/
86
87
static __attribute__((unused))
88
void *sys_brk(void *addr)
89
{
90
return (void *)my_syscall1(__NR_brk, addr);
91
}
92
93
static __attribute__((unused))
94
int brk(void *addr)
95
{
96
void *ret = sys_brk(addr);
97
98
if (!ret) {
99
SET_ERRNO(ENOMEM);
100
return -1;
101
}
102
return 0;
103
}
104
105
static __attribute__((unused))
106
void *sbrk(intptr_t inc)
107
{
108
/* first call to find current end */
109
void *ret = sys_brk(0);
110
111
if (ret && sys_brk(ret + inc) == ret + inc)
112
return ret + inc;
113
114
SET_ERRNO(ENOMEM);
115
return (void *)-1;
116
}
117
118
119
/*
120
* int chdir(const char *path);
121
*/
122
123
static __attribute__((unused))
124
int sys_chdir(const char *path)
125
{
126
return my_syscall1(__NR_chdir, path);
127
}
128
129
static __attribute__((unused))
130
int chdir(const char *path)
131
{
132
return __sysret(sys_chdir(path));
133
}
134
135
136
/*
137
* int chmod(const char *path, mode_t mode);
138
*/
139
140
static __attribute__((unused))
141
int sys_chmod(const char *path, mode_t mode)
142
{
143
#if defined(__NR_fchmodat)
144
return my_syscall4(__NR_fchmodat, AT_FDCWD, path, mode, 0);
145
#elif defined(__NR_chmod)
146
return my_syscall2(__NR_chmod, path, mode);
147
#else
148
return __nolibc_enosys(__func__, path, mode);
149
#endif
150
}
151
152
static __attribute__((unused))
153
int chmod(const char *path, mode_t mode)
154
{
155
return __sysret(sys_chmod(path, mode));
156
}
157
158
159
/*
160
* int chown(const char *path, uid_t owner, gid_t group);
161
*/
162
163
static __attribute__((unused))
164
int sys_chown(const char *path, uid_t owner, gid_t group)
165
{
166
#if defined(__NR_fchownat)
167
return my_syscall5(__NR_fchownat, AT_FDCWD, path, owner, group, 0);
168
#elif defined(__NR_chown)
169
return my_syscall3(__NR_chown, path, owner, group);
170
#else
171
return __nolibc_enosys(__func__, path, owner, group);
172
#endif
173
}
174
175
static __attribute__((unused))
176
int chown(const char *path, uid_t owner, gid_t group)
177
{
178
return __sysret(sys_chown(path, owner, group));
179
}
180
181
182
/*
183
* int chroot(const char *path);
184
*/
185
186
static __attribute__((unused))
187
int sys_chroot(const char *path)
188
{
189
return my_syscall1(__NR_chroot, path);
190
}
191
192
static __attribute__((unused))
193
int chroot(const char *path)
194
{
195
return __sysret(sys_chroot(path));
196
}
197
198
199
/*
200
* int close(int fd);
201
*/
202
203
static __attribute__((unused))
204
int sys_close(int fd)
205
{
206
return my_syscall1(__NR_close, fd);
207
}
208
209
static __attribute__((unused))
210
int close(int fd)
211
{
212
return __sysret(sys_close(fd));
213
}
214
215
216
/*
217
* int dup(int fd);
218
*/
219
220
static __attribute__((unused))
221
int sys_dup(int fd)
222
{
223
return my_syscall1(__NR_dup, fd);
224
}
225
226
static __attribute__((unused))
227
int dup(int fd)
228
{
229
return __sysret(sys_dup(fd));
230
}
231
232
233
/*
234
* int dup2(int old, int new);
235
*/
236
237
static __attribute__((unused))
238
int sys_dup2(int old, int new)
239
{
240
#if defined(__NR_dup3)
241
return my_syscall3(__NR_dup3, old, new, 0);
242
#elif defined(__NR_dup2)
243
return my_syscall2(__NR_dup2, old, new);
244
#else
245
return __nolibc_enosys(__func__, old, new);
246
#endif
247
}
248
249
static __attribute__((unused))
250
int dup2(int old, int new)
251
{
252
return __sysret(sys_dup2(old, new));
253
}
254
255
256
/*
257
* int dup3(int old, int new, int flags);
258
*/
259
260
#if defined(__NR_dup3)
261
static __attribute__((unused))
262
int sys_dup3(int old, int new, int flags)
263
{
264
return my_syscall3(__NR_dup3, old, new, flags);
265
}
266
267
static __attribute__((unused))
268
int dup3(int old, int new, int flags)
269
{
270
return __sysret(sys_dup3(old, new, flags));
271
}
272
#endif
273
274
275
/*
276
* int execve(const char *filename, char *const argv[], char *const envp[]);
277
*/
278
279
static __attribute__((unused))
280
int sys_execve(const char *filename, char *const argv[], char *const envp[])
281
{
282
return my_syscall3(__NR_execve, filename, argv, envp);
283
}
284
285
static __attribute__((unused))
286
int execve(const char *filename, char *const argv[], char *const envp[])
287
{
288
return __sysret(sys_execve(filename, argv, envp));
289
}
290
291
292
/*
293
* void exit(int status);
294
*/
295
296
static __attribute__((noreturn,unused))
297
void sys_exit(int status)
298
{
299
my_syscall1(__NR_exit, status & 255);
300
while(1); /* shut the "noreturn" warnings. */
301
}
302
303
static __attribute__((noreturn,unused))
304
void _exit(int status)
305
{
306
sys_exit(status);
307
}
308
309
static __attribute__((noreturn,unused))
310
void exit(int status)
311
{
312
_exit(status);
313
}
314
315
316
/*
317
* pid_t fork(void);
318
*/
319
320
#ifndef sys_fork
321
static __attribute__((unused))
322
pid_t sys_fork(void)
323
{
324
#if defined(__NR_clone)
325
/* note: some archs only have clone() and not fork(). Different archs
326
* have a different API, but most archs have the flags on first arg and
327
* will not use the rest with no other flag.
328
*/
329
return my_syscall5(__NR_clone, SIGCHLD, 0, 0, 0, 0);
330
#elif defined(__NR_fork)
331
return my_syscall0(__NR_fork);
332
#else
333
return __nolibc_enosys(__func__);
334
#endif
335
}
336
#endif
337
338
static __attribute__((unused))
339
pid_t fork(void)
340
{
341
return __sysret(sys_fork());
342
}
343
344
#ifndef sys_vfork
345
static __attribute__((unused))
346
pid_t sys_vfork(void)
347
{
348
#if defined(__NR_vfork)
349
return my_syscall0(__NR_vfork);
350
#elif defined(__NR_clone3)
351
/*
352
* clone() could be used but has different argument orders per
353
* architecture.
354
*/
355
struct clone_args args = {
356
.flags = CLONE_VM | CLONE_VFORK,
357
.exit_signal = SIGCHLD,
358
};
359
360
return my_syscall2(__NR_clone3, &args, sizeof(args));
361
#else
362
return __nolibc_enosys(__func__);
363
#endif
364
}
365
#endif
366
367
static __attribute__((unused))
368
pid_t vfork(void)
369
{
370
return __sysret(sys_vfork());
371
}
372
373
/*
374
* int fsync(int fd);
375
*/
376
377
static __attribute__((unused))
378
int sys_fsync(int fd)
379
{
380
return my_syscall1(__NR_fsync, fd);
381
}
382
383
static __attribute__((unused))
384
int fsync(int fd)
385
{
386
return __sysret(sys_fsync(fd));
387
}
388
389
390
/*
391
* int getdents64(int fd, struct linux_dirent64 *dirp, int count);
392
*/
393
394
static __attribute__((unused))
395
int sys_getdents64(int fd, struct linux_dirent64 *dirp, int count)
396
{
397
return my_syscall3(__NR_getdents64, fd, dirp, count);
398
}
399
400
static __attribute__((unused))
401
int getdents64(int fd, struct linux_dirent64 *dirp, int count)
402
{
403
return __sysret(sys_getdents64(fd, dirp, count));
404
}
405
406
407
/*
408
* uid_t geteuid(void);
409
*/
410
411
static __attribute__((unused))
412
uid_t sys_geteuid(void)
413
{
414
#if defined(__NR_geteuid32)
415
return my_syscall0(__NR_geteuid32);
416
#else
417
return my_syscall0(__NR_geteuid);
418
#endif
419
}
420
421
static __attribute__((unused))
422
uid_t geteuid(void)
423
{
424
return sys_geteuid();
425
}
426
427
428
/*
429
* pid_t getpgid(pid_t pid);
430
*/
431
432
static __attribute__((unused))
433
pid_t sys_getpgid(pid_t pid)
434
{
435
return my_syscall1(__NR_getpgid, pid);
436
}
437
438
static __attribute__((unused))
439
pid_t getpgid(pid_t pid)
440
{
441
return __sysret(sys_getpgid(pid));
442
}
443
444
445
/*
446
* pid_t getpgrp(void);
447
*/
448
449
static __attribute__((unused))
450
pid_t sys_getpgrp(void)
451
{
452
return sys_getpgid(0);
453
}
454
455
static __attribute__((unused))
456
pid_t getpgrp(void)
457
{
458
return sys_getpgrp();
459
}
460
461
462
/*
463
* pid_t getpid(void);
464
*/
465
466
static __attribute__((unused))
467
pid_t sys_getpid(void)
468
{
469
return my_syscall0(__NR_getpid);
470
}
471
472
static __attribute__((unused))
473
pid_t getpid(void)
474
{
475
return sys_getpid();
476
}
477
478
479
/*
480
* pid_t getppid(void);
481
*/
482
483
static __attribute__((unused))
484
pid_t sys_getppid(void)
485
{
486
return my_syscall0(__NR_getppid);
487
}
488
489
static __attribute__((unused))
490
pid_t getppid(void)
491
{
492
return sys_getppid();
493
}
494
495
496
/*
497
* pid_t gettid(void);
498
*/
499
500
static __attribute__((unused))
501
pid_t sys_gettid(void)
502
{
503
return my_syscall0(__NR_gettid);
504
}
505
506
static __attribute__((unused))
507
pid_t gettid(void)
508
{
509
return sys_gettid();
510
}
511
512
static unsigned long getauxval(unsigned long key);
513
514
/*
515
* int getpagesize(void);
516
*/
517
518
static __attribute__((unused))
519
int getpagesize(void)
520
{
521
return __sysret((int)getauxval(AT_PAGESZ) ?: -ENOENT);
522
}
523
524
525
/*
526
* uid_t getuid(void);
527
*/
528
529
static __attribute__((unused))
530
uid_t sys_getuid(void)
531
{
532
#if defined(__NR_getuid32)
533
return my_syscall0(__NR_getuid32);
534
#else
535
return my_syscall0(__NR_getuid);
536
#endif
537
}
538
539
static __attribute__((unused))
540
uid_t getuid(void)
541
{
542
return sys_getuid();
543
}
544
545
546
/*
547
* int kill(pid_t pid, int signal);
548
*/
549
550
static __attribute__((unused))
551
int sys_kill(pid_t pid, int signal)
552
{
553
return my_syscall2(__NR_kill, pid, signal);
554
}
555
556
static __attribute__((unused))
557
int kill(pid_t pid, int signal)
558
{
559
return __sysret(sys_kill(pid, signal));
560
}
561
562
563
/*
564
* int link(const char *old, const char *new);
565
*/
566
567
static __attribute__((unused))
568
int sys_link(const char *old, const char *new)
569
{
570
#if defined(__NR_linkat)
571
return my_syscall5(__NR_linkat, AT_FDCWD, old, AT_FDCWD, new, 0);
572
#elif defined(__NR_link)
573
return my_syscall2(__NR_link, old, new);
574
#else
575
return __nolibc_enosys(__func__, old, new);
576
#endif
577
}
578
579
static __attribute__((unused))
580
int link(const char *old, const char *new)
581
{
582
return __sysret(sys_link(old, new));
583
}
584
585
586
/*
587
* off_t lseek(int fd, off_t offset, int whence);
588
*/
589
590
static __attribute__((unused))
591
off_t sys_lseek(int fd, off_t offset, int whence)
592
{
593
#if defined(__NR_lseek)
594
return my_syscall3(__NR_lseek, fd, offset, whence);
595
#else
596
return __nolibc_enosys(__func__, fd, offset, whence);
597
#endif
598
}
599
600
static __attribute__((unused))
601
int sys_llseek(int fd, unsigned long offset_high, unsigned long offset_low,
602
__kernel_loff_t *result, int whence)
603
{
604
#if defined(__NR_llseek)
605
return my_syscall5(__NR_llseek, fd, offset_high, offset_low, result, whence);
606
#else
607
return __nolibc_enosys(__func__, fd, offset_high, offset_low, result, whence);
608
#endif
609
}
610
611
static __attribute__((unused))
612
off_t lseek(int fd, off_t offset, int whence)
613
{
614
__kernel_loff_t loff = 0;
615
off_t result;
616
int ret;
617
618
result = sys_lseek(fd, offset, whence);
619
if (result == -ENOSYS) {
620
/* Only exists on 32bit where nolibc off_t is also 32bit */
621
ret = sys_llseek(fd, 0, offset, &loff, whence);
622
if (ret < 0)
623
result = ret;
624
else if (loff != (off_t)loff)
625
result = -EOVERFLOW;
626
else
627
result = loff;
628
}
629
630
return __sysret(result);
631
}
632
633
634
/*
635
* int mkdir(const char *path, mode_t mode);
636
*/
637
638
static __attribute__((unused))
639
int sys_mkdir(const char *path, mode_t mode)
640
{
641
#if defined(__NR_mkdirat)
642
return my_syscall3(__NR_mkdirat, AT_FDCWD, path, mode);
643
#elif defined(__NR_mkdir)
644
return my_syscall2(__NR_mkdir, path, mode);
645
#else
646
return __nolibc_enosys(__func__, path, mode);
647
#endif
648
}
649
650
static __attribute__((unused))
651
int mkdir(const char *path, mode_t mode)
652
{
653
return __sysret(sys_mkdir(path, mode));
654
}
655
656
/*
657
* int rmdir(const char *path);
658
*/
659
660
static __attribute__((unused))
661
int sys_rmdir(const char *path)
662
{
663
#if defined(__NR_rmdir)
664
return my_syscall1(__NR_rmdir, path);
665
#elif defined(__NR_unlinkat)
666
return my_syscall3(__NR_unlinkat, AT_FDCWD, path, AT_REMOVEDIR);
667
#else
668
return __nolibc_enosys(__func__, path);
669
#endif
670
}
671
672
static __attribute__((unused))
673
int rmdir(const char *path)
674
{
675
return __sysret(sys_rmdir(path));
676
}
677
678
679
/*
680
* int mknod(const char *path, mode_t mode, dev_t dev);
681
*/
682
683
static __attribute__((unused))
684
long sys_mknod(const char *path, mode_t mode, dev_t dev)
685
{
686
#if defined(__NR_mknodat)
687
return my_syscall4(__NR_mknodat, AT_FDCWD, path, mode, dev);
688
#elif defined(__NR_mknod)
689
return my_syscall3(__NR_mknod, path, mode, dev);
690
#else
691
return __nolibc_enosys(__func__, path, mode, dev);
692
#endif
693
}
694
695
static __attribute__((unused))
696
int mknod(const char *path, mode_t mode, dev_t dev)
697
{
698
return __sysret(sys_mknod(path, mode, dev));
699
}
700
701
702
/*
703
* int pipe2(int pipefd[2], int flags);
704
* int pipe(int pipefd[2]);
705
*/
706
707
static __attribute__((unused))
708
int sys_pipe2(int pipefd[2], int flags)
709
{
710
return my_syscall2(__NR_pipe2, pipefd, flags);
711
}
712
713
static __attribute__((unused))
714
int pipe2(int pipefd[2], int flags)
715
{
716
return __sysret(sys_pipe2(pipefd, flags));
717
}
718
719
static __attribute__((unused))
720
int pipe(int pipefd[2])
721
{
722
return pipe2(pipefd, 0);
723
}
724
725
726
/*
727
* int pivot_root(const char *new, const char *old);
728
*/
729
730
static __attribute__((unused))
731
int sys_pivot_root(const char *new, const char *old)
732
{
733
return my_syscall2(__NR_pivot_root, new, old);
734
}
735
736
static __attribute__((unused))
737
int pivot_root(const char *new, const char *old)
738
{
739
return __sysret(sys_pivot_root(new, old));
740
}
741
742
743
/*
744
* ssize_t read(int fd, void *buf, size_t count);
745
*/
746
747
static __attribute__((unused))
748
ssize_t sys_read(int fd, void *buf, size_t count)
749
{
750
return my_syscall3(__NR_read, fd, buf, count);
751
}
752
753
static __attribute__((unused))
754
ssize_t read(int fd, void *buf, size_t count)
755
{
756
return __sysret(sys_read(fd, buf, count));
757
}
758
759
760
/*
761
* int sched_yield(void);
762
*/
763
764
static __attribute__((unused))
765
int sys_sched_yield(void)
766
{
767
return my_syscall0(__NR_sched_yield);
768
}
769
770
static __attribute__((unused))
771
int sched_yield(void)
772
{
773
return __sysret(sys_sched_yield());
774
}
775
776
777
/*
778
* int select(int nfds, fd_set *read_fds, fd_set *write_fds,
779
* fd_set *except_fds, struct timeval *timeout);
780
*/
781
782
static __attribute__((unused))
783
int sys_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout)
784
{
785
#if defined(__ARCH_WANT_SYS_OLD_SELECT) && !defined(__NR__newselect)
786
struct sel_arg_struct {
787
unsigned long n;
788
fd_set *r, *w, *e;
789
struct timeval *t;
790
} arg = { .n = nfds, .r = rfds, .w = wfds, .e = efds, .t = timeout };
791
return my_syscall1(__NR_select, &arg);
792
#elif defined(__NR__newselect)
793
return my_syscall5(__NR__newselect, nfds, rfds, wfds, efds, timeout);
794
#elif defined(__NR_select)
795
return my_syscall5(__NR_select, nfds, rfds, wfds, efds, timeout);
796
#elif defined(__NR_pselect6)
797
struct timespec t;
798
799
if (timeout) {
800
t.tv_sec = timeout->tv_sec;
801
t.tv_nsec = timeout->tv_usec * 1000;
802
}
803
return my_syscall6(__NR_pselect6, nfds, rfds, wfds, efds, timeout ? &t : NULL, NULL);
804
#elif defined(__NR_pselect6_time64)
805
struct __kernel_timespec t;
806
807
if (timeout) {
808
t.tv_sec = timeout->tv_sec;
809
t.tv_nsec = timeout->tv_usec * 1000;
810
}
811
return my_syscall6(__NR_pselect6_time64, nfds, rfds, wfds, efds, timeout ? &t : NULL, NULL);
812
#else
813
return __nolibc_enosys(__func__, nfds, rfds, wfds, efds, timeout);
814
#endif
815
}
816
817
static __attribute__((unused))
818
int select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout)
819
{
820
return __sysret(sys_select(nfds, rfds, wfds, efds, timeout));
821
}
822
823
824
/*
825
* int setpgid(pid_t pid, pid_t pgid);
826
*/
827
828
static __attribute__((unused))
829
int sys_setpgid(pid_t pid, pid_t pgid)
830
{
831
return my_syscall2(__NR_setpgid, pid, pgid);
832
}
833
834
static __attribute__((unused))
835
int setpgid(pid_t pid, pid_t pgid)
836
{
837
return __sysret(sys_setpgid(pid, pgid));
838
}
839
840
/*
841
* pid_t setpgrp(void)
842
*/
843
844
static __attribute__((unused))
845
pid_t setpgrp(void)
846
{
847
return setpgid(0, 0);
848
}
849
850
851
/*
852
* pid_t setsid(void);
853
*/
854
855
static __attribute__((unused))
856
pid_t sys_setsid(void)
857
{
858
return my_syscall0(__NR_setsid);
859
}
860
861
static __attribute__((unused))
862
pid_t setsid(void)
863
{
864
return __sysret(sys_setsid());
865
}
866
867
868
/*
869
* int symlink(const char *old, const char *new);
870
*/
871
872
static __attribute__((unused))
873
int sys_symlink(const char *old, const char *new)
874
{
875
#if defined(__NR_symlinkat)
876
return my_syscall3(__NR_symlinkat, old, AT_FDCWD, new);
877
#elif defined(__NR_symlink)
878
return my_syscall2(__NR_symlink, old, new);
879
#else
880
return __nolibc_enosys(__func__, old, new);
881
#endif
882
}
883
884
static __attribute__((unused))
885
int symlink(const char *old, const char *new)
886
{
887
return __sysret(sys_symlink(old, new));
888
}
889
890
891
/*
892
* mode_t umask(mode_t mode);
893
*/
894
895
static __attribute__((unused))
896
mode_t sys_umask(mode_t mode)
897
{
898
return my_syscall1(__NR_umask, mode);
899
}
900
901
static __attribute__((unused))
902
mode_t umask(mode_t mode)
903
{
904
return sys_umask(mode);
905
}
906
907
908
/*
909
* int umount2(const char *path, int flags);
910
*/
911
912
static __attribute__((unused))
913
int sys_umount2(const char *path, int flags)
914
{
915
return my_syscall2(__NR_umount2, path, flags);
916
}
917
918
static __attribute__((unused))
919
int umount2(const char *path, int flags)
920
{
921
return __sysret(sys_umount2(path, flags));
922
}
923
924
925
/*
926
* int unlink(const char *path);
927
*/
928
929
static __attribute__((unused))
930
int sys_unlink(const char *path)
931
{
932
#if defined(__NR_unlinkat)
933
return my_syscall3(__NR_unlinkat, AT_FDCWD, path, 0);
934
#elif defined(__NR_unlink)
935
return my_syscall1(__NR_unlink, path);
936
#else
937
return __nolibc_enosys(__func__, path);
938
#endif
939
}
940
941
static __attribute__((unused))
942
int unlink(const char *path)
943
{
944
return __sysret(sys_unlink(path));
945
}
946
947
948
/*
949
* ssize_t write(int fd, const void *buf, size_t count);
950
*/
951
952
static __attribute__((unused))
953
ssize_t sys_write(int fd, const void *buf, size_t count)
954
{
955
return my_syscall3(__NR_write, fd, buf, count);
956
}
957
958
static __attribute__((unused))
959
ssize_t write(int fd, const void *buf, size_t count)
960
{
961
return __sysret(sys_write(fd, buf, count));
962
}
963
964
965
/*
966
* int memfd_create(const char *name, unsigned int flags);
967
*/
968
969
static __attribute__((unused))
970
int sys_memfd_create(const char *name, unsigned int flags)
971
{
972
return my_syscall2(__NR_memfd_create, name, flags);
973
}
974
975
static __attribute__((unused))
976
int memfd_create(const char *name, unsigned int flags)
977
{
978
return __sysret(sys_memfd_create(name, flags));
979
}
980
981
#endif /* _NOLIBC_SYS_H */
982
983