cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sys.h (22724B)


      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_H
      8#define _NOLIBC_SYS_H
      9
     10#include <stdarg.h>
     11#include "std.h"
     12
     13/* system includes */
     14#include <asm/unistd.h>
     15#include <asm/signal.h>  // for SIGCHLD
     16#include <asm/ioctls.h>
     17#include <asm/mman.h>
     18#include <linux/fs.h>
     19#include <linux/loop.h>
     20#include <linux/time.h>
     21
     22#include "arch.h"
     23#include "errno.h"
     24#include "types.h"
     25
     26
     27/* Functions in this file only describe syscalls. They're declared static so
     28 * that the compiler usually decides to inline them while still being allowed
     29 * to pass a pointer to one of their instances. Each syscall exists in two
     30 * versions:
     31 *   - the "internal" ones, which matches the raw syscall interface at the
     32 *     kernel level, which may sometimes slightly differ from the documented
     33 *     libc-level ones. For example most of them return either a valid value
     34 *     or -errno. All of these are prefixed with "sys_". They may be called
     35 *     by non-portable applications if desired.
     36 *
     37 *   - the "exported" ones, whose interface must closely match the one
     38 *     documented in man(2), that applications are supposed to expect. These
     39 *     ones rely on the internal ones, and set errno.
     40 *
     41 * Each syscall will be defined with the two functions, sorted in alphabetical
     42 * order applied to the exported names.
     43 *
     44 * In case of doubt about the relevance of a function here, only those which
     45 * set errno should be defined here. Wrappers like those appearing in man(3)
     46 * should not be placed here.
     47 */
     48
     49
     50/*
     51 * int brk(void *addr);
     52 * void *sbrk(intptr_t inc)
     53 */
     54
     55static __attribute__((unused))
     56void *sys_brk(void *addr)
     57{
     58	return (void *)my_syscall1(__NR_brk, addr);
     59}
     60
     61static __attribute__((unused))
     62int brk(void *addr)
     63{
     64	void *ret = sys_brk(addr);
     65
     66	if (!ret) {
     67		SET_ERRNO(ENOMEM);
     68		return -1;
     69	}
     70	return 0;
     71}
     72
     73static __attribute__((unused))
     74void *sbrk(intptr_t inc)
     75{
     76	void *ret;
     77
     78	/* first call to find current end */
     79	if ((ret = sys_brk(0)) && (sys_brk(ret + inc) == ret + inc))
     80		return ret + inc;
     81
     82	SET_ERRNO(ENOMEM);
     83	return (void *)-1;
     84}
     85
     86
     87/*
     88 * int chdir(const char *path);
     89 */
     90
     91static __attribute__((unused))
     92int sys_chdir(const char *path)
     93{
     94	return my_syscall1(__NR_chdir, path);
     95}
     96
     97static __attribute__((unused))
     98int chdir(const char *path)
     99{
    100	int ret = sys_chdir(path);
    101
    102	if (ret < 0) {
    103		SET_ERRNO(-ret);
    104		ret = -1;
    105	}
    106	return ret;
    107}
    108
    109
    110/*
    111 * int chmod(const char *path, mode_t mode);
    112 */
    113
    114static __attribute__((unused))
    115int sys_chmod(const char *path, mode_t mode)
    116{
    117#ifdef __NR_fchmodat
    118	return my_syscall4(__NR_fchmodat, AT_FDCWD, path, mode, 0);
    119#elif defined(__NR_chmod)
    120	return my_syscall2(__NR_chmod, path, mode);
    121#else
    122#error Neither __NR_fchmodat nor __NR_chmod defined, cannot implement sys_chmod()
    123#endif
    124}
    125
    126static __attribute__((unused))
    127int chmod(const char *path, mode_t mode)
    128{
    129	int ret = sys_chmod(path, mode);
    130
    131	if (ret < 0) {
    132		SET_ERRNO(-ret);
    133		ret = -1;
    134	}
    135	return ret;
    136}
    137
    138
    139/*
    140 * int chown(const char *path, uid_t owner, gid_t group);
    141 */
    142
    143static __attribute__((unused))
    144int sys_chown(const char *path, uid_t owner, gid_t group)
    145{
    146#ifdef __NR_fchownat
    147	return my_syscall5(__NR_fchownat, AT_FDCWD, path, owner, group, 0);
    148#elif defined(__NR_chown)
    149	return my_syscall3(__NR_chown, path, owner, group);
    150#else
    151#error Neither __NR_fchownat nor __NR_chown defined, cannot implement sys_chown()
    152#endif
    153}
    154
    155static __attribute__((unused))
    156int chown(const char *path, uid_t owner, gid_t group)
    157{
    158	int ret = sys_chown(path, owner, group);
    159
    160	if (ret < 0) {
    161		SET_ERRNO(-ret);
    162		ret = -1;
    163	}
    164	return ret;
    165}
    166
    167
    168/*
    169 * int chroot(const char *path);
    170 */
    171
    172static __attribute__((unused))
    173int sys_chroot(const char *path)
    174{
    175	return my_syscall1(__NR_chroot, path);
    176}
    177
    178static __attribute__((unused))
    179int chroot(const char *path)
    180{
    181	int ret = sys_chroot(path);
    182
    183	if (ret < 0) {
    184		SET_ERRNO(-ret);
    185		ret = -1;
    186	}
    187	return ret;
    188}
    189
    190
    191/*
    192 * int close(int fd);
    193 */
    194
    195static __attribute__((unused))
    196int sys_close(int fd)
    197{
    198	return my_syscall1(__NR_close, fd);
    199}
    200
    201static __attribute__((unused))
    202int close(int fd)
    203{
    204	int ret = sys_close(fd);
    205
    206	if (ret < 0) {
    207		SET_ERRNO(-ret);
    208		ret = -1;
    209	}
    210	return ret;
    211}
    212
    213
    214/*
    215 * int dup(int fd);
    216 */
    217
    218static __attribute__((unused))
    219int sys_dup(int fd)
    220{
    221	return my_syscall1(__NR_dup, fd);
    222}
    223
    224static __attribute__((unused))
    225int dup(int fd)
    226{
    227	int ret = sys_dup(fd);
    228
    229	if (ret < 0) {
    230		SET_ERRNO(-ret);
    231		ret = -1;
    232	}
    233	return ret;
    234}
    235
    236
    237/*
    238 * int dup2(int old, int new);
    239 */
    240
    241static __attribute__((unused))
    242int sys_dup2(int old, int new)
    243{
    244#ifdef __NR_dup3
    245	return my_syscall3(__NR_dup3, old, new, 0);
    246#elif defined(__NR_dup2)
    247	return my_syscall2(__NR_dup2, old, new);
    248#else
    249#error Neither __NR_dup3 nor __NR_dup2 defined, cannot implement sys_dup2()
    250#endif
    251}
    252
    253static __attribute__((unused))
    254int dup2(int old, int new)
    255{
    256	int ret = sys_dup2(old, new);
    257
    258	if (ret < 0) {
    259		SET_ERRNO(-ret);
    260		ret = -1;
    261	}
    262	return ret;
    263}
    264
    265
    266/*
    267 * int dup3(int old, int new, int flags);
    268 */
    269
    270#ifdef __NR_dup3
    271static __attribute__((unused))
    272int sys_dup3(int old, int new, int flags)
    273{
    274	return my_syscall3(__NR_dup3, old, new, flags);
    275}
    276
    277static __attribute__((unused))
    278int dup3(int old, int new, int flags)
    279{
    280	int ret = sys_dup3(old, new, flags);
    281
    282	if (ret < 0) {
    283		SET_ERRNO(-ret);
    284		ret = -1;
    285	}
    286	return ret;
    287}
    288#endif
    289
    290
    291/*
    292 * int execve(const char *filename, char *const argv[], char *const envp[]);
    293 */
    294
    295static __attribute__((unused))
    296int sys_execve(const char *filename, char *const argv[], char *const envp[])
    297{
    298	return my_syscall3(__NR_execve, filename, argv, envp);
    299}
    300
    301static __attribute__((unused))
    302int execve(const char *filename, char *const argv[], char *const envp[])
    303{
    304	int ret = sys_execve(filename, argv, envp);
    305
    306	if (ret < 0) {
    307		SET_ERRNO(-ret);
    308		ret = -1;
    309	}
    310	return ret;
    311}
    312
    313
    314/*
    315 * void exit(int status);
    316 */
    317
    318static __attribute__((noreturn,unused))
    319void sys_exit(int status)
    320{
    321	my_syscall1(__NR_exit, status & 255);
    322	while(1); // shut the "noreturn" warnings.
    323}
    324
    325static __attribute__((noreturn,unused))
    326void exit(int status)
    327{
    328	sys_exit(status);
    329}
    330
    331
    332/*
    333 * pid_t fork(void);
    334 */
    335
    336static __attribute__((unused))
    337pid_t sys_fork(void)
    338{
    339#ifdef __NR_clone
    340	/* note: some archs only have clone() and not fork(). Different archs
    341	 * have a different API, but most archs have the flags on first arg and
    342	 * will not use the rest with no other flag.
    343	 */
    344	return my_syscall5(__NR_clone, SIGCHLD, 0, 0, 0, 0);
    345#elif defined(__NR_fork)
    346	return my_syscall0(__NR_fork);
    347#else
    348#error Neither __NR_clone nor __NR_fork defined, cannot implement sys_fork()
    349#endif
    350}
    351
    352static __attribute__((unused))
    353pid_t fork(void)
    354{
    355	pid_t ret = sys_fork();
    356
    357	if (ret < 0) {
    358		SET_ERRNO(-ret);
    359		ret = -1;
    360	}
    361	return ret;
    362}
    363
    364
    365/*
    366 * int fsync(int fd);
    367 */
    368
    369static __attribute__((unused))
    370int sys_fsync(int fd)
    371{
    372	return my_syscall1(__NR_fsync, fd);
    373}
    374
    375static __attribute__((unused))
    376int fsync(int fd)
    377{
    378	int ret = sys_fsync(fd);
    379
    380	if (ret < 0) {
    381		SET_ERRNO(-ret);
    382		ret = -1;
    383	}
    384	return ret;
    385}
    386
    387
    388/*
    389 * int getdents64(int fd, struct linux_dirent64 *dirp, int count);
    390 */
    391
    392static __attribute__((unused))
    393int sys_getdents64(int fd, struct linux_dirent64 *dirp, int count)
    394{
    395	return my_syscall3(__NR_getdents64, fd, dirp, count);
    396}
    397
    398static __attribute__((unused))
    399int getdents64(int fd, struct linux_dirent64 *dirp, int count)
    400{
    401	int ret = sys_getdents64(fd, dirp, count);
    402
    403	if (ret < 0) {
    404		SET_ERRNO(-ret);
    405		ret = -1;
    406	}
    407	return ret;
    408}
    409
    410
    411/*
    412 * pid_t getpgid(pid_t pid);
    413 */
    414
    415static __attribute__((unused))
    416pid_t sys_getpgid(pid_t pid)
    417{
    418	return my_syscall1(__NR_getpgid, pid);
    419}
    420
    421static __attribute__((unused))
    422pid_t getpgid(pid_t pid)
    423{
    424	pid_t ret = sys_getpgid(pid);
    425
    426	if (ret < 0) {
    427		SET_ERRNO(-ret);
    428		ret = -1;
    429	}
    430	return ret;
    431}
    432
    433
    434/*
    435 * pid_t getpgrp(void);
    436 */
    437
    438static __attribute__((unused))
    439pid_t sys_getpgrp(void)
    440{
    441	return sys_getpgid(0);
    442}
    443
    444static __attribute__((unused))
    445pid_t getpgrp(void)
    446{
    447	return sys_getpgrp();
    448}
    449
    450
    451/*
    452 * pid_t getpid(void);
    453 */
    454
    455static __attribute__((unused))
    456pid_t sys_getpid(void)
    457{
    458	return my_syscall0(__NR_getpid);
    459}
    460
    461static __attribute__((unused))
    462pid_t getpid(void)
    463{
    464	return sys_getpid();
    465}
    466
    467
    468/*
    469 * pid_t getppid(void);
    470 */
    471
    472static __attribute__((unused))
    473pid_t sys_getppid(void)
    474{
    475	return my_syscall0(__NR_getppid);
    476}
    477
    478static __attribute__((unused))
    479pid_t getppid(void)
    480{
    481	return sys_getppid();
    482}
    483
    484
    485/*
    486 * pid_t gettid(void);
    487 */
    488
    489static __attribute__((unused))
    490pid_t sys_gettid(void)
    491{
    492	return my_syscall0(__NR_gettid);
    493}
    494
    495static __attribute__((unused))
    496pid_t gettid(void)
    497{
    498	return sys_gettid();
    499}
    500
    501
    502/*
    503 * int gettimeofday(struct timeval *tv, struct timezone *tz);
    504 */
    505
    506static __attribute__((unused))
    507int sys_gettimeofday(struct timeval *tv, struct timezone *tz)
    508{
    509	return my_syscall2(__NR_gettimeofday, tv, tz);
    510}
    511
    512static __attribute__((unused))
    513int gettimeofday(struct timeval *tv, struct timezone *tz)
    514{
    515	int ret = sys_gettimeofday(tv, tz);
    516
    517	if (ret < 0) {
    518		SET_ERRNO(-ret);
    519		ret = -1;
    520	}
    521	return ret;
    522}
    523
    524
    525/*
    526 * int ioctl(int fd, unsigned long req, void *value);
    527 */
    528
    529static __attribute__((unused))
    530int sys_ioctl(int fd, unsigned long req, void *value)
    531{
    532	return my_syscall3(__NR_ioctl, fd, req, value);
    533}
    534
    535static __attribute__((unused))
    536int ioctl(int fd, unsigned long req, void *value)
    537{
    538	int ret = sys_ioctl(fd, req, value);
    539
    540	if (ret < 0) {
    541		SET_ERRNO(-ret);
    542		ret = -1;
    543	}
    544	return ret;
    545}
    546
    547/*
    548 * int kill(pid_t pid, int signal);
    549 */
    550
    551static __attribute__((unused))
    552int sys_kill(pid_t pid, int signal)
    553{
    554	return my_syscall2(__NR_kill, pid, signal);
    555}
    556
    557static __attribute__((unused))
    558int kill(pid_t pid, int signal)
    559{
    560	int ret = sys_kill(pid, signal);
    561
    562	if (ret < 0) {
    563		SET_ERRNO(-ret);
    564		ret = -1;
    565	}
    566	return ret;
    567}
    568
    569
    570/*
    571 * int link(const char *old, const char *new);
    572 */
    573
    574static __attribute__((unused))
    575int sys_link(const char *old, const char *new)
    576{
    577#ifdef __NR_linkat
    578	return my_syscall5(__NR_linkat, AT_FDCWD, old, AT_FDCWD, new, 0);
    579#elif defined(__NR_link)
    580	return my_syscall2(__NR_link, old, new);
    581#else
    582#error Neither __NR_linkat nor __NR_link defined, cannot implement sys_link()
    583#endif
    584}
    585
    586static __attribute__((unused))
    587int link(const char *old, const char *new)
    588{
    589	int ret = sys_link(old, new);
    590
    591	if (ret < 0) {
    592		SET_ERRNO(-ret);
    593		ret = -1;
    594	}
    595	return ret;
    596}
    597
    598
    599/*
    600 * off_t lseek(int fd, off_t offset, int whence);
    601 */
    602
    603static __attribute__((unused))
    604off_t sys_lseek(int fd, off_t offset, int whence)
    605{
    606	return my_syscall3(__NR_lseek, fd, offset, whence);
    607}
    608
    609static __attribute__((unused))
    610off_t lseek(int fd, off_t offset, int whence)
    611{
    612	off_t ret = sys_lseek(fd, offset, whence);
    613
    614	if (ret < 0) {
    615		SET_ERRNO(-ret);
    616		ret = -1;
    617	}
    618	return ret;
    619}
    620
    621
    622/*
    623 * int mkdir(const char *path, mode_t mode);
    624 */
    625
    626static __attribute__((unused))
    627int sys_mkdir(const char *path, mode_t mode)
    628{
    629#ifdef __NR_mkdirat
    630	return my_syscall3(__NR_mkdirat, AT_FDCWD, path, mode);
    631#elif defined(__NR_mkdir)
    632	return my_syscall2(__NR_mkdir, path, mode);
    633#else
    634#error Neither __NR_mkdirat nor __NR_mkdir defined, cannot implement sys_mkdir()
    635#endif
    636}
    637
    638static __attribute__((unused))
    639int mkdir(const char *path, mode_t mode)
    640{
    641	int ret = sys_mkdir(path, mode);
    642
    643	if (ret < 0) {
    644		SET_ERRNO(-ret);
    645		ret = -1;
    646	}
    647	return ret;
    648}
    649
    650
    651/*
    652 * int mknod(const char *path, mode_t mode, dev_t dev);
    653 */
    654
    655static __attribute__((unused))
    656long sys_mknod(const char *path, mode_t mode, dev_t dev)
    657{
    658#ifdef __NR_mknodat
    659	return my_syscall4(__NR_mknodat, AT_FDCWD, path, mode, dev);
    660#elif defined(__NR_mknod)
    661	return my_syscall3(__NR_mknod, path, mode, dev);
    662#else
    663#error Neither __NR_mknodat nor __NR_mknod defined, cannot implement sys_mknod()
    664#endif
    665}
    666
    667static __attribute__((unused))
    668int mknod(const char *path, mode_t mode, dev_t dev)
    669{
    670	int ret = sys_mknod(path, mode, dev);
    671
    672	if (ret < 0) {
    673		SET_ERRNO(-ret);
    674		ret = -1;
    675	}
    676	return ret;
    677}
    678
    679#ifndef MAP_SHARED
    680#define MAP_SHARED		0x01	/* Share changes */
    681#define MAP_PRIVATE		0x02	/* Changes are private */
    682#define MAP_SHARED_VALIDATE	0x03	/* share + validate extension flags */
    683#endif
    684
    685#ifndef MAP_FAILED
    686#define MAP_FAILED ((void *)-1)
    687#endif
    688
    689static __attribute__((unused))
    690void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd,
    691	       off_t offset)
    692{
    693#ifndef my_syscall6
    694	/* Function not implemented. */
    695	return -ENOSYS;
    696#else
    697
    698	int n;
    699
    700#if defined(__i386__)
    701	n = __NR_mmap2;
    702	offset >>= 12;
    703#else
    704	n = __NR_mmap;
    705#endif
    706
    707	return (void *)my_syscall6(n, addr, length, prot, flags, fd, offset);
    708#endif
    709}
    710
    711static __attribute__((unused))
    712void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
    713{
    714	void *ret = sys_mmap(addr, length, prot, flags, fd, offset);
    715
    716	if ((unsigned long)ret >= -4095UL) {
    717		SET_ERRNO(-(long)ret);
    718		ret = MAP_FAILED;
    719	}
    720	return ret;
    721}
    722
    723static __attribute__((unused))
    724int sys_munmap(void *addr, size_t length)
    725{
    726	return my_syscall2(__NR_munmap, addr, length);
    727}
    728
    729static __attribute__((unused))
    730int munmap(void *addr, size_t length)
    731{
    732	int ret = sys_munmap(addr, length);
    733
    734	if (ret < 0) {
    735		SET_ERRNO(-ret);
    736		ret = -1;
    737	}
    738	return ret;
    739}
    740
    741/*
    742 * int mount(const char *source, const char *target,
    743 *           const char *fstype, unsigned long flags,
    744 *           const void *data);
    745 */
    746static __attribute__((unused))
    747int sys_mount(const char *src, const char *tgt, const char *fst,
    748                     unsigned long flags, const void *data)
    749{
    750	return my_syscall5(__NR_mount, src, tgt, fst, flags, data);
    751}
    752
    753static __attribute__((unused))
    754int mount(const char *src, const char *tgt,
    755          const char *fst, unsigned long flags,
    756          const void *data)
    757{
    758	int ret = sys_mount(src, tgt, fst, flags, data);
    759
    760	if (ret < 0) {
    761		SET_ERRNO(-ret);
    762		ret = -1;
    763	}
    764	return ret;
    765}
    766
    767
    768/*
    769 * int open(const char *path, int flags[, mode_t mode]);
    770 */
    771
    772static __attribute__((unused))
    773int sys_open(const char *path, int flags, mode_t mode)
    774{
    775#ifdef __NR_openat
    776	return my_syscall4(__NR_openat, AT_FDCWD, path, flags, mode);
    777#elif defined(__NR_open)
    778	return my_syscall3(__NR_open, path, flags, mode);
    779#else
    780#error Neither __NR_openat nor __NR_open defined, cannot implement sys_open()
    781#endif
    782}
    783
    784static __attribute__((unused))
    785int open(const char *path, int flags, ...)
    786{
    787	mode_t mode = 0;
    788	int ret;
    789
    790	if (flags & O_CREAT) {
    791		va_list args;
    792
    793		va_start(args, flags);
    794		mode = va_arg(args, mode_t);
    795		va_end(args);
    796	}
    797
    798	ret = sys_open(path, flags, mode);
    799
    800	if (ret < 0) {
    801		SET_ERRNO(-ret);
    802		ret = -1;
    803	}
    804	return ret;
    805}
    806
    807
    808/*
    809 * int pivot_root(const char *new, const char *old);
    810 */
    811
    812static __attribute__((unused))
    813int sys_pivot_root(const char *new, const char *old)
    814{
    815	return my_syscall2(__NR_pivot_root, new, old);
    816}
    817
    818static __attribute__((unused))
    819int pivot_root(const char *new, const char *old)
    820{
    821	int ret = sys_pivot_root(new, old);
    822
    823	if (ret < 0) {
    824		SET_ERRNO(-ret);
    825		ret = -1;
    826	}
    827	return ret;
    828}
    829
    830
    831/*
    832 * int poll(struct pollfd *fds, int nfds, int timeout);
    833 */
    834
    835static __attribute__((unused))
    836int sys_poll(struct pollfd *fds, int nfds, int timeout)
    837{
    838#if defined(__NR_ppoll)
    839	struct timespec t;
    840
    841	if (timeout >= 0) {
    842		t.tv_sec  = timeout / 1000;
    843		t.tv_nsec = (timeout % 1000) * 1000000;
    844	}
    845	return my_syscall4(__NR_ppoll, fds, nfds, (timeout >= 0) ? &t : NULL, NULL);
    846#elif defined(__NR_poll)
    847	return my_syscall3(__NR_poll, fds, nfds, timeout);
    848#else
    849#error Neither __NR_ppoll nor __NR_poll defined, cannot implement sys_poll()
    850#endif
    851}
    852
    853static __attribute__((unused))
    854int poll(struct pollfd *fds, int nfds, int timeout)
    855{
    856	int ret = sys_poll(fds, nfds, timeout);
    857
    858	if (ret < 0) {
    859		SET_ERRNO(-ret);
    860		ret = -1;
    861	}
    862	return ret;
    863}
    864
    865
    866/*
    867 * ssize_t read(int fd, void *buf, size_t count);
    868 */
    869
    870static __attribute__((unused))
    871ssize_t sys_read(int fd, void *buf, size_t count)
    872{
    873	return my_syscall3(__NR_read, fd, buf, count);
    874}
    875
    876static __attribute__((unused))
    877ssize_t read(int fd, void *buf, size_t count)
    878{
    879	ssize_t ret = sys_read(fd, buf, count);
    880
    881	if (ret < 0) {
    882		SET_ERRNO(-ret);
    883		ret = -1;
    884	}
    885	return ret;
    886}
    887
    888
    889/*
    890 * int reboot(int cmd);
    891 * <cmd> is among LINUX_REBOOT_CMD_*
    892 */
    893
    894static __attribute__((unused))
    895ssize_t sys_reboot(int magic1, int magic2, int cmd, void *arg)
    896{
    897	return my_syscall4(__NR_reboot, magic1, magic2, cmd, arg);
    898}
    899
    900static __attribute__((unused))
    901int reboot(int cmd)
    902{
    903	int ret = sys_reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, 0);
    904
    905	if (ret < 0) {
    906		SET_ERRNO(-ret);
    907		ret = -1;
    908	}
    909	return ret;
    910}
    911
    912
    913/*
    914 * int sched_yield(void);
    915 */
    916
    917static __attribute__((unused))
    918int sys_sched_yield(void)
    919{
    920	return my_syscall0(__NR_sched_yield);
    921}
    922
    923static __attribute__((unused))
    924int sched_yield(void)
    925{
    926	int ret = sys_sched_yield();
    927
    928	if (ret < 0) {
    929		SET_ERRNO(-ret);
    930		ret = -1;
    931	}
    932	return ret;
    933}
    934
    935
    936/*
    937 * int select(int nfds, fd_set *read_fds, fd_set *write_fds,
    938 *            fd_set *except_fds, struct timeval *timeout);
    939 */
    940
    941static __attribute__((unused))
    942int sys_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout)
    943{
    944#if defined(__ARCH_WANT_SYS_OLD_SELECT) && !defined(__NR__newselect)
    945	struct sel_arg_struct {
    946		unsigned long n;
    947		fd_set *r, *w, *e;
    948		struct timeval *t;
    949	} arg = { .n = nfds, .r = rfds, .w = wfds, .e = efds, .t = timeout };
    950	return my_syscall1(__NR_select, &arg);
    951#elif defined(__ARCH_WANT_SYS_PSELECT6) && defined(__NR_pselect6)
    952	struct timespec t;
    953
    954	if (timeout) {
    955		t.tv_sec  = timeout->tv_sec;
    956		t.tv_nsec = timeout->tv_usec * 1000;
    957	}
    958	return my_syscall6(__NR_pselect6, nfds, rfds, wfds, efds, timeout ? &t : NULL, NULL);
    959#elif defined(__NR__newselect) || defined(__NR_select)
    960#ifndef __NR__newselect
    961#define __NR__newselect __NR_select
    962#endif
    963	return my_syscall5(__NR__newselect, nfds, rfds, wfds, efds, timeout);
    964#else
    965#error None of __NR_select, __NR_pselect6, nor __NR__newselect defined, cannot implement sys_select()
    966#endif
    967}
    968
    969static __attribute__((unused))
    970int select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout)
    971{
    972	int ret = sys_select(nfds, rfds, wfds, efds, timeout);
    973
    974	if (ret < 0) {
    975		SET_ERRNO(-ret);
    976		ret = -1;
    977	}
    978	return ret;
    979}
    980
    981
    982/*
    983 * int setpgid(pid_t pid, pid_t pgid);
    984 */
    985
    986static __attribute__((unused))
    987int sys_setpgid(pid_t pid, pid_t pgid)
    988{
    989	return my_syscall2(__NR_setpgid, pid, pgid);
    990}
    991
    992static __attribute__((unused))
    993int setpgid(pid_t pid, pid_t pgid)
    994{
    995	int ret = sys_setpgid(pid, pgid);
    996
    997	if (ret < 0) {
    998		SET_ERRNO(-ret);
    999		ret = -1;
   1000	}
   1001	return ret;
   1002}
   1003
   1004
   1005/*
   1006 * pid_t setsid(void);
   1007 */
   1008
   1009static __attribute__((unused))
   1010pid_t sys_setsid(void)
   1011{
   1012	return my_syscall0(__NR_setsid);
   1013}
   1014
   1015static __attribute__((unused))
   1016pid_t setsid(void)
   1017{
   1018	pid_t ret = sys_setsid();
   1019
   1020	if (ret < 0) {
   1021		SET_ERRNO(-ret);
   1022		ret = -1;
   1023	}
   1024	return ret;
   1025}
   1026
   1027
   1028/*
   1029 * int stat(const char *path, struct stat *buf);
   1030 * Warning: the struct stat's layout is arch-dependent.
   1031 */
   1032
   1033static __attribute__((unused))
   1034int sys_stat(const char *path, struct stat *buf)
   1035{
   1036	struct sys_stat_struct stat;
   1037	long ret;
   1038
   1039#ifdef __NR_newfstatat
   1040	/* only solution for arm64 */
   1041	ret = my_syscall4(__NR_newfstatat, AT_FDCWD, path, &stat, 0);
   1042#elif defined(__NR_stat)
   1043	ret = my_syscall2(__NR_stat, path, &stat);
   1044#else
   1045#error Neither __NR_newfstatat nor __NR_stat defined, cannot implement sys_stat()
   1046#endif
   1047	buf->st_dev     = stat.st_dev;
   1048	buf->st_ino     = stat.st_ino;
   1049	buf->st_mode    = stat.st_mode;
   1050	buf->st_nlink   = stat.st_nlink;
   1051	buf->st_uid     = stat.st_uid;
   1052	buf->st_gid     = stat.st_gid;
   1053	buf->st_rdev    = stat.st_rdev;
   1054	buf->st_size    = stat.st_size;
   1055	buf->st_blksize = stat.st_blksize;
   1056	buf->st_blocks  = stat.st_blocks;
   1057	buf->st_atime   = stat.st_atime;
   1058	buf->st_mtime   = stat.st_mtime;
   1059	buf->st_ctime   = stat.st_ctime;
   1060	return ret;
   1061}
   1062
   1063static __attribute__((unused))
   1064int stat(const char *path, struct stat *buf)
   1065{
   1066	int ret = sys_stat(path, buf);
   1067
   1068	if (ret < 0) {
   1069		SET_ERRNO(-ret);
   1070		ret = -1;
   1071	}
   1072	return ret;
   1073}
   1074
   1075
   1076/*
   1077 * int symlink(const char *old, const char *new);
   1078 */
   1079
   1080static __attribute__((unused))
   1081int sys_symlink(const char *old, const char *new)
   1082{
   1083#ifdef __NR_symlinkat
   1084	return my_syscall3(__NR_symlinkat, old, AT_FDCWD, new);
   1085#elif defined(__NR_symlink)
   1086	return my_syscall2(__NR_symlink, old, new);
   1087#else
   1088#error Neither __NR_symlinkat nor __NR_symlink defined, cannot implement sys_symlink()
   1089#endif
   1090}
   1091
   1092static __attribute__((unused))
   1093int symlink(const char *old, const char *new)
   1094{
   1095	int ret = sys_symlink(old, new);
   1096
   1097	if (ret < 0) {
   1098		SET_ERRNO(-ret);
   1099		ret = -1;
   1100	}
   1101	return ret;
   1102}
   1103
   1104
   1105/*
   1106 * mode_t umask(mode_t mode);
   1107 */
   1108
   1109static __attribute__((unused))
   1110mode_t sys_umask(mode_t mode)
   1111{
   1112	return my_syscall1(__NR_umask, mode);
   1113}
   1114
   1115static __attribute__((unused))
   1116mode_t umask(mode_t mode)
   1117{
   1118	return sys_umask(mode);
   1119}
   1120
   1121
   1122/*
   1123 * int umount2(const char *path, int flags);
   1124 */
   1125
   1126static __attribute__((unused))
   1127int sys_umount2(const char *path, int flags)
   1128{
   1129	return my_syscall2(__NR_umount2, path, flags);
   1130}
   1131
   1132static __attribute__((unused))
   1133int umount2(const char *path, int flags)
   1134{
   1135	int ret = sys_umount2(path, flags);
   1136
   1137	if (ret < 0) {
   1138		SET_ERRNO(-ret);
   1139		ret = -1;
   1140	}
   1141	return ret;
   1142}
   1143
   1144
   1145/*
   1146 * int unlink(const char *path);
   1147 */
   1148
   1149static __attribute__((unused))
   1150int sys_unlink(const char *path)
   1151{
   1152#ifdef __NR_unlinkat
   1153	return my_syscall3(__NR_unlinkat, AT_FDCWD, path, 0);
   1154#elif defined(__NR_unlink)
   1155	return my_syscall1(__NR_unlink, path);
   1156#else
   1157#error Neither __NR_unlinkat nor __NR_unlink defined, cannot implement sys_unlink()
   1158#endif
   1159}
   1160
   1161static __attribute__((unused))
   1162int unlink(const char *path)
   1163{
   1164	int ret = sys_unlink(path);
   1165
   1166	if (ret < 0) {
   1167		SET_ERRNO(-ret);
   1168		ret = -1;
   1169	}
   1170	return ret;
   1171}
   1172
   1173
   1174/*
   1175 * pid_t wait(int *status);
   1176 * pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage);
   1177 * pid_t waitpid(pid_t pid, int *status, int options);
   1178 */
   1179
   1180static __attribute__((unused))
   1181pid_t sys_wait4(pid_t pid, int *status, int options, struct rusage *rusage)
   1182{
   1183	return my_syscall4(__NR_wait4, pid, status, options, rusage);
   1184}
   1185
   1186static __attribute__((unused))
   1187pid_t wait(int *status)
   1188{
   1189	pid_t ret = sys_wait4(-1, status, 0, NULL);
   1190
   1191	if (ret < 0) {
   1192		SET_ERRNO(-ret);
   1193		ret = -1;
   1194	}
   1195	return ret;
   1196}
   1197
   1198static __attribute__((unused))
   1199pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage)
   1200{
   1201	pid_t ret = sys_wait4(pid, status, options, rusage);
   1202
   1203	if (ret < 0) {
   1204		SET_ERRNO(-ret);
   1205		ret = -1;
   1206	}
   1207	return ret;
   1208}
   1209
   1210
   1211static __attribute__((unused))
   1212pid_t waitpid(pid_t pid, int *status, int options)
   1213{
   1214	pid_t ret = sys_wait4(pid, status, options, NULL);
   1215
   1216	if (ret < 0) {
   1217		SET_ERRNO(-ret);
   1218		ret = -1;
   1219	}
   1220	return ret;
   1221}
   1222
   1223
   1224/*
   1225 * ssize_t write(int fd, const void *buf, size_t count);
   1226 */
   1227
   1228static __attribute__((unused))
   1229ssize_t sys_write(int fd, const void *buf, size_t count)
   1230{
   1231	return my_syscall3(__NR_write, fd, buf, count);
   1232}
   1233
   1234static __attribute__((unused))
   1235ssize_t write(int fd, const void *buf, size_t count)
   1236{
   1237	ssize_t ret = sys_write(fd, buf, count);
   1238
   1239	if (ret < 0) {
   1240		SET_ERRNO(-ret);
   1241		ret = -1;
   1242	}
   1243	return ret;
   1244}
   1245
   1246
   1247#endif /* _NOLIBC_SYS_H */