brintos

brintos / linux-shallow public Read only

0
0
Text · 25.1 KiB · 7b82bc3 Raw
1265 lines · c
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#ifndef _NOLIBC_SYS_H8#define _NOLIBC_SYS_H9 10#include "std.h"11 12/* system includes */13#include <asm/unistd.h>14#include <asm/signal.h>  /* for SIGCHLD */15#include <asm/ioctls.h>16#include <asm/mman.h>17#include <linux/fs.h>18#include <linux/loop.h>19#include <linux/time.h>20#include <linux/auxvec.h>21#include <linux/fcntl.h> /* for O_* and AT_* */22#include <linux/stat.h>  /* for statx() */23#include <linux/prctl.h>24#include <linux/resource.h>25#include <linux/utsname.h>26 27#include "arch.h"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 an34 * error in it. This may only be used with signed returns (int or long), but35 * 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 is37 * 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 a49 * debugging hook.50 */51 52static __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 so60 * that the compiler usually decides to inline them while still being allowed61 * to pass a pointer to one of their instances. Each syscall exists in two62 * versions:63 *   - the "internal" ones, which matches the raw syscall interface at the64 *     kernel level, which may sometimes slightly differ from the documented65 *     libc-level ones. For example most of them return either a valid value66 *     or -errno. All of these are prefixed with "sys_". They may be called67 *     by non-portable applications if desired.68 *69 *   - the "exported" ones, whose interface must closely match the one70 *     documented in man(2), that applications are supposed to expect. These71 *     ones rely on the internal ones, and set errno.72 *73 * Each syscall will be defined with the two functions, sorted in alphabetical74 * order applied to the exported names.75 *76 * In case of doubt about the relevance of a function here, only those which77 * 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 87static __attribute__((unused))88void *sys_brk(void *addr)89{90	return (void *)my_syscall1(__NR_brk, addr);91}92 93static __attribute__((unused))94int 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 105static __attribute__((unused))106void *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 123static __attribute__((unused))124int sys_chdir(const char *path)125{126	return my_syscall1(__NR_chdir, path);127}128 129static __attribute__((unused))130int 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 140static __attribute__((unused))141int sys_chmod(const char *path, mode_t mode)142{143#ifdef __NR_fchmodat144	return my_syscall4(__NR_fchmodat, AT_FDCWD, path, mode, 0);145#elif defined(__NR_chmod)146	return my_syscall2(__NR_chmod, path, mode);147#else148	return __nolibc_enosys(__func__, path, mode);149#endif150}151 152static __attribute__((unused))153int 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 163static __attribute__((unused))164int sys_chown(const char *path, uid_t owner, gid_t group)165{166#ifdef __NR_fchownat167	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#else171	return __nolibc_enosys(__func__, path, owner, group);172#endif173}174 175static __attribute__((unused))176int 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 186static __attribute__((unused))187int sys_chroot(const char *path)188{189	return my_syscall1(__NR_chroot, path);190}191 192static __attribute__((unused))193int chroot(const char *path)194{195	return __sysret(sys_chroot(path));196}197 198 199/*200 * int close(int fd);201 */202 203static __attribute__((unused))204int sys_close(int fd)205{206	return my_syscall1(__NR_close, fd);207}208 209static __attribute__((unused))210int close(int fd)211{212	return __sysret(sys_close(fd));213}214 215 216/*217 * int dup(int fd);218 */219 220static __attribute__((unused))221int sys_dup(int fd)222{223	return my_syscall1(__NR_dup, fd);224}225 226static __attribute__((unused))227int dup(int fd)228{229	return __sysret(sys_dup(fd));230}231 232 233/*234 * int dup2(int old, int new);235 */236 237static __attribute__((unused))238int sys_dup2(int old, int new)239{240#ifdef __NR_dup3241	return my_syscall3(__NR_dup3, old, new, 0);242#elif defined(__NR_dup2)243	return my_syscall2(__NR_dup2, old, new);244#else245	return __nolibc_enosys(__func__, old, new);246#endif247}248 249static __attribute__((unused))250int 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#ifdef __NR_dup3261static __attribute__((unused))262int sys_dup3(int old, int new, int flags)263{264	return my_syscall3(__NR_dup3, old, new, flags);265}266 267static __attribute__((unused))268int dup3(int old, int new, int flags)269{270	return __sysret(sys_dup3(old, new, flags));271}272#endif273 274 275/*276 * int execve(const char *filename, char *const argv[], char *const envp[]);277 */278 279static __attribute__((unused))280int sys_execve(const char *filename, char *const argv[], char *const envp[])281{282	return my_syscall3(__NR_execve, filename, argv, envp);283}284 285static __attribute__((unused))286int 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 296static __attribute__((noreturn,unused))297void sys_exit(int status)298{299	my_syscall1(__NR_exit, status & 255);300	while(1); /* shut the "noreturn" warnings. */301}302 303static __attribute__((noreturn,unused))304void exit(int status)305{306	sys_exit(status);307}308 309 310/*311 * pid_t fork(void);312 */313 314#ifndef sys_fork315static __attribute__((unused))316pid_t sys_fork(void)317{318#ifdef __NR_clone319	/* note: some archs only have clone() and not fork(). Different archs320	 * have a different API, but most archs have the flags on first arg and321	 * will not use the rest with no other flag.322	 */323	return my_syscall5(__NR_clone, SIGCHLD, 0, 0, 0, 0);324#elif defined(__NR_fork)325	return my_syscall0(__NR_fork);326#else327	return __nolibc_enosys(__func__);328#endif329}330#endif331 332static __attribute__((unused))333pid_t fork(void)334{335	return __sysret(sys_fork());336}337 338 339/*340 * int fsync(int fd);341 */342 343static __attribute__((unused))344int sys_fsync(int fd)345{346	return my_syscall1(__NR_fsync, fd);347}348 349static __attribute__((unused))350int fsync(int fd)351{352	return __sysret(sys_fsync(fd));353}354 355 356/*357 * int getdents64(int fd, struct linux_dirent64 *dirp, int count);358 */359 360static __attribute__((unused))361int sys_getdents64(int fd, struct linux_dirent64 *dirp, int count)362{363	return my_syscall3(__NR_getdents64, fd, dirp, count);364}365 366static __attribute__((unused))367int getdents64(int fd, struct linux_dirent64 *dirp, int count)368{369	return __sysret(sys_getdents64(fd, dirp, count));370}371 372 373/*374 * uid_t geteuid(void);375 */376 377static __attribute__((unused))378uid_t sys_geteuid(void)379{380#ifdef __NR_geteuid32381	return my_syscall0(__NR_geteuid32);382#else383	return my_syscall0(__NR_geteuid);384#endif385}386 387static __attribute__((unused))388uid_t geteuid(void)389{390	return sys_geteuid();391}392 393 394/*395 * pid_t getpgid(pid_t pid);396 */397 398static __attribute__((unused))399pid_t sys_getpgid(pid_t pid)400{401	return my_syscall1(__NR_getpgid, pid);402}403 404static __attribute__((unused))405pid_t getpgid(pid_t pid)406{407	return __sysret(sys_getpgid(pid));408}409 410 411/*412 * pid_t getpgrp(void);413 */414 415static __attribute__((unused))416pid_t sys_getpgrp(void)417{418	return sys_getpgid(0);419}420 421static __attribute__((unused))422pid_t getpgrp(void)423{424	return sys_getpgrp();425}426 427 428/*429 * pid_t getpid(void);430 */431 432static __attribute__((unused))433pid_t sys_getpid(void)434{435	return my_syscall0(__NR_getpid);436}437 438static __attribute__((unused))439pid_t getpid(void)440{441	return sys_getpid();442}443 444 445/*446 * pid_t getppid(void);447 */448 449static __attribute__((unused))450pid_t sys_getppid(void)451{452	return my_syscall0(__NR_getppid);453}454 455static __attribute__((unused))456pid_t getppid(void)457{458	return sys_getppid();459}460 461 462/*463 * pid_t gettid(void);464 */465 466static __attribute__((unused))467pid_t sys_gettid(void)468{469	return my_syscall0(__NR_gettid);470}471 472static __attribute__((unused))473pid_t gettid(void)474{475	return sys_gettid();476}477 478static unsigned long getauxval(unsigned long key);479 480/*481 * int getpagesize(void);482 */483 484static __attribute__((unused))485int getpagesize(void)486{487	return __sysret((int)getauxval(AT_PAGESZ) ?: -ENOENT);488}489 490 491/*492 * int gettimeofday(struct timeval *tv, struct timezone *tz);493 */494 495static __attribute__((unused))496int sys_gettimeofday(struct timeval *tv, struct timezone *tz)497{498#ifdef __NR_gettimeofday499	return my_syscall2(__NR_gettimeofday, tv, tz);500#else501	return __nolibc_enosys(__func__, tv, tz);502#endif503}504 505static __attribute__((unused))506int gettimeofday(struct timeval *tv, struct timezone *tz)507{508	return __sysret(sys_gettimeofday(tv, tz));509}510 511 512/*513 * uid_t getuid(void);514 */515 516static __attribute__((unused))517uid_t sys_getuid(void)518{519#ifdef __NR_getuid32520	return my_syscall0(__NR_getuid32);521#else522	return my_syscall0(__NR_getuid);523#endif524}525 526static __attribute__((unused))527uid_t getuid(void)528{529	return sys_getuid();530}531 532 533/*534 * int ioctl(int fd, unsigned long req, void *value);535 */536 537static __attribute__((unused))538int sys_ioctl(int fd, unsigned long req, void *value)539{540	return my_syscall3(__NR_ioctl, fd, req, value);541}542 543static __attribute__((unused))544int ioctl(int fd, unsigned long req, void *value)545{546	return __sysret(sys_ioctl(fd, req, value));547}548 549/*550 * int kill(pid_t pid, int signal);551 */552 553static __attribute__((unused))554int sys_kill(pid_t pid, int signal)555{556	return my_syscall2(__NR_kill, pid, signal);557}558 559static __attribute__((unused))560int 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 570static __attribute__((unused))571int sys_link(const char *old, const char *new)572{573#ifdef __NR_linkat574	return my_syscall5(__NR_linkat, AT_FDCWD, old, AT_FDCWD, new, 0);575#elif defined(__NR_link)576	return my_syscall2(__NR_link, old, new);577#else578	return __nolibc_enosys(__func__, old, new);579#endif580}581 582static __attribute__((unused))583int link(const char *old, const char *new)584{585	return __sysret(sys_link(old, new));586}587 588 589/*590 * off_t lseek(int fd, off_t offset, int whence);591 */592 593static __attribute__((unused))594off_t sys_lseek(int fd, off_t offset, int whence)595{596#ifdef __NR_lseek597	return my_syscall3(__NR_lseek, fd, offset, whence);598#else599	return __nolibc_enosys(__func__, fd, offset, whence);600#endif601}602 603static __attribute__((unused))604off_t lseek(int fd, off_t offset, int whence)605{606	return __sysret(sys_lseek(fd, offset, whence));607}608 609 610/*611 * int mkdir(const char *path, mode_t mode);612 */613 614static __attribute__((unused))615int sys_mkdir(const char *path, mode_t mode)616{617#ifdef __NR_mkdirat618	return my_syscall3(__NR_mkdirat, AT_FDCWD, path, mode);619#elif defined(__NR_mkdir)620	return my_syscall2(__NR_mkdir, path, mode);621#else622	return __nolibc_enosys(__func__, path, mode);623#endif624}625 626static __attribute__((unused))627int mkdir(const char *path, mode_t mode)628{629	return __sysret(sys_mkdir(path, mode));630}631 632/*633 * int rmdir(const char *path);634 */635 636static __attribute__((unused))637int sys_rmdir(const char *path)638{639#ifdef __NR_rmdir640	return my_syscall1(__NR_rmdir, path);641#elif defined(__NR_unlinkat)642	return my_syscall3(__NR_unlinkat, AT_FDCWD, path, AT_REMOVEDIR);643#else644	return __nolibc_enosys(__func__, path);645#endif646}647 648static __attribute__((unused))649int rmdir(const char *path)650{651	return __sysret(sys_rmdir(path));652}653 654 655/*656 * int mknod(const char *path, mode_t mode, dev_t dev);657 */658 659static __attribute__((unused))660long sys_mknod(const char *path, mode_t mode, dev_t dev)661{662#ifdef __NR_mknodat663	return my_syscall4(__NR_mknodat, AT_FDCWD, path, mode, dev);664#elif defined(__NR_mknod)665	return my_syscall3(__NR_mknod, path, mode, dev);666#else667	return __nolibc_enosys(__func__, path, mode, dev);668#endif669}670 671static __attribute__((unused))672int mknod(const char *path, mode_t mode, dev_t dev)673{674	return __sysret(sys_mknod(path, mode, dev));675}676 677#ifndef sys_mmap678static __attribute__((unused))679void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd,680	       off_t offset)681{682	int n;683 684#if defined(__NR_mmap2)685	n = __NR_mmap2;686	offset >>= 12;687#else688	n = __NR_mmap;689#endif690 691	return (void *)my_syscall6(n, addr, length, prot, flags, fd, offset);692}693#endif694 695/* Note that on Linux, MAP_FAILED is -1 so we can use the generic __sysret()696 * which returns -1 upon error and still satisfy user land that checks for697 * MAP_FAILED.698 */699 700static __attribute__((unused))701void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)702{703	void *ret = sys_mmap(addr, length, prot, flags, fd, offset);704 705	if ((unsigned long)ret >= -4095UL) {706		SET_ERRNO(-(long)ret);707		ret = MAP_FAILED;708	}709	return ret;710}711 712static __attribute__((unused))713int sys_munmap(void *addr, size_t length)714{715	return my_syscall2(__NR_munmap, addr, length);716}717 718static __attribute__((unused))719int munmap(void *addr, size_t length)720{721	return __sysret(sys_munmap(addr, length));722}723 724/*725 * int mount(const char *source, const char *target,726 *           const char *fstype, unsigned long flags,727 *           const void *data);728 */729static __attribute__((unused))730int sys_mount(const char *src, const char *tgt, const char *fst,731                     unsigned long flags, const void *data)732{733	return my_syscall5(__NR_mount, src, tgt, fst, flags, data);734}735 736static __attribute__((unused))737int mount(const char *src, const char *tgt,738          const char *fst, unsigned long flags,739          const void *data)740{741	return __sysret(sys_mount(src, tgt, fst, flags, data));742}743 744 745/*746 * int open(const char *path, int flags[, mode_t mode]);747 */748 749static __attribute__((unused))750int sys_open(const char *path, int flags, mode_t mode)751{752#ifdef __NR_openat753	return my_syscall4(__NR_openat, AT_FDCWD, path, flags, mode);754#elif defined(__NR_open)755	return my_syscall3(__NR_open, path, flags, mode);756#else757	return __nolibc_enosys(__func__, path, flags, mode);758#endif759}760 761static __attribute__((unused))762int open(const char *path, int flags, ...)763{764	mode_t mode = 0;765 766	if (flags & O_CREAT) {767		va_list args;768 769		va_start(args, flags);770		mode = va_arg(args, int);771		va_end(args);772	}773 774	return __sysret(sys_open(path, flags, mode));775}776 777 778/*779 * int pipe2(int pipefd[2], int flags);780 * int pipe(int pipefd[2]);781 */782 783static __attribute__((unused))784int sys_pipe2(int pipefd[2], int flags)785{786	return my_syscall2(__NR_pipe2, pipefd, flags);787}788 789static __attribute__((unused))790int pipe2(int pipefd[2], int flags)791{792	return __sysret(sys_pipe2(pipefd, flags));793}794 795static __attribute__((unused))796int pipe(int pipefd[2])797{798	return pipe2(pipefd, 0);799}800 801 802/*803 * int prctl(int option, unsigned long arg2, unsigned long arg3,804 *                       unsigned long arg4, unsigned long arg5);805 */806 807static __attribute__((unused))808int sys_prctl(int option, unsigned long arg2, unsigned long arg3,809		          unsigned long arg4, unsigned long arg5)810{811	return my_syscall5(__NR_prctl, option, arg2, arg3, arg4, arg5);812}813 814static __attribute__((unused))815int prctl(int option, unsigned long arg2, unsigned long arg3,816		      unsigned long arg4, unsigned long arg5)817{818	return __sysret(sys_prctl(option, arg2, arg3, arg4, arg5));819}820 821 822/*823 * int pivot_root(const char *new, const char *old);824 */825 826static __attribute__((unused))827int sys_pivot_root(const char *new, const char *old)828{829	return my_syscall2(__NR_pivot_root, new, old);830}831 832static __attribute__((unused))833int pivot_root(const char *new, const char *old)834{835	return __sysret(sys_pivot_root(new, old));836}837 838 839/*840 * int poll(struct pollfd *fds, int nfds, int timeout);841 */842 843static __attribute__((unused))844int sys_poll(struct pollfd *fds, int nfds, int timeout)845{846#if defined(__NR_ppoll)847	struct timespec t;848 849	if (timeout >= 0) {850		t.tv_sec  = timeout / 1000;851		t.tv_nsec = (timeout % 1000) * 1000000;852	}853	return my_syscall5(__NR_ppoll, fds, nfds, (timeout >= 0) ? &t : NULL, NULL, 0);854#elif defined(__NR_poll)855	return my_syscall3(__NR_poll, fds, nfds, timeout);856#else857	return __nolibc_enosys(__func__, fds, nfds, timeout);858#endif859}860 861static __attribute__((unused))862int poll(struct pollfd *fds, int nfds, int timeout)863{864	return __sysret(sys_poll(fds, nfds, timeout));865}866 867 868/*869 * ssize_t read(int fd, void *buf, size_t count);870 */871 872static __attribute__((unused))873ssize_t sys_read(int fd, void *buf, size_t count)874{875	return my_syscall3(__NR_read, fd, buf, count);876}877 878static __attribute__((unused))879ssize_t read(int fd, void *buf, size_t count)880{881	return __sysret(sys_read(fd, buf, count));882}883 884 885/*886 * int reboot(int cmd);887 * <cmd> is among LINUX_REBOOT_CMD_*888 */889 890static __attribute__((unused))891ssize_t sys_reboot(int magic1, int magic2, int cmd, void *arg)892{893	return my_syscall4(__NR_reboot, magic1, magic2, cmd, arg);894}895 896static __attribute__((unused))897int reboot(int cmd)898{899	return __sysret(sys_reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, 0));900}901 902 903/*904 * int getrlimit(int resource, struct rlimit *rlim);905 * int setrlimit(int resource, const struct rlimit *rlim);906 */907 908static __attribute__((unused))909int sys_prlimit64(pid_t pid, int resource,910		  const struct rlimit64 *new_limit, struct rlimit64 *old_limit)911{912	return my_syscall4(__NR_prlimit64, pid, resource, new_limit, old_limit);913}914 915static __attribute__((unused))916int getrlimit(int resource, struct rlimit *rlim)917{918	struct rlimit64 rlim64;919	int ret;920 921	ret = __sysret(sys_prlimit64(0, resource, NULL, &rlim64));922	rlim->rlim_cur = rlim64.rlim_cur;923	rlim->rlim_max = rlim64.rlim_max;924 925	return ret;926}927 928static __attribute__((unused))929int setrlimit(int resource, const struct rlimit *rlim)930{931	struct rlimit64 rlim64 = {932		.rlim_cur = rlim->rlim_cur,933		.rlim_max = rlim->rlim_max,934	};935 936	return __sysret(sys_prlimit64(0, resource, &rlim64, NULL));937}938 939 940/*941 * int sched_yield(void);942 */943 944static __attribute__((unused))945int sys_sched_yield(void)946{947	return my_syscall0(__NR_sched_yield);948}949 950static __attribute__((unused))951int sched_yield(void)952{953	return __sysret(sys_sched_yield());954}955 956 957/*958 * int select(int nfds, fd_set *read_fds, fd_set *write_fds,959 *            fd_set *except_fds, struct timeval *timeout);960 */961 962static __attribute__((unused))963int sys_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout)964{965#if defined(__ARCH_WANT_SYS_OLD_SELECT) && !defined(__NR__newselect)966	struct sel_arg_struct {967		unsigned long n;968		fd_set *r, *w, *e;969		struct timeval *t;970	} arg = { .n = nfds, .r = rfds, .w = wfds, .e = efds, .t = timeout };971	return my_syscall1(__NR_select, &arg);972#elif defined(__NR__newselect)973	return my_syscall5(__NR__newselect, nfds, rfds, wfds, efds, timeout);974#elif defined(__NR_select)975	return my_syscall5(__NR_select, nfds, rfds, wfds, efds, timeout);976#elif defined(__NR_pselect6)977	struct timespec t;978 979	if (timeout) {980		t.tv_sec  = timeout->tv_sec;981		t.tv_nsec = timeout->tv_usec * 1000;982	}983	return my_syscall6(__NR_pselect6, nfds, rfds, wfds, efds, timeout ? &t : NULL, NULL);984#else985	return __nolibc_enosys(__func__, nfds, rfds, wfds, efds, timeout);986#endif987}988 989static __attribute__((unused))990int select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout)991{992	return __sysret(sys_select(nfds, rfds, wfds, efds, timeout));993}994 995 996/*997 * int setpgid(pid_t pid, pid_t pgid);998 */999 1000static __attribute__((unused))1001int sys_setpgid(pid_t pid, pid_t pgid)1002{1003	return my_syscall2(__NR_setpgid, pid, pgid);1004}1005 1006static __attribute__((unused))1007int setpgid(pid_t pid, pid_t pgid)1008{1009	return __sysret(sys_setpgid(pid, pgid));1010}1011 1012 1013/*1014 * pid_t setsid(void);1015 */1016 1017static __attribute__((unused))1018pid_t sys_setsid(void)1019{1020	return my_syscall0(__NR_setsid);1021}1022 1023static __attribute__((unused))1024pid_t setsid(void)1025{1026	return __sysret(sys_setsid());1027}1028 1029/*1030 * int statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf);1031 * int stat(const char *path, struct stat *buf);1032 */1033 1034static __attribute__((unused))1035int sys_statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf)1036{1037#ifdef __NR_statx1038	return my_syscall5(__NR_statx, fd, path, flags, mask, buf);1039#else1040	return __nolibc_enosys(__func__, fd, path, flags, mask, buf);1041#endif1042}1043 1044static __attribute__((unused))1045int statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf)1046{1047	return __sysret(sys_statx(fd, path, flags, mask, buf));1048}1049 1050 1051static __attribute__((unused))1052int stat(const char *path, struct stat *buf)1053{1054	struct statx statx;1055	long ret;1056 1057	ret = __sysret(sys_statx(AT_FDCWD, path, AT_NO_AUTOMOUNT, STATX_BASIC_STATS, &statx));1058	if (ret == -1)1059		return ret;1060 1061	buf->st_dev          = ((statx.stx_dev_minor & 0xff)1062			       | (statx.stx_dev_major << 8)1063			       | ((statx.stx_dev_minor & ~0xff) << 12));1064	buf->st_ino          = statx.stx_ino;1065	buf->st_mode         = statx.stx_mode;1066	buf->st_nlink        = statx.stx_nlink;1067	buf->st_uid          = statx.stx_uid;1068	buf->st_gid          = statx.stx_gid;1069	buf->st_rdev         = ((statx.stx_rdev_minor & 0xff)1070			       | (statx.stx_rdev_major << 8)1071			       | ((statx.stx_rdev_minor & ~0xff) << 12));1072	buf->st_size         = statx.stx_size;1073	buf->st_blksize      = statx.stx_blksize;1074	buf->st_blocks       = statx.stx_blocks;1075	buf->st_atim.tv_sec  = statx.stx_atime.tv_sec;1076	buf->st_atim.tv_nsec = statx.stx_atime.tv_nsec;1077	buf->st_mtim.tv_sec  = statx.stx_mtime.tv_sec;1078	buf->st_mtim.tv_nsec = statx.stx_mtime.tv_nsec;1079	buf->st_ctim.tv_sec  = statx.stx_ctime.tv_sec;1080	buf->st_ctim.tv_nsec = statx.stx_ctime.tv_nsec;1081 1082	return 0;1083}1084 1085 1086/*1087 * int symlink(const char *old, const char *new);1088 */1089 1090static __attribute__((unused))1091int sys_symlink(const char *old, const char *new)1092{1093#ifdef __NR_symlinkat1094	return my_syscall3(__NR_symlinkat, old, AT_FDCWD, new);1095#elif defined(__NR_symlink)1096	return my_syscall2(__NR_symlink, old, new);1097#else1098	return __nolibc_enosys(__func__, old, new);1099#endif1100}1101 1102static __attribute__((unused))1103int symlink(const char *old, const char *new)1104{1105	return __sysret(sys_symlink(old, new));1106}1107 1108 1109/*1110 * mode_t umask(mode_t mode);1111 */1112 1113static __attribute__((unused))1114mode_t sys_umask(mode_t mode)1115{1116	return my_syscall1(__NR_umask, mode);1117}1118 1119static __attribute__((unused))1120mode_t umask(mode_t mode)1121{1122	return sys_umask(mode);1123}1124 1125 1126/*1127 * int umount2(const char *path, int flags);1128 */1129 1130static __attribute__((unused))1131int sys_umount2(const char *path, int flags)1132{1133	return my_syscall2(__NR_umount2, path, flags);1134}1135 1136static __attribute__((unused))1137int umount2(const char *path, int flags)1138{1139	return __sysret(sys_umount2(path, flags));1140}1141 1142 1143/*1144 * int uname(struct utsname *buf);1145 */1146 1147struct utsname {1148	char sysname[65];1149	char nodename[65];1150	char release[65];1151	char version[65];1152	char machine[65];1153	char domainname[65];1154};1155 1156static __attribute__((unused))1157int sys_uname(struct utsname *buf)1158{1159	return my_syscall1(__NR_uname, buf);1160}1161 1162static __attribute__((unused))1163int uname(struct utsname *buf)1164{1165	return __sysret(sys_uname(buf));1166}1167 1168 1169/*1170 * int unlink(const char *path);1171 */1172 1173static __attribute__((unused))1174int sys_unlink(const char *path)1175{1176#ifdef __NR_unlinkat1177	return my_syscall3(__NR_unlinkat, AT_FDCWD, path, 0);1178#elif defined(__NR_unlink)1179	return my_syscall1(__NR_unlink, path);1180#else1181	return __nolibc_enosys(__func__, path);1182#endif1183}1184 1185static __attribute__((unused))1186int unlink(const char *path)1187{1188	return __sysret(sys_unlink(path));1189}1190 1191 1192/*1193 * pid_t wait(int *status);1194 * pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage);1195 * pid_t waitpid(pid_t pid, int *status, int options);1196 */1197 1198static __attribute__((unused))1199pid_t sys_wait4(pid_t pid, int *status, int options, struct rusage *rusage)1200{1201#ifdef __NR_wait41202	return my_syscall4(__NR_wait4, pid, status, options, rusage);1203#else1204	return __nolibc_enosys(__func__, pid, status, options, rusage);1205#endif1206}1207 1208static __attribute__((unused))1209pid_t wait(int *status)1210{1211	return __sysret(sys_wait4(-1, status, 0, NULL));1212}1213 1214static __attribute__((unused))1215pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage)1216{1217	return __sysret(sys_wait4(pid, status, options, rusage));1218}1219 1220 1221static __attribute__((unused))1222pid_t waitpid(pid_t pid, int *status, int options)1223{1224	return __sysret(sys_wait4(pid, status, options, NULL));1225}1226 1227 1228/*1229 * ssize_t write(int fd, const void *buf, size_t count);1230 */1231 1232static __attribute__((unused))1233ssize_t sys_write(int fd, const void *buf, size_t count)1234{1235	return my_syscall3(__NR_write, fd, buf, count);1236}1237 1238static __attribute__((unused))1239ssize_t write(int fd, const void *buf, size_t count)1240{1241	return __sysret(sys_write(fd, buf, count));1242}1243 1244 1245/*1246 * int memfd_create(const char *name, unsigned int flags);1247 */1248 1249static __attribute__((unused))1250int sys_memfd_create(const char *name, unsigned int flags)1251{1252	return my_syscall2(__NR_memfd_create, name, flags);1253}1254 1255static __attribute__((unused))1256int memfd_create(const char *name, unsigned int flags)1257{1258	return __sysret(sys_memfd_create(name, flags));1259}1260 1261/* make sure to include all global symbols */1262#include "nolibc.h"1263 1264#endif /* _NOLIBC_SYS_H */1265