projects/linux·blob master · refs

985 lines · 18.7 KiB

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