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 <w@1wt.eu>
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 and provides a
49 * debugging hook.
50 */
51
__nolibc_enosys(const char * syscall,...)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))
sys_brk(void * addr)88 void *sys_brk(void *addr)
89 {
90 return (void *)my_syscall1(__NR_brk, addr);
91 }
92
93 static __attribute__((unused))
brk(void * addr)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))
sbrk(intptr_t inc)106 void *sbrk(intptr_t inc)
107 {
108 /* first call to find current end */
109 void *ret = sys_brk(NULL);
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 * int fchdir(int fildes);
122 */
123
124 static __attribute__((unused))
sys_chdir(const char * path)125 int sys_chdir(const char *path)
126 {
127 return my_syscall1(__NR_chdir, path);
128 }
129
130 static __attribute__((unused))
chdir(const char * path)131 int chdir(const char *path)
132 {
133 return __sysret(sys_chdir(path));
134 }
135
136 static __attribute__((unused))
sys_fchdir(int fildes)137 int sys_fchdir(int fildes)
138 {
139 return my_syscall1(__NR_fchdir, fildes);
140 }
141
142 static __attribute__((unused))
fchdir(int fildes)143 int fchdir(int fildes)
144 {
145 return __sysret(sys_fchdir(fildes));
146 }
147
148
149 /*
150 * int chmod(const char *path, mode_t mode);
151 */
152
153 static __attribute__((unused))
sys_chmod(const char * path,mode_t mode)154 int sys_chmod(const char *path, mode_t mode)
155 {
156 #if defined(__NR_fchmodat)
157 return my_syscall4(__NR_fchmodat, AT_FDCWD, path, mode, 0);
158 #else
159 return my_syscall2(__NR_chmod, path, mode);
160 #endif
161 }
162
163 static __attribute__((unused))
chmod(const char * path,mode_t mode)164 int chmod(const char *path, mode_t mode)
165 {
166 return __sysret(sys_chmod(path, mode));
167 }
168
169
170 /*
171 * int chown(const char *path, uid_t owner, gid_t group);
172 */
173
174 static __attribute__((unused))
sys_chown(const char * path,uid_t owner,gid_t group)175 int sys_chown(const char *path, uid_t owner, gid_t group)
176 {
177 #if defined(__NR_fchownat)
178 return my_syscall5(__NR_fchownat, AT_FDCWD, path, owner, group, 0);
179 #else
180 return my_syscall3(__NR_chown, path, owner, group);
181 #endif
182 }
183
184 static __attribute__((unused))
chown(const char * path,uid_t owner,gid_t group)185 int chown(const char *path, uid_t owner, gid_t group)
186 {
187 return __sysret(sys_chown(path, owner, group));
188 }
189
190
191 /*
192 * int chroot(const char *path);
193 */
194
195 static __attribute__((unused))
sys_chroot(const char * path)196 int sys_chroot(const char *path)
197 {
198 return my_syscall1(__NR_chroot, path);
199 }
200
201 static __attribute__((unused))
chroot(const char * path)202 int chroot(const char *path)
203 {
204 return __sysret(sys_chroot(path));
205 }
206
207
208 /*
209 * int close(int fd);
210 */
211
212 static __attribute__((unused))
sys_close(int fd)213 int sys_close(int fd)
214 {
215 return my_syscall1(__NR_close, fd);
216 }
217
218 static __attribute__((unused))
close(int fd)219 int close(int fd)
220 {
221 return __sysret(sys_close(fd));
222 }
223
224
225 /*
226 * int dup(int fd);
227 */
228
229 static __attribute__((unused))
sys_dup(int fd)230 int sys_dup(int fd)
231 {
232 return my_syscall1(__NR_dup, fd);
233 }
234
235 static __attribute__((unused))
dup(int fd)236 int dup(int fd)
237 {
238 return __sysret(sys_dup(fd));
239 }
240
241
242 /*
243 * int dup2(int old, int new);
244 */
245
246 static __attribute__((unused))
sys_dup2(int old,int new)247 int sys_dup2(int old, int new)
248 {
249 #if defined(__NR_dup3)
250 int ret, nr_fcntl;
251
252 #ifdef __NR_fcntl64
253 nr_fcntl = __NR_fcntl64;
254 #else
255 nr_fcntl = __NR_fcntl;
256 #endif
257
258 if (old == new) {
259 ret = my_syscall2(nr_fcntl, old, F_GETFD);
260 return ret < 0 ? ret : old;
261 }
262
263 return my_syscall3(__NR_dup3, old, new, 0);
264 #else
265 return my_syscall2(__NR_dup2, old, new);
266 #endif
267 }
268
269 static __attribute__((unused))
dup2(int old,int new)270 int dup2(int old, int new)
271 {
272 return __sysret(sys_dup2(old, new));
273 }
274
275
276 /*
277 * int dup3(int old, int new, int flags);
278 */
279
280 #if defined(__NR_dup3)
281 static __attribute__((unused))
sys_dup3(int old,int new,int flags)282 int sys_dup3(int old, int new, int flags)
283 {
284 return my_syscall3(__NR_dup3, old, new, flags);
285 }
286
287 static __attribute__((unused))
dup3(int old,int new,int flags)288 int dup3(int old, int new, int flags)
289 {
290 return __sysret(sys_dup3(old, new, flags));
291 }
292 #endif
293
294
295 /*
296 * int execve(const char *filename, char *const argv[], char *const envp[]);
297 */
298
299 static __attribute__((unused))
sys_execve(const char * filename,char * const argv[],char * const envp[])300 int sys_execve(const char *filename, char *const argv[], char *const envp[])
301 {
302 return my_syscall3(__NR_execve, filename, argv, envp);
303 }
304
305 static __attribute__((unused))
execve(const char * filename,char * const argv[],char * const envp[])306 int execve(const char *filename, char *const argv[], char *const envp[])
307 {
308 return __sysret(sys_execve(filename, argv, envp));
309 }
310
311
312 /*
313 * void exit(int status);
314 */
315
316 static __attribute__((noreturn,unused))
sys_exit(int status)317 void sys_exit(int status)
318 {
319 my_syscall1(__NR_exit, status & 255);
320 while(1); /* shut the "noreturn" warnings. */
321 }
322
323 static __attribute__((noreturn,unused))
_exit(int status)324 void _exit(int status)
325 {
326 sys_exit(status);
327 }
328
329 static __attribute__((noreturn,unused))
exit(int status)330 void exit(int status)
331 {
332 _exit(status);
333 }
334
335
336 /*
337 * pid_t fork(void);
338 */
339
340 #ifndef sys_fork
341 static __attribute__((unused))
sys_fork(void)342 pid_t sys_fork(void)
343 {
344 #if defined(__NR_clone)
345 /* note: some archs only have clone() and not fork(). Different archs
346 * have a different API, but most archs have the flags on first arg and
347 * will not use the rest with no other flag.
348 */
349 return my_syscall5(__NR_clone, SIGCHLD, 0, 0, 0, 0);
350 #else
351 return my_syscall0(__NR_fork);
352 #endif
353 }
354 #endif
355
356 static __attribute__((unused))
fork(void)357 pid_t fork(void)
358 {
359 return __sysret(sys_fork());
360 }
361
362 #ifndef sys_vfork
363 static __attribute__((unused))
sys_vfork(void)364 pid_t sys_vfork(void)
365 {
366 #if defined(__NR_clone)
367 /* See the note in sys_fork(). */
368 return my_syscall5(__NR_clone, CLONE_VM | CLONE_VFORK | SIGCHLD, 0, 0, 0, 0);
369 #elif defined(__NR_vfork)
370 return my_syscall0(__NR_vfork);
371 #endif
372 }
373 #endif
374
375 static __attribute__((unused))
vfork(void)376 pid_t vfork(void)
377 {
378 return __sysret(sys_vfork());
379 }
380
381 /*
382 * int fsync(int fd);
383 */
384
385 static __attribute__((unused))
sys_fsync(int fd)386 int sys_fsync(int fd)
387 {
388 return my_syscall1(__NR_fsync, fd);
389 }
390
391 static __attribute__((unused))
fsync(int fd)392 int fsync(int fd)
393 {
394 return __sysret(sys_fsync(fd));
395 }
396
397
398 /*
399 * int getdents64(int fd, struct linux_dirent64 *dirp, int count);
400 */
401
402 static __attribute__((unused))
sys_getdents64(int fd,struct linux_dirent64 * dirp,int count)403 int sys_getdents64(int fd, struct linux_dirent64 *dirp, int count)
404 {
405 return my_syscall3(__NR_getdents64, fd, dirp, count);
406 }
407
408 static __attribute__((unused))
getdents64(int fd,struct linux_dirent64 * dirp,int count)409 int getdents64(int fd, struct linux_dirent64 *dirp, int count)
410 {
411 return __sysret(sys_getdents64(fd, dirp, count));
412 }
413
414
415 /*
416 * uid_t geteuid(void);
417 */
418
419 static __attribute__((unused))
sys_geteuid(void)420 uid_t sys_geteuid(void)
421 {
422 #if defined(__NR_geteuid32)
423 return my_syscall0(__NR_geteuid32);
424 #else
425 return my_syscall0(__NR_geteuid);
426 #endif
427 }
428
429 static __attribute__((unused))
geteuid(void)430 uid_t geteuid(void)
431 {
432 return sys_geteuid();
433 }
434
435
436 /*
437 * pid_t getpgid(pid_t pid);
438 */
439
440 static __attribute__((unused))
sys_getpgid(pid_t pid)441 pid_t sys_getpgid(pid_t pid)
442 {
443 return my_syscall1(__NR_getpgid, pid);
444 }
445
446 static __attribute__((unused))
getpgid(pid_t pid)447 pid_t getpgid(pid_t pid)
448 {
449 return __sysret(sys_getpgid(pid));
450 }
451
452
453 /*
454 * pid_t getpgrp(void);
455 */
456
457 static __attribute__((unused))
sys_getpgrp(void)458 pid_t sys_getpgrp(void)
459 {
460 return sys_getpgid(0);
461 }
462
463 static __attribute__((unused))
getpgrp(void)464 pid_t getpgrp(void)
465 {
466 return sys_getpgrp();
467 }
468
469
470 /*
471 * pid_t getpid(void);
472 */
473
474 static __attribute__((unused))
sys_getpid(void)475 pid_t sys_getpid(void)
476 {
477 return my_syscall0(__NR_getpid);
478 }
479
480 static __attribute__((unused))
getpid(void)481 pid_t getpid(void)
482 {
483 return sys_getpid();
484 }
485
486
487 /*
488 * pid_t getppid(void);
489 */
490
491 static __attribute__((unused))
sys_getppid(void)492 pid_t sys_getppid(void)
493 {
494 return my_syscall0(__NR_getppid);
495 }
496
497 static __attribute__((unused))
getppid(void)498 pid_t getppid(void)
499 {
500 return sys_getppid();
501 }
502
503
504 /*
505 * pid_t gettid(void);
506 */
507
508 static __attribute__((unused))
sys_gettid(void)509 pid_t sys_gettid(void)
510 {
511 return my_syscall0(__NR_gettid);
512 }
513
514 static __attribute__((unused))
gettid(void)515 pid_t gettid(void)
516 {
517 return sys_gettid();
518 }
519
520 #ifndef NOLIBC_NO_RUNTIME
521 static unsigned long getauxval(unsigned long key);
522
523 /*
524 * int getpagesize(void);
525 */
526
527 static __attribute__((unused))
getpagesize(void)528 int getpagesize(void)
529 {
530 return __sysret((int)getauxval(AT_PAGESZ) ?: -ENOENT);
531 }
532 #endif /* NOLIBC_NO_RUNTIME */
533
534 /*
535 * uid_t getuid(void);
536 */
537
538 static __attribute__((unused))
sys_getuid(void)539 uid_t sys_getuid(void)
540 {
541 #if defined(__NR_getuid32)
542 return my_syscall0(__NR_getuid32);
543 #else
544 return my_syscall0(__NR_getuid);
545 #endif
546 }
547
548 static __attribute__((unused))
getuid(void)549 uid_t getuid(void)
550 {
551 return sys_getuid();
552 }
553
554
555 /*
556 * int kill(pid_t pid, int signal);
557 */
558
559 static __attribute__((unused))
sys_kill(pid_t pid,int signal)560 int sys_kill(pid_t pid, int signal)
561 {
562 return my_syscall2(__NR_kill, pid, signal);
563 }
564
565 static __attribute__((unused))
kill(pid_t pid,int signal)566 int kill(pid_t pid, int signal)
567 {
568 return __sysret(sys_kill(pid, signal));
569 }
570
571
572 /*
573 * int link(const char *old, const char *new);
574 */
575
576 static __attribute__((unused))
sys_link(const char * old,const char * new)577 int sys_link(const char *old, const char *new)
578 {
579 #if defined(__NR_linkat)
580 return my_syscall5(__NR_linkat, AT_FDCWD, old, AT_FDCWD, new, 0);
581 #else
582 return my_syscall2(__NR_link, old, new);
583 #endif
584 }
585
586 static __attribute__((unused))
link(const char * old,const char * new)587 int link(const char *old, const char *new)
588 {
589 return __sysret(sys_link(old, new));
590 }
591
592
593 /*
594 * off_t lseek(int fd, off_t offset, int whence);
595 */
596
597 static __attribute__((unused))
sys_lseek(int fd,off_t offset,int whence)598 off_t sys_lseek(int fd, off_t offset, int whence)
599 {
600 #if defined(__NR_llseek)
601 __kernel_loff_t loff = 0;
602 off_t result;
603 int ret;
604
605 ret = my_syscall5(__NR_llseek, fd, offset >> 32, (uint32_t)offset, &loff, whence);
606 if (ret < 0)
607 result = ret;
608 else
609 result = loff;
610
611 return result;
612 #else
613 return my_syscall3(__NR_lseek, fd, offset, whence);
614 #endif
615 }
616
617 static __attribute__((unused))
lseek(int fd,off_t offset,int whence)618 off_t lseek(int fd, off_t offset, int whence)
619 {
620 return __sysret(sys_lseek(fd, offset, whence));
621 }
622
623
624 /*
625 * int mkdir(const char *path, mode_t mode);
626 */
627
628 static __attribute__((unused))
sys_mkdir(const char * path,mode_t mode)629 int sys_mkdir(const char *path, mode_t mode)
630 {
631 #if defined(__NR_mkdirat)
632 return my_syscall3(__NR_mkdirat, AT_FDCWD, path, mode);
633 #else
634 return my_syscall2(__NR_mkdir, path, mode);
635 #endif
636 }
637
638 static __attribute__((unused))
mkdir(const char * path,mode_t mode)639 int mkdir(const char *path, mode_t mode)
640 {
641 return __sysret(sys_mkdir(path, mode));
642 }
643
644 /*
645 * int rmdir(const char *path);
646 */
647
648 static __attribute__((unused))
sys_rmdir(const char * path)649 int sys_rmdir(const char *path)
650 {
651 #if defined(__NR_rmdir)
652 return my_syscall1(__NR_rmdir, path);
653 #else
654 return my_syscall3(__NR_unlinkat, AT_FDCWD, path, AT_REMOVEDIR);
655 #endif
656 }
657
658 static __attribute__((unused))
rmdir(const char * path)659 int rmdir(const char *path)
660 {
661 return __sysret(sys_rmdir(path));
662 }
663
664
665 /*
666 * int mknod(const char *path, mode_t mode, dev_t dev);
667 */
668
669 static __attribute__((unused))
sys_mknod(const char * path,mode_t mode,dev_t dev)670 long sys_mknod(const char *path, mode_t mode, dev_t dev)
671 {
672 #if defined(__NR_mknodat)
673 return my_syscall4(__NR_mknodat, AT_FDCWD, path, mode, dev);
674 #else
675 return my_syscall3(__NR_mknod, path, mode, dev);
676 #endif
677 }
678
679 static __attribute__((unused))
mknod(const char * path,mode_t mode,dev_t dev)680 int mknod(const char *path, mode_t mode, dev_t dev)
681 {
682 return __sysret(sys_mknod(path, mode, dev));
683 }
684
685
686 /*
687 * int pipe2(int pipefd[2], int flags);
688 * int pipe(int pipefd[2]);
689 */
690
691 static __attribute__((unused))
sys_pipe2(int pipefd[2],int flags)692 int sys_pipe2(int pipefd[2], int flags)
693 {
694 return my_syscall2(__NR_pipe2, pipefd, flags);
695 }
696
697 static __attribute__((unused))
pipe2(int pipefd[2],int flags)698 int pipe2(int pipefd[2], int flags)
699 {
700 return __sysret(sys_pipe2(pipefd, flags));
701 }
702
703 static __attribute__((unused))
pipe(int pipefd[2])704 int pipe(int pipefd[2])
705 {
706 return pipe2(pipefd, 0);
707 }
708
709
710 /*
711 * int pivot_root(const char *new, const char *old);
712 */
713
714 static __attribute__((unused))
sys_pivot_root(const char * new,const char * old)715 int sys_pivot_root(const char *new, const char *old)
716 {
717 return my_syscall2(__NR_pivot_root, new, old);
718 }
719
720 static __attribute__((unused))
pivot_root(const char * new,const char * old)721 int pivot_root(const char *new, const char *old)
722 {
723 return __sysret(sys_pivot_root(new, old));
724 }
725
726
727 /*
728 * ssize_t read(int fd, void *buf, size_t count);
729 */
730
731 static __attribute__((unused))
sys_read(int fd,void * buf,size_t count)732 ssize_t sys_read(int fd, void *buf, size_t count)
733 {
734 return my_syscall3(__NR_read, fd, buf, count);
735 }
736
737 static __attribute__((unused))
read(int fd,void * buf,size_t count)738 ssize_t read(int fd, void *buf, size_t count)
739 {
740 return __sysret(sys_read(fd, buf, count));
741 }
742
743
744 /*
745 * int sched_yield(void);
746 */
747
748 static __attribute__((unused))
sys_sched_yield(void)749 int sys_sched_yield(void)
750 {
751 return my_syscall0(__NR_sched_yield);
752 }
753
754 static __attribute__((unused))
sched_yield(void)755 int sched_yield(void)
756 {
757 return __sysret(sys_sched_yield());
758 }
759
760
761 /*
762 * int setpgid(pid_t pid, pid_t pgid);
763 */
764
765 static __attribute__((unused))
sys_setpgid(pid_t pid,pid_t pgid)766 int sys_setpgid(pid_t pid, pid_t pgid)
767 {
768 return my_syscall2(__NR_setpgid, pid, pgid);
769 }
770
771 static __attribute__((unused))
setpgid(pid_t pid,pid_t pgid)772 int setpgid(pid_t pid, pid_t pgid)
773 {
774 return __sysret(sys_setpgid(pid, pgid));
775 }
776
777 /*
778 * pid_t setpgrp(void)
779 */
780
781 static __attribute__((unused))
setpgrp(void)782 pid_t setpgrp(void)
783 {
784 return setpgid(0, 0);
785 }
786
787
788 /*
789 * pid_t setsid(void);
790 */
791
792 static __attribute__((unused))
sys_setsid(void)793 pid_t sys_setsid(void)
794 {
795 return my_syscall0(__NR_setsid);
796 }
797
798 static __attribute__((unused))
setsid(void)799 pid_t setsid(void)
800 {
801 return __sysret(sys_setsid());
802 }
803
804
805 /*
806 * int symlink(const char *old, const char *new);
807 */
808
809 static __attribute__((unused))
sys_symlink(const char * old,const char * new)810 int sys_symlink(const char *old, const char *new)
811 {
812 #if defined(__NR_symlinkat)
813 return my_syscall3(__NR_symlinkat, old, AT_FDCWD, new);
814 #else
815 return my_syscall2(__NR_symlink, old, new);
816 #endif
817 }
818
819 static __attribute__((unused))
symlink(const char * old,const char * new)820 int symlink(const char *old, const char *new)
821 {
822 return __sysret(sys_symlink(old, new));
823 }
824
825
826 /*
827 * mode_t umask(mode_t mode);
828 */
829
830 static __attribute__((unused))
sys_umask(mode_t mode)831 mode_t sys_umask(mode_t mode)
832 {
833 return my_syscall1(__NR_umask, mode);
834 }
835
836 static __attribute__((unused))
umask(mode_t mode)837 mode_t umask(mode_t mode)
838 {
839 return sys_umask(mode);
840 }
841
842
843 /*
844 * int umount2(const char *path, int flags);
845 */
846
847 static __attribute__((unused))
sys_umount2(const char * path,int flags)848 int sys_umount2(const char *path, int flags)
849 {
850 return my_syscall2(__NR_umount2, path, flags);
851 }
852
853 static __attribute__((unused))
umount2(const char * path,int flags)854 int umount2(const char *path, int flags)
855 {
856 return __sysret(sys_umount2(path, flags));
857 }
858
859
860 /*
861 * int unlink(const char *path);
862 */
863
864 static __attribute__((unused))
sys_unlink(const char * path)865 int sys_unlink(const char *path)
866 {
867 #if defined(__NR_unlinkat)
868 return my_syscall3(__NR_unlinkat, AT_FDCWD, path, 0);
869 #else
870 return my_syscall1(__NR_unlink, path);
871 #endif
872 }
873
874 static __attribute__((unused))
unlink(const char * path)875 int unlink(const char *path)
876 {
877 return __sysret(sys_unlink(path));
878 }
879
880
881 /*
882 * ssize_t write(int fd, const void *buf, size_t count);
883 */
884
885 static __attribute__((unused))
sys_write(int fd,const void * buf,size_t count)886 ssize_t sys_write(int fd, const void *buf, size_t count)
887 {
888 return my_syscall3(__NR_write, fd, buf, count);
889 }
890
891 static __attribute__((unused))
write(int fd,const void * buf,size_t count)892 ssize_t write(int fd, const void *buf, size_t count)
893 {
894 return __sysret(sys_write(fd, buf, count));
895 }
896
897
898 /*
899 * int memfd_create(const char *name, unsigned int flags);
900 */
901
902 static __attribute__((unused))
sys_memfd_create(const char * name,unsigned int flags)903 int sys_memfd_create(const char *name, unsigned int flags)
904 {
905 return my_syscall2(__NR_memfd_create, name, flags);
906 }
907
908 static __attribute__((unused))
memfd_create(const char * name,unsigned int flags)909 int memfd_create(const char *name, unsigned int flags)
910 {
911 return __sysret(sys_memfd_create(name, flags));
912 }
913
914 #endif /* _NOLIBC_SYS_H */
915