xref: /linux/tools/include/nolibc/sys.h (revision 542fed2ef2ff7e580cc25efb174f5e1237e3b0eb)
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, provides compile
49  * time validation and a debugging hook.
50  */
51 
52 #if defined(NOLIBC_COMPILE_TIME_ENOSYS)
__nolibc_enosys(const char * syscall,...)53 static __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")))
61 extern int __nolibc_enosys(const char *syscall, ...);
62 
63 #else
__nolibc_enosys(const char * syscall,...)64 static __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 
102 static __attribute__((unused))
_sys_brk(void * addr)103 void *_sys_brk(void *addr)
104 {
105 	return (void *)(unsigned long)__nolibc_syscall1(__NR_brk, addr);
106 }
107 
108 static __attribute__((unused))
brk(void * addr)109 int 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 
120 static __attribute__((unused))
sbrk(intptr_t inc)121 void *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 
139 static __attribute__((unused))
_sys_chdir(const char * path)140 int _sys_chdir(const char *path)
141 {
142 	return __nolibc_syscall1(__NR_chdir, path);
143 }
144 
145 static __attribute__((unused))
chdir(const char * path)146 int chdir(const char *path)
147 {
148 	return __sysret(_sys_chdir(path));
149 }
150 
151 static __attribute__((unused))
_sys_fchdir(int fildes)152 int _sys_fchdir(int fildes)
153 {
154 	return __nolibc_syscall1(__NR_fchdir, fildes);
155 }
156 
157 static __attribute__((unused))
fchdir(int fildes)158 int 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 
168 static __attribute__((unused))
_sys_chmod(const char * path,mode_t mode)169 int _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 
178 static __attribute__((unused))
chmod(const char * path,mode_t mode)179 int 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 
189 static __attribute__((unused))
_sys_chown(const char * path,uid_t owner,gid_t group)190 int _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 
199 static __attribute__((unused))
chown(const char * path,uid_t owner,gid_t group)200 int 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 
210 static __attribute__((unused))
_sys_chroot(const char * path)211 int _sys_chroot(const char *path)
212 {
213 	return __nolibc_syscall1(__NR_chroot, path);
214 }
215 
216 static __attribute__((unused))
chroot(const char * path)217 int chroot(const char *path)
218 {
219 	return __sysret(_sys_chroot(path));
220 }
221 
222 
223 /*
224  * int close(int fd);
225  */
226 
227 static __attribute__((unused))
_sys_close(int fd)228 int _sys_close(int fd)
229 {
230 	return __nolibc_syscall1(__NR_close, fd);
231 }
232 
233 static __attribute__((unused))
close(int fd)234 int close(int fd)
235 {
236 	return __sysret(_sys_close(fd));
237 }
238 
239 
240 /*
241  * int dup(int fd);
242  */
243 
244 static __attribute__((unused))
_sys_dup(int fd)245 int _sys_dup(int fd)
246 {
247 	return __nolibc_syscall1(__NR_dup, fd);
248 }
249 
250 static __attribute__((unused))
dup(int fd)251 int dup(int fd)
252 {
253 	return __sysret(_sys_dup(fd));
254 }
255 
256 
257 /*
258  * int dup2(int old, int new);
259  */
260 
261 static __attribute__((unused))
_sys_dup2(int old,int new)262 int _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 
284 static __attribute__((unused))
dup2(int old,int new)285 int 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)
296 static __attribute__((unused))
_sys_dup3(int old,int new,int flags)297 int _sys_dup3(int old, int new, int flags)
298 {
299 	return __nolibc_syscall3(__NR_dup3, old, new, flags);
300 }
301 
302 static __attribute__((unused))
dup3(int old,int new,int flags)303 int 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 
314 static __attribute__((unused))
_sys_execve(const char * filename,char * const argv[],char * const envp[])315 int _sys_execve(const char *filename, char *const argv[], char *const envp[])
316 {
317 	return __nolibc_syscall3(__NR_execve, filename, argv, envp);
318 }
319 
320 static __attribute__((unused))
execve(const char * filename,char * const argv[],char * const envp[])321 int 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 
331 static __attribute__((noreturn,unused))
_sys_exit(int status)332 void _sys_exit(int status)
333 {
334 	__nolibc_syscall1(__NR_exit, status & 255);
335 	while(1); /* shut the "noreturn" warnings. */
336 }
337 
338 static __attribute__((noreturn,unused))
_exit(int status)339 void _exit(int status)
340 {
341 	_sys_exit(status);
342 }
343 
344 static __attribute__((noreturn,unused))
exit(int status)345 void exit(int status)
346 {
347 	_exit(status);
348 }
349 
350 
351 /*
352  * pid_t fork(void);
353  */
354 
355 #ifndef _sys_fork
356 static __attribute__((unused))
_sys_fork(void)357 pid_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 
371 static __attribute__((unused))
fork(void)372 pid_t fork(void)
373 {
374 	return __sysret(_sys_fork());
375 }
376 
377 #ifndef _sys_vfork
378 static __attribute__((unused))
_sys_vfork(void)379 pid_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 
390 static __attribute__((unused))
vfork(void)391 pid_t vfork(void)
392 {
393 	return __sysret(_sys_vfork());
394 }
395 
396 /*
397  * int fsync(int fd);
398  */
399 
400 static __attribute__((unused))
_sys_fsync(int fd)401 int _sys_fsync(int fd)
402 {
403 	return __nolibc_syscall1(__NR_fsync, fd);
404 }
405 
406 static __attribute__((unused))
fsync(int fd)407 int 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 
417 static __attribute__((unused))
_sys_getdents64(int fd,struct linux_dirent64 * dirp,int count)418 int _sys_getdents64(int fd, struct linux_dirent64 *dirp, int count)
419 {
420 	return __nolibc_syscall3(__NR_getdents64, fd, dirp, count);
421 }
422 
423 static __attribute__((unused))
getdents64(int fd,struct linux_dirent64 * dirp,int count)424 int 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 
434 static __attribute__((unused))
_sys_geteuid(void)435 uid_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 
444 static __attribute__((unused))
geteuid(void)445 uid_t geteuid(void)
446 {
447 	return _sys_geteuid();
448 }
449 
450 
451 /*
452  * pid_t getpgid(pid_t pid);
453  */
454 
455 static __attribute__((unused))
_sys_getpgid(pid_t pid)456 pid_t _sys_getpgid(pid_t pid)
457 {
458 	return __nolibc_syscall1(__NR_getpgid, pid);
459 }
460 
461 static __attribute__((unused))
getpgid(pid_t pid)462 pid_t getpgid(pid_t pid)
463 {
464 	return __sysret(_sys_getpgid(pid));
465 }
466 
467 
468 /*
469  * pid_t getpgrp(void);
470  */
471 
472 static __attribute__((unused))
_sys_getpgrp(void)473 pid_t _sys_getpgrp(void)
474 {
475 	return _sys_getpgid(0);
476 }
477 
478 static __attribute__((unused))
getpgrp(void)479 pid_t getpgrp(void)
480 {
481 	return _sys_getpgrp();
482 }
483 
484 
485 /*
486  * pid_t getpid(void);
487  */
488 
489 static __attribute__((unused))
_sys_getpid(void)490 pid_t _sys_getpid(void)
491 {
492 	return __nolibc_syscall0(__NR_getpid);
493 }
494 
495 static __attribute__((unused))
getpid(void)496 pid_t getpid(void)
497 {
498 	return _sys_getpid();
499 }
500 
501 
502 /*
503  * pid_t getppid(void);
504  */
505 
506 static __attribute__((unused))
_sys_getppid(void)507 pid_t _sys_getppid(void)
508 {
509 	return __nolibc_syscall0(__NR_getppid);
510 }
511 
512 static __attribute__((unused))
getppid(void)513 pid_t getppid(void)
514 {
515 	return _sys_getppid();
516 }
517 
518 
519 /*
520  * pid_t gettid(void);
521  */
522 
523 static __attribute__((unused))
_sys_gettid(void)524 pid_t _sys_gettid(void)
525 {
526 	return __nolibc_syscall0(__NR_gettid);
527 }
528 
529 static __attribute__((unused))
gettid(void)530 pid_t gettid(void)
531 {
532 	return _sys_gettid();
533 }
534 
535 #ifndef NOLIBC_NO_RUNTIME
536 static unsigned long getauxval(unsigned long key);
537 
538 /*
539  * int getpagesize(void);
540  */
541 
542 static __attribute__((unused))
getpagesize(void)543 int 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 
553 static __attribute__((unused))
_sys_getuid(void)554 uid_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 
563 static __attribute__((unused))
getuid(void)564 uid_t getuid(void)
565 {
566 	return _sys_getuid();
567 }
568 
569 
570 /*
571  * int kill(pid_t pid, int signal);
572  */
573 
574 static __attribute__((unused))
_sys_kill(pid_t pid,int signal)575 int _sys_kill(pid_t pid, int signal)
576 {
577 	return __nolibc_syscall2(__NR_kill, pid, signal);
578 }
579 
580 static __attribute__((unused))
kill(pid_t pid,int signal)581 int 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 
591 static __attribute__((unused))
_sys_link(const char * old,const char * new)592 int _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 
601 static __attribute__((unused))
link(const char * old,const char * new)602 int 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 
612 static __attribute__((unused))
_sys_lseek(int fd,off_t offset,int whence)613 off_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 
638 static __attribute__((unused))
lseek(int fd,off_t offset,int whence)639 off_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 
649 static __attribute__((unused))
_sys_mkdir(const char * path,mode_t mode)650 int _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 
659 static __attribute__((unused))
mkdir(const char * path,mode_t mode)660 int 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 
669 static __attribute__((unused))
_sys_rmdir(const char * path)670 int _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 
679 static __attribute__((unused))
rmdir(const char * path)680 int 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 
690 static __attribute__((unused))
_sys_mknod(const char * path,mode_t mode,dev_t dev)691 long _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 
700 static __attribute__((unused))
mknod(const char * path,mode_t mode,dev_t dev)701 int 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 
712 static __attribute__((unused))
_sys_pipe2(int pipefd[2],int flags)713 int _sys_pipe2(int pipefd[2], int flags)
714 {
715 	return __nolibc_syscall2(__NR_pipe2, pipefd, flags);
716 }
717 
718 static __attribute__((unused))
pipe2(int pipefd[2],int flags)719 int pipe2(int pipefd[2], int flags)
720 {
721 	return __sysret(_sys_pipe2(pipefd, flags));
722 }
723 
724 static __attribute__((unused))
pipe(int pipefd[2])725 int 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 
735 static __attribute__((unused))
_sys_pivot_root(const char * new,const char * old)736 int _sys_pivot_root(const char *new, const char *old)
737 {
738 	return __nolibc_syscall2(__NR_pivot_root, new, old);
739 }
740 
741 static __attribute__((unused))
pivot_root(const char * new,const char * old)742 int 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
754 static __attribute__((unused))
_sys_pread(int fd,void * buf,size_t count,off_t offset)755 ssize_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 
769 static __attribute__((unused))
pread(int fd,void * buf,size_t count,off_t offset)770 ssize_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
776 static __attribute__((unused))
_sys_pwrite(int fd,const void * buf,size_t count,off_t offset)777 ssize_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 
791 static __attribute__((unused))
pwrite(int fd,const void * buf,size_t count,off_t offset)792 ssize_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 
802 static __attribute__((unused))
_sys_read(int fd,void * buf,size_t count)803 ssize_t _sys_read(int fd, void *buf, size_t count)
804 {
805 	return __nolibc_syscall3(__NR_read, fd, buf, count);
806 }
807 
808 static __attribute__((unused))
read(int fd,void * buf,size_t count)809 ssize_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 
819 static __attribute__((unused))
_sys_sched_yield(void)820 int _sys_sched_yield(void)
821 {
822 	return __nolibc_syscall0(__NR_sched_yield);
823 }
824 
825 static __attribute__((unused))
sched_yield(void)826 int 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 
836 static __attribute__((unused))
_sys_setpgid(pid_t pid,pid_t pgid)837 int _sys_setpgid(pid_t pid, pid_t pgid)
838 {
839 	return __nolibc_syscall2(__NR_setpgid, pid, pgid);
840 }
841 
842 static __attribute__((unused))
setpgid(pid_t pid,pid_t pgid)843 int 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 
852 static __attribute__((unused))
setpgrp(void)853 pid_t setpgrp(void)
854 {
855 	return setpgid(0, 0);
856 }
857 
858 
859 /*
860  * pid_t setsid(void);
861  */
862 
863 static __attribute__((unused))
_sys_setsid(void)864 pid_t _sys_setsid(void)
865 {
866 	return __nolibc_syscall0(__NR_setsid);
867 }
868 
869 static __attribute__((unused))
setsid(void)870 pid_t setsid(void)
871 {
872 	return __sysret(_sys_setsid());
873 }
874 
875 
876 /*
877  * int symlink(const char *old, const char *new);
878  */
879 
880 static __attribute__((unused))
_sys_symlink(const char * old,const char * new)881 int _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 
890 static __attribute__((unused))
symlink(const char * old,const char * new)891 int 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 
901 static __attribute__((unused))
_sys_umask(mode_t mode)902 mode_t _sys_umask(mode_t mode)
903 {
904 	return __nolibc_syscall1(__NR_umask, mode);
905 }
906 
907 static __attribute__((unused))
umask(mode_t mode)908 mode_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 
918 static __attribute__((unused))
_sys_umount2(const char * path,int flags)919 int _sys_umount2(const char *path, int flags)
920 {
921 	return __nolibc_syscall2(__NR_umount2, path, flags);
922 }
923 
924 static __attribute__((unused))
umount2(const char * path,int flags)925 int 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 
935 static __attribute__((unused))
_sys_unlink(const char * path)936 int _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 
945 static __attribute__((unused))
unlink(const char * path)946 int 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 
956 static __attribute__((unused))
_sys_write(int fd,const void * buf,size_t count)957 ssize_t _sys_write(int fd, const void *buf, size_t count)
958 {
959 	return __nolibc_syscall3(__NR_write, fd, buf, count);
960 }
961 
962 static __attribute__((unused))
write(int fd,const void * buf,size_t count)963 ssize_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 
973 static __attribute__((unused))
_sys_memfd_create(const char * name,unsigned int flags)974 int _sys_memfd_create(const char *name, unsigned int flags)
975 {
976 	return __nolibc_syscall2(__NR_memfd_create, name, flags);
977 }
978 
979 static __attribute__((unused))
memfd_create(const char * name,unsigned int flags)980 int memfd_create(const char *name, unsigned int flags)
981 {
982 	return __sysret(_sys_memfd_create(name, flags));
983 }
984 
985 #endif /* _NOLIBC_SYS_H */
986