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