diff options
Diffstat (limited to 'tools/include/nolibc/sys.h')
| -rw-r--r-- | tools/include/nolibc/sys.h | 1247 | 
1 files changed, 1247 insertions, 0 deletions
diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h new file mode 100644 index 000000000000..08491070387b --- /dev/null +++ b/tools/include/nolibc/sys.h @@ -0,0 +1,1247 @@ +/* SPDX-License-Identifier: LGPL-2.1 OR MIT */ +/* + * Syscall definitions for NOLIBC (those in man(2)) + * Copyright (C) 2017-2021 Willy Tarreau <w@1wt.eu> + */ + +#ifndef _NOLIBC_SYS_H +#define _NOLIBC_SYS_H + +#include <stdarg.h> +#include "std.h" + +/* system includes */ +#include <asm/unistd.h> +#include <asm/signal.h>  // for SIGCHLD +#include <asm/ioctls.h> +#include <asm/mman.h> +#include <linux/fs.h> +#include <linux/loop.h> +#include <linux/time.h> + +#include "arch.h" +#include "errno.h" +#include "types.h" + + +/* Functions in this file only describe syscalls. They're declared static so + * that the compiler usually decides to inline them while still being allowed + * to pass a pointer to one of their instances. Each syscall exists in two + * versions: + *   - the "internal" ones, which matches the raw syscall interface at the + *     kernel level, which may sometimes slightly differ from the documented + *     libc-level ones. For example most of them return either a valid value + *     or -errno. All of these are prefixed with "sys_". They may be called + *     by non-portable applications if desired. + * + *   - the "exported" ones, whose interface must closely match the one + *     documented in man(2), that applications are supposed to expect. These + *     ones rely on the internal ones, and set errno. + * + * Each syscall will be defined with the two functions, sorted in alphabetical + * order applied to the exported names. + * + * In case of doubt about the relevance of a function here, only those which + * set errno should be defined here. Wrappers like those appearing in man(3) + * should not be placed here. + */ + + +/* + * int brk(void *addr); + * void *sbrk(intptr_t inc) + */ + +static __attribute__((unused)) +void *sys_brk(void *addr) +{ +	return (void *)my_syscall1(__NR_brk, addr); +} + +static __attribute__((unused)) +int brk(void *addr) +{ +	void *ret = sys_brk(addr); + +	if (!ret) { +		SET_ERRNO(ENOMEM); +		return -1; +	} +	return 0; +} + +static __attribute__((unused)) +void *sbrk(intptr_t inc) +{ +	void *ret; + +	/* first call to find current end */ +	if ((ret = sys_brk(0)) && (sys_brk(ret + inc) == ret + inc)) +		return ret + inc; + +	SET_ERRNO(ENOMEM); +	return (void *)-1; +} + + +/* + * int chdir(const char *path); + */ + +static __attribute__((unused)) +int sys_chdir(const char *path) +{ +	return my_syscall1(__NR_chdir, path); +} + +static __attribute__((unused)) +int chdir(const char *path) +{ +	int ret = sys_chdir(path); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * int chmod(const char *path, mode_t mode); + */ + +static __attribute__((unused)) +int sys_chmod(const char *path, mode_t mode) +{ +#ifdef __NR_fchmodat +	return my_syscall4(__NR_fchmodat, AT_FDCWD, path, mode, 0); +#elif defined(__NR_chmod) +	return my_syscall2(__NR_chmod, path, mode); +#else +#error Neither __NR_fchmodat nor __NR_chmod defined, cannot implement sys_chmod() +#endif +} + +static __attribute__((unused)) +int chmod(const char *path, mode_t mode) +{ +	int ret = sys_chmod(path, mode); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * int chown(const char *path, uid_t owner, gid_t group); + */ + +static __attribute__((unused)) +int sys_chown(const char *path, uid_t owner, gid_t group) +{ +#ifdef __NR_fchownat +	return my_syscall5(__NR_fchownat, AT_FDCWD, path, owner, group, 0); +#elif defined(__NR_chown) +	return my_syscall3(__NR_chown, path, owner, group); +#else +#error Neither __NR_fchownat nor __NR_chown defined, cannot implement sys_chown() +#endif +} + +static __attribute__((unused)) +int chown(const char *path, uid_t owner, gid_t group) +{ +	int ret = sys_chown(path, owner, group); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * int chroot(const char *path); + */ + +static __attribute__((unused)) +int sys_chroot(const char *path) +{ +	return my_syscall1(__NR_chroot, path); +} + +static __attribute__((unused)) +int chroot(const char *path) +{ +	int ret = sys_chroot(path); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * int close(int fd); + */ + +static __attribute__((unused)) +int sys_close(int fd) +{ +	return my_syscall1(__NR_close, fd); +} + +static __attribute__((unused)) +int close(int fd) +{ +	int ret = sys_close(fd); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * int dup(int fd); + */ + +static __attribute__((unused)) +int sys_dup(int fd) +{ +	return my_syscall1(__NR_dup, fd); +} + +static __attribute__((unused)) +int dup(int fd) +{ +	int ret = sys_dup(fd); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * int dup2(int old, int new); + */ + +static __attribute__((unused)) +int sys_dup2(int old, int new) +{ +#ifdef __NR_dup3 +	return my_syscall3(__NR_dup3, old, new, 0); +#elif defined(__NR_dup2) +	return my_syscall2(__NR_dup2, old, new); +#else +#error Neither __NR_dup3 nor __NR_dup2 defined, cannot implement sys_dup2() +#endif +} + +static __attribute__((unused)) +int dup2(int old, int new) +{ +	int ret = sys_dup2(old, new); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * int dup3(int old, int new, int flags); + */ + +#ifdef __NR_dup3 +static __attribute__((unused)) +int sys_dup3(int old, int new, int flags) +{ +	return my_syscall3(__NR_dup3, old, new, flags); +} + +static __attribute__((unused)) +int dup3(int old, int new, int flags) +{ +	int ret = sys_dup3(old, new, flags); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} +#endif + + +/* + * int execve(const char *filename, char *const argv[], char *const envp[]); + */ + +static __attribute__((unused)) +int sys_execve(const char *filename, char *const argv[], char *const envp[]) +{ +	return my_syscall3(__NR_execve, filename, argv, envp); +} + +static __attribute__((unused)) +int execve(const char *filename, char *const argv[], char *const envp[]) +{ +	int ret = sys_execve(filename, argv, envp); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * void exit(int status); + */ + +static __attribute__((noreturn,unused)) +void sys_exit(int status) +{ +	my_syscall1(__NR_exit, status & 255); +	while(1); // shut the "noreturn" warnings. +} + +static __attribute__((noreturn,unused)) +void exit(int status) +{ +	sys_exit(status); +} + + +/* + * pid_t fork(void); + */ + +static __attribute__((unused)) +pid_t sys_fork(void) +{ +#ifdef __NR_clone +	/* note: some archs only have clone() and not fork(). Different archs +	 * have a different API, but most archs have the flags on first arg and +	 * will not use the rest with no other flag. +	 */ +	return my_syscall5(__NR_clone, SIGCHLD, 0, 0, 0, 0); +#elif defined(__NR_fork) +	return my_syscall0(__NR_fork); +#else +#error Neither __NR_clone nor __NR_fork defined, cannot implement sys_fork() +#endif +} + +static __attribute__((unused)) +pid_t fork(void) +{ +	pid_t ret = sys_fork(); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * int fsync(int fd); + */ + +static __attribute__((unused)) +int sys_fsync(int fd) +{ +	return my_syscall1(__NR_fsync, fd); +} + +static __attribute__((unused)) +int fsync(int fd) +{ +	int ret = sys_fsync(fd); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * int getdents64(int fd, struct linux_dirent64 *dirp, int count); + */ + +static __attribute__((unused)) +int sys_getdents64(int fd, struct linux_dirent64 *dirp, int count) +{ +	return my_syscall3(__NR_getdents64, fd, dirp, count); +} + +static __attribute__((unused)) +int getdents64(int fd, struct linux_dirent64 *dirp, int count) +{ +	int ret = sys_getdents64(fd, dirp, count); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * pid_t getpgid(pid_t pid); + */ + +static __attribute__((unused)) +pid_t sys_getpgid(pid_t pid) +{ +	return my_syscall1(__NR_getpgid, pid); +} + +static __attribute__((unused)) +pid_t getpgid(pid_t pid) +{ +	pid_t ret = sys_getpgid(pid); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * pid_t getpgrp(void); + */ + +static __attribute__((unused)) +pid_t sys_getpgrp(void) +{ +	return sys_getpgid(0); +} + +static __attribute__((unused)) +pid_t getpgrp(void) +{ +	return sys_getpgrp(); +} + + +/* + * pid_t getpid(void); + */ + +static __attribute__((unused)) +pid_t sys_getpid(void) +{ +	return my_syscall0(__NR_getpid); +} + +static __attribute__((unused)) +pid_t getpid(void) +{ +	return sys_getpid(); +} + + +/* + * pid_t getppid(void); + */ + +static __attribute__((unused)) +pid_t sys_getppid(void) +{ +	return my_syscall0(__NR_getppid); +} + +static __attribute__((unused)) +pid_t getppid(void) +{ +	return sys_getppid(); +} + + +/* + * pid_t gettid(void); + */ + +static __attribute__((unused)) +pid_t sys_gettid(void) +{ +	return my_syscall0(__NR_gettid); +} + +static __attribute__((unused)) +pid_t gettid(void) +{ +	return sys_gettid(); +} + + +/* + * int gettimeofday(struct timeval *tv, struct timezone *tz); + */ + +static __attribute__((unused)) +int sys_gettimeofday(struct timeval *tv, struct timezone *tz) +{ +	return my_syscall2(__NR_gettimeofday, tv, tz); +} + +static __attribute__((unused)) +int gettimeofday(struct timeval *tv, struct timezone *tz) +{ +	int ret = sys_gettimeofday(tv, tz); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * int ioctl(int fd, unsigned long req, void *value); + */ + +static __attribute__((unused)) +int sys_ioctl(int fd, unsigned long req, void *value) +{ +	return my_syscall3(__NR_ioctl, fd, req, value); +} + +static __attribute__((unused)) +int ioctl(int fd, unsigned long req, void *value) +{ +	int ret = sys_ioctl(fd, req, value); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + +/* + * int kill(pid_t pid, int signal); + */ + +static __attribute__((unused)) +int sys_kill(pid_t pid, int signal) +{ +	return my_syscall2(__NR_kill, pid, signal); +} + +static __attribute__((unused)) +int kill(pid_t pid, int signal) +{ +	int ret = sys_kill(pid, signal); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * int link(const char *old, const char *new); + */ + +static __attribute__((unused)) +int sys_link(const char *old, const char *new) +{ +#ifdef __NR_linkat +	return my_syscall5(__NR_linkat, AT_FDCWD, old, AT_FDCWD, new, 0); +#elif defined(__NR_link) +	return my_syscall2(__NR_link, old, new); +#else +#error Neither __NR_linkat nor __NR_link defined, cannot implement sys_link() +#endif +} + +static __attribute__((unused)) +int link(const char *old, const char *new) +{ +	int ret = sys_link(old, new); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * off_t lseek(int fd, off_t offset, int whence); + */ + +static __attribute__((unused)) +off_t sys_lseek(int fd, off_t offset, int whence) +{ +	return my_syscall3(__NR_lseek, fd, offset, whence); +} + +static __attribute__((unused)) +off_t lseek(int fd, off_t offset, int whence) +{ +	off_t ret = sys_lseek(fd, offset, whence); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * int mkdir(const char *path, mode_t mode); + */ + +static __attribute__((unused)) +int sys_mkdir(const char *path, mode_t mode) +{ +#ifdef __NR_mkdirat +	return my_syscall3(__NR_mkdirat, AT_FDCWD, path, mode); +#elif defined(__NR_mkdir) +	return my_syscall2(__NR_mkdir, path, mode); +#else +#error Neither __NR_mkdirat nor __NR_mkdir defined, cannot implement sys_mkdir() +#endif +} + +static __attribute__((unused)) +int mkdir(const char *path, mode_t mode) +{ +	int ret = sys_mkdir(path, mode); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * int mknod(const char *path, mode_t mode, dev_t dev); + */ + +static __attribute__((unused)) +long sys_mknod(const char *path, mode_t mode, dev_t dev) +{ +#ifdef __NR_mknodat +	return my_syscall4(__NR_mknodat, AT_FDCWD, path, mode, dev); +#elif defined(__NR_mknod) +	return my_syscall3(__NR_mknod, path, mode, dev); +#else +#error Neither __NR_mknodat nor __NR_mknod defined, cannot implement sys_mknod() +#endif +} + +static __attribute__((unused)) +int mknod(const char *path, mode_t mode, dev_t dev) +{ +	int ret = sys_mknod(path, mode, dev); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + +#ifndef MAP_SHARED +#define MAP_SHARED		0x01	/* Share changes */ +#define MAP_PRIVATE		0x02	/* Changes are private */ +#define MAP_SHARED_VALIDATE	0x03	/* share + validate extension flags */ +#endif + +#ifndef MAP_FAILED +#define MAP_FAILED ((void *)-1) +#endif + +static __attribute__((unused)) +void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd, +	       off_t offset) +{ +#ifndef my_syscall6 +	/* Function not implemented. */ +	return -ENOSYS; +#else + +	int n; + +#if defined(__i386__) +	n = __NR_mmap2; +	offset >>= 12; +#else +	n = __NR_mmap; +#endif + +	return (void *)my_syscall6(n, addr, length, prot, flags, fd, offset); +#endif +} + +static __attribute__((unused)) +void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) +{ +	void *ret = sys_mmap(addr, length, prot, flags, fd, offset); + +	if ((unsigned long)ret >= -4095UL) { +		SET_ERRNO(-(long)ret); +		ret = MAP_FAILED; +	} +	return ret; +} + +static __attribute__((unused)) +int sys_munmap(void *addr, size_t length) +{ +	return my_syscall2(__NR_munmap, addr, length); +} + +static __attribute__((unused)) +int munmap(void *addr, size_t length) +{ +	int ret = sys_munmap(addr, length); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + +/* + * int mount(const char *source, const char *target, + *           const char *fstype, unsigned long flags, + *           const void *data); + */ +static __attribute__((unused)) +int sys_mount(const char *src, const char *tgt, const char *fst, +                     unsigned long flags, const void *data) +{ +	return my_syscall5(__NR_mount, src, tgt, fst, flags, data); +} + +static __attribute__((unused)) +int mount(const char *src, const char *tgt, +          const char *fst, unsigned long flags, +          const void *data) +{ +	int ret = sys_mount(src, tgt, fst, flags, data); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * int open(const char *path, int flags[, mode_t mode]); + */ + +static __attribute__((unused)) +int sys_open(const char *path, int flags, mode_t mode) +{ +#ifdef __NR_openat +	return my_syscall4(__NR_openat, AT_FDCWD, path, flags, mode); +#elif defined(__NR_open) +	return my_syscall3(__NR_open, path, flags, mode); +#else +#error Neither __NR_openat nor __NR_open defined, cannot implement sys_open() +#endif +} + +static __attribute__((unused)) +int open(const char *path, int flags, ...) +{ +	mode_t mode = 0; +	int ret; + +	if (flags & O_CREAT) { +		va_list args; + +		va_start(args, flags); +		mode = va_arg(args, mode_t); +		va_end(args); +	} + +	ret = sys_open(path, flags, mode); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * int pivot_root(const char *new, const char *old); + */ + +static __attribute__((unused)) +int sys_pivot_root(const char *new, const char *old) +{ +	return my_syscall2(__NR_pivot_root, new, old); +} + +static __attribute__((unused)) +int pivot_root(const char *new, const char *old) +{ +	int ret = sys_pivot_root(new, old); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * int poll(struct pollfd *fds, int nfds, int timeout); + */ + +static __attribute__((unused)) +int sys_poll(struct pollfd *fds, int nfds, int timeout) +{ +#if defined(__NR_ppoll) +	struct timespec t; + +	if (timeout >= 0) { +		t.tv_sec  = timeout / 1000; +		t.tv_nsec = (timeout % 1000) * 1000000; +	} +	return my_syscall4(__NR_ppoll, fds, nfds, (timeout >= 0) ? &t : NULL, NULL); +#elif defined(__NR_poll) +	return my_syscall3(__NR_poll, fds, nfds, timeout); +#else +#error Neither __NR_ppoll nor __NR_poll defined, cannot implement sys_poll() +#endif +} + +static __attribute__((unused)) +int poll(struct pollfd *fds, int nfds, int timeout) +{ +	int ret = sys_poll(fds, nfds, timeout); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * ssize_t read(int fd, void *buf, size_t count); + */ + +static __attribute__((unused)) +ssize_t sys_read(int fd, void *buf, size_t count) +{ +	return my_syscall3(__NR_read, fd, buf, count); +} + +static __attribute__((unused)) +ssize_t read(int fd, void *buf, size_t count) +{ +	ssize_t ret = sys_read(fd, buf, count); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * int reboot(int cmd); + * <cmd> is among LINUX_REBOOT_CMD_* + */ + +static __attribute__((unused)) +ssize_t sys_reboot(int magic1, int magic2, int cmd, void *arg) +{ +	return my_syscall4(__NR_reboot, magic1, magic2, cmd, arg); +} + +static __attribute__((unused)) +int reboot(int cmd) +{ +	int ret = sys_reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, 0); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * int sched_yield(void); + */ + +static __attribute__((unused)) +int sys_sched_yield(void) +{ +	return my_syscall0(__NR_sched_yield); +} + +static __attribute__((unused)) +int sched_yield(void) +{ +	int ret = sys_sched_yield(); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * int select(int nfds, fd_set *read_fds, fd_set *write_fds, + *            fd_set *except_fds, struct timeval *timeout); + */ + +static __attribute__((unused)) +int sys_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout) +{ +#if defined(__ARCH_WANT_SYS_OLD_SELECT) && !defined(__NR__newselect) +	struct sel_arg_struct { +		unsigned long n; +		fd_set *r, *w, *e; +		struct timeval *t; +	} arg = { .n = nfds, .r = rfds, .w = wfds, .e = efds, .t = timeout }; +	return my_syscall1(__NR_select, &arg); +#elif defined(__ARCH_WANT_SYS_PSELECT6) && defined(__NR_pselect6) +	struct timespec t; + +	if (timeout) { +		t.tv_sec  = timeout->tv_sec; +		t.tv_nsec = timeout->tv_usec * 1000; +	} +	return my_syscall6(__NR_pselect6, nfds, rfds, wfds, efds, timeout ? &t : NULL, NULL); +#elif defined(__NR__newselect) || defined(__NR_select) +#ifndef __NR__newselect +#define __NR__newselect __NR_select +#endif +	return my_syscall5(__NR__newselect, nfds, rfds, wfds, efds, timeout); +#else +#error None of __NR_select, __NR_pselect6, nor __NR__newselect defined, cannot implement sys_select() +#endif +} + +static __attribute__((unused)) +int select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout) +{ +	int ret = sys_select(nfds, rfds, wfds, efds, timeout); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * int setpgid(pid_t pid, pid_t pgid); + */ + +static __attribute__((unused)) +int sys_setpgid(pid_t pid, pid_t pgid) +{ +	return my_syscall2(__NR_setpgid, pid, pgid); +} + +static __attribute__((unused)) +int setpgid(pid_t pid, pid_t pgid) +{ +	int ret = sys_setpgid(pid, pgid); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * pid_t setsid(void); + */ + +static __attribute__((unused)) +pid_t sys_setsid(void) +{ +	return my_syscall0(__NR_setsid); +} + +static __attribute__((unused)) +pid_t setsid(void) +{ +	pid_t ret = sys_setsid(); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * int stat(const char *path, struct stat *buf); + * Warning: the struct stat's layout is arch-dependent. + */ + +static __attribute__((unused)) +int sys_stat(const char *path, struct stat *buf) +{ +	struct sys_stat_struct stat; +	long ret; + +#ifdef __NR_newfstatat +	/* only solution for arm64 */ +	ret = my_syscall4(__NR_newfstatat, AT_FDCWD, path, &stat, 0); +#elif defined(__NR_stat) +	ret = my_syscall2(__NR_stat, path, &stat); +#else +#error Neither __NR_newfstatat nor __NR_stat defined, cannot implement sys_stat() +#endif +	buf->st_dev     = stat.st_dev; +	buf->st_ino     = stat.st_ino; +	buf->st_mode    = stat.st_mode; +	buf->st_nlink   = stat.st_nlink; +	buf->st_uid     = stat.st_uid; +	buf->st_gid     = stat.st_gid; +	buf->st_rdev    = stat.st_rdev; +	buf->st_size    = stat.st_size; +	buf->st_blksize = stat.st_blksize; +	buf->st_blocks  = stat.st_blocks; +	buf->st_atime   = stat.st_atime; +	buf->st_mtime   = stat.st_mtime; +	buf->st_ctime   = stat.st_ctime; +	return ret; +} + +static __attribute__((unused)) +int stat(const char *path, struct stat *buf) +{ +	int ret = sys_stat(path, buf); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * int symlink(const char *old, const char *new); + */ + +static __attribute__((unused)) +int sys_symlink(const char *old, const char *new) +{ +#ifdef __NR_symlinkat +	return my_syscall3(__NR_symlinkat, old, AT_FDCWD, new); +#elif defined(__NR_symlink) +	return my_syscall2(__NR_symlink, old, new); +#else +#error Neither __NR_symlinkat nor __NR_symlink defined, cannot implement sys_symlink() +#endif +} + +static __attribute__((unused)) +int symlink(const char *old, const char *new) +{ +	int ret = sys_symlink(old, new); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * mode_t umask(mode_t mode); + */ + +static __attribute__((unused)) +mode_t sys_umask(mode_t mode) +{ +	return my_syscall1(__NR_umask, mode); +} + +static __attribute__((unused)) +mode_t umask(mode_t mode) +{ +	return sys_umask(mode); +} + + +/* + * int umount2(const char *path, int flags); + */ + +static __attribute__((unused)) +int sys_umount2(const char *path, int flags) +{ +	return my_syscall2(__NR_umount2, path, flags); +} + +static __attribute__((unused)) +int umount2(const char *path, int flags) +{ +	int ret = sys_umount2(path, flags); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * int unlink(const char *path); + */ + +static __attribute__((unused)) +int sys_unlink(const char *path) +{ +#ifdef __NR_unlinkat +	return my_syscall3(__NR_unlinkat, AT_FDCWD, path, 0); +#elif defined(__NR_unlink) +	return my_syscall1(__NR_unlink, path); +#else +#error Neither __NR_unlinkat nor __NR_unlink defined, cannot implement sys_unlink() +#endif +} + +static __attribute__((unused)) +int unlink(const char *path) +{ +	int ret = sys_unlink(path); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * pid_t wait(int *status); + * pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage); + * pid_t waitpid(pid_t pid, int *status, int options); + */ + +static __attribute__((unused)) +pid_t sys_wait4(pid_t pid, int *status, int options, struct rusage *rusage) +{ +	return my_syscall4(__NR_wait4, pid, status, options, rusage); +} + +static __attribute__((unused)) +pid_t wait(int *status) +{ +	pid_t ret = sys_wait4(-1, status, 0, NULL); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + +static __attribute__((unused)) +pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage) +{ +	pid_t ret = sys_wait4(pid, status, options, rusage); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +static __attribute__((unused)) +pid_t waitpid(pid_t pid, int *status, int options) +{ +	pid_t ret = sys_wait4(pid, status, options, NULL); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +/* + * ssize_t write(int fd, const void *buf, size_t count); + */ + +static __attribute__((unused)) +ssize_t sys_write(int fd, const void *buf, size_t count) +{ +	return my_syscall3(__NR_write, fd, buf, count); +} + +static __attribute__((unused)) +ssize_t write(int fd, const void *buf, size_t count) +{ +	ssize_t ret = sys_write(fd, buf, count); + +	if (ret < 0) { +		SET_ERRNO(-ret); +		ret = -1; +	} +	return ret; +} + + +#endif /* _NOLIBC_SYS_H */  | 
