/* This file is part of Fennix Kernel. Fennix Kernel is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Fennix Kernel is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_API_SYSTEM_CALLS_LIST_H__ #define __FENNIX_API_SYSTEM_CALLS_LIST_H__ #if __has_include() #include #else #include #endif #ifndef __fennix__ #error "__fennix__ not defined" #endif #pragma region Syscall Wrappers #define scarg __UINTPTR_TYPE__ #ifdef __arm__ #ifdef __thumb__ #define __thumb_r7 #define __arm_call(...) #warning "arm thumb code not implemented" #else /* __thumb__ */ #define __thumb_r7 __asm__("r7") #define __arm_call(...) \ __asm__ __volatile__("svc 0" \ : "=r"(r0) \ : __VA_ARGS__ \ : "memory") #endif /* __thumb__ */ #ifdef __thumb2__ #define __r7_operand "rI"(r7) #else /* __thumb2__ */ #define __r7_operand "r"(r7) #endif /* __thumb2__ */ #endif /* __arm__ */ /** * @brief Syscall wrapper with 0 arguments * * @details This wrapper is used to call syscalls with 0 arguments * * @param syscall #syscalls_t * @return The return value of the syscall */ static inline scarg syscall0(scarg syscall) { scarg ret; #if defined(__amd64__) __asm__ __volatile__("syscall" : "=a"(ret) : "a"(syscall) : "rcx", "r11", "memory"); #elif defined(__i386__) __asm__ __volatile__("int $0x30" : "=a"(ret) : "a"(syscall) : "memory"); #elif defined(__arm__) register scarg r7 __thumb_r7 = syscall; register scarg r0 __asm__("r0"); __arm_call(__r7_operand); #elif defined(__aarch64__) register scarg x8 __asm__("x8") = syscall; register scarg x0 __asm__("x0"); __asm__ __volatile__("svc 0" : "=r"(x0) : "r"(x8) : "memory", "cc"); #else #error "Unsupported architecture" #endif return ret; } /** * @brief Syscall wrapper with 1 argument * * @details This wrapper is used to call syscalls with 1 argument * * @param syscall #syscalls_t * @param arg1 Argument 1 * @return The return value of the syscall */ static inline scarg syscall1(scarg syscall, scarg arg1) { scarg ret; #if defined(__amd64__) __asm__ __volatile__("syscall" : "=a"(ret) : "a"(syscall), "D"(arg1) : "rcx", "r11", "memory"); #elif defined(__i386__) __asm__ __volatile__("int $0x30" : "=a"(ret) : "a"(syscall), "b"(arg1) : "memory"); #elif defined(__arm__) register scarg r7 __thumb_r7 = syscall; register scarg r0 __asm__("r0") = arg1; __arm_call(__r7_operand, "0"(r0)); #elif defined(__aarch64__) register scarg x8 __asm__("x8") = syscall; register scarg x0 __asm__("x0") = arg1; __asm__ __volatile__("svc 0" : "=r"(ret) : "r"(x8), "0"(x0) : "memory", "cc"); #else #error "Unsupported architecture" #endif return ret; } /** * @brief Syscall wrapper with 2 arguments * * @details This wrapper is used to call syscalls with 2 arguments * * @param syscall #syscalls_t * @param arg1 Argument 1 * @param arg2 Argument 2 * @return The return value of the syscall */ static inline scarg syscall2(scarg syscall, scarg arg1, scarg arg2) { scarg ret; #if defined(__amd64__) __asm__ __volatile__("syscall" : "=a"(ret) : "a"(syscall), "D"(arg1), "S"(arg2) : "rcx", "r11", "memory"); #elif defined(__i386__) __asm__ __volatile__("int $0x30" : "=a"(ret) : "a"(syscall), "b"(arg1), "c"(arg2) : "memory"); #elif defined(__arm__) register scarg r7 __thumb_r7 = syscall; register scarg r0 __asm__("r0") = arg1; register scarg r1 __asm__("r1") = arg2; __arm_call(__r7_operand, "0"(r0), "r"(r1)); #elif defined(__aarch64__) register scarg x8 __asm__("x8") = syscall; register scarg x0 __asm__("x0") = arg1; register scarg x1 __asm__("x1") = arg2; __asm__ __volatile__("svc 0" : "=r"(ret) : "r"(x8), "0"(x0), "r"(x1) : "memory", "cc"); #else #error "Unsupported architecture" #endif return ret; } /** * @brief Syscall wrapper with 3 arguments * * @details This wrapper is used to call syscalls with 3 arguments * * @param syscall #syscalls_t * @param arg1 Argument 1 * @param arg2 Argument 2 * @param arg3 Argument 3 * @return The return value of the syscall */ static inline scarg syscall3(scarg syscall, scarg arg1, scarg arg2, scarg arg3) { scarg ret; #if defined(__amd64__) __asm__ __volatile__("syscall" : "=a"(ret) : "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3) : "rcx", "r11", "memory"); #elif defined(__i386__) __asm__ __volatile__("int $0x30" : "=a"(ret) : "a"(syscall), "b"(arg1), "c"(arg2), "d"(arg3) : "memory"); #elif defined(__arm__) register scarg r7 __thumb_r7 = syscall; register scarg r0 __asm__("r0") = arg1; register scarg r1 __asm__("r1") = arg2; register scarg r2 __asm__("r2") = arg3; __arm_call(__r7_operand, "0"(r0), "r"(r1), "r"(r2)); #elif defined(__aarch64__) register scarg x8 __asm__("x8") = syscall; register scarg x0 __asm__("x0") = arg1; register scarg x1 __asm__("x1") = arg2; register scarg x2 __asm__("x2") = arg3; __asm__ __volatile__("svc 0" : "=r"(ret) : "r"(x8), "0"(x0), "r"(x1), "r"(x2) : "memory", "cc"); #else #error "Unsupported architecture" #endif return ret; } /** * @brief Syscall wrapper with 4 arguments * * @details This wrapper is used to call syscalls with 4 arguments * * @param syscall #syscalls_t * @param arg1 Argument 1 * @param arg2 Argument 2 * @param arg3 Argument 3 * @param arg4 Argument 4 * @return The return value of the syscall */ static inline scarg syscall4(scarg syscall, scarg arg1, scarg arg2, scarg arg3, scarg arg4) { scarg ret; #if defined(__amd64__) register scarg r10 __asm__("r10") = arg4; __asm__ __volatile__("syscall" : "=a"(ret) : "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10) : "rcx", "r11", "memory"); #elif defined(__i386__) __asm__ __volatile__("int $0x30" : "=a"(ret) : "a"(syscall), "b"(arg1), "c"(arg2), "d"(arg3), "S"(arg4) : "memory"); #elif defined(__arm__) register scarg r7 __thumb_r7 = syscall; register scarg r0 __asm__("r0") = arg1; register scarg r1 __asm__("r1") = arg2; register scarg r2 __asm__("r2") = arg3; register scarg r3 __asm__("r3") = arg4; __arm_call(__r7_operand, "0"(r0), "r"(r1), "r"(r2), "r"(r3)); #elif defined(__aarch64__) register scarg x8 __asm__("x8") = syscall; register scarg x0 __asm__("x0") = arg1; register scarg x1 __asm__("x1") = arg2; register scarg x2 __asm__("x2") = arg3; register scarg x3 __asm__("x3") = arg4; __asm__ __volatile__("svc 0" : "=r"(ret) : "r"(x8), "0"(x0), "r"(x1), "r"(x2), "r"(x3) : "memory", "cc"); #else #error "Unsupported architecture" #endif return ret; } /** * @brief Syscall wrapper with 5 arguments * * @details This wrapper is used to call syscalls with 5 arguments * * @param syscall #syscalls_t * @param arg1 Argument 1 * @param arg2 Argument 2 * @param arg3 Argument 3 * @param arg4 Argument 4 * @param arg5 Argument 5 * @return The return value of the syscall */ static inline scarg syscall5(scarg syscall, scarg arg1, scarg arg2, scarg arg3, scarg arg4, scarg arg5) { scarg ret; #if defined(__amd64__) register scarg r10 __asm__("r10") = arg4; register scarg r8 __asm__("r8") = arg5; __asm__ __volatile__("syscall" : "=a"(ret) : "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10), "r"(r8) : "rcx", "r11", "memory"); #elif defined(__i386__) __asm__ __volatile__("int $0x30" : "=a"(ret) : "a"(syscall), "b"(arg1), "c"(arg2), "d"(arg3), "S"(arg4), "D"(arg5) : "memory"); #elif defined(__arm__) register scarg r7 __thumb_r7 = syscall; register scarg r0 __asm__("r0") = arg1; register scarg r1 __asm__("r1") = arg2; register scarg r2 __asm__("r2") = arg3; register scarg r3 __asm__("r3") = arg4; register scarg r4 __asm__("r4") = arg5; __arm_call(__r7_operand, "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4)); #elif defined(__aarch64__) register scarg x8 __asm__("x8") = syscall; register scarg x0 __asm__("x0") = arg1; register scarg x1 __asm__("x1") = arg2; register scarg x2 __asm__("x2") = arg3; register scarg x3 __asm__("x3") = arg4; register scarg x4 __asm__("x4") = arg5; __asm__ __volatile__("svc 0" : "=r"(ret) : "r"(x8), "0"(x0), "r"(x1), "r"(x2), "r"(x3), "r"(x4) : "memory", "cc"); #else #error "Unsupported architecture" #endif return ret; } /** * @brief Syscall wrapper with 6 arguments * * @details This wrapper is used to call syscalls with 6 arguments * * @param syscall #syscalls_t * @param arg1 Argument 1 * @param arg2 Argument 2 * @param arg3 Argument 3 * @param arg4 Argument 4 * @param arg5 Argument 5 * @param arg6 Argument 6 * @return The return value of the syscall */ static inline scarg syscall6(scarg syscall, scarg arg1, scarg arg2, scarg arg3, scarg arg4, scarg arg5, scarg arg6) { scarg ret; #if defined(__amd64__) register scarg r10 __asm__("r10") = arg4; register scarg r8 __asm__("r8") = arg5; register scarg r9 __asm__("r9") = arg6; __asm__ __volatile__("syscall" : "=a"(ret) : "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10), "r"(r8), "r"(r9) : "rcx", "r11", "memory"); #elif defined(__i386__) __asm__ __volatile__("int $0x30" : "=a"(ret) : "a"(syscall), "b"(arg1), "c"(arg2), "d"(arg3), "S"(arg4), "D"(arg5), "g"(arg6) : "memory"); #elif defined(__arm__) register scarg r7 __thumb_r7 = syscall; register scarg r0 __asm__("r0") = arg1; register scarg r1 __asm__("r1") = arg2; register scarg r2 __asm__("r2") = arg3; register scarg r3 __asm__("r3") = arg4; register scarg r4 __asm__("r4") = arg5; register scarg r5 __asm__("r5") = arg6; __arm_call(__r7_operand, "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5)); #elif defined(__aarch64__) register scarg x8 __asm__("x8") = syscall; register scarg x0 __asm__("x0") = arg1; register scarg x1 __asm__("x1") = arg2; register scarg x2 __asm__("x2") = arg3; register scarg x3 __asm__("x3") = arg4; register scarg x4 __asm__("x4") = arg5; register scarg x5 __asm__("x5") = arg6; __asm__ __volatile__("svc 0" : "=r"(ret) : "r"(x8), "0"(x0), "r"(x1), "r"(x2), "r"(x3), "r"(x4), "r"(x5) : "memory", "cc"); #else #error "Unsupported architecture" #endif return ret; } #pragma endregion Syscall Wrappers /** * @brief NULL pointer * * This is a pointer to address 0, which is reserved and cannot be dereferenced. * * @note This macro is defined only for this documentation. */ #define __SYS_NULL ((void *)0) typedef enum { __SYS_PROT_READ = 0x1, __SYS_PROT_WRITE = 0x2, __SYS_PROT_EXEC = 0x4, __SYS_PROT_NONE = 0x0, __SYS_MAP_SHARED = 0x1, __SYS_MAP_PRIVATE = 0x2, __SYS_MAP_FIXED = 0x4, __SYS_MAP_ANONYMOUS = 0x8, __SYS_MAP_ANON = __SYS_MAP_ANONYMOUS } syscall_mmap_flags_t; typedef enum { __SYS_O_RDONLY = O_RDONLY, __SYS_O_WRONLY = O_WRONLY, __SYS_O_RDWR = O_RDWR, __SYS_O_APPEND = O_APPEND, __SYS_O_CREAT = O_CREAT, __SYS_O_DSYNC = O_DSYNC, __SYS_O_EXCL = O_EXCL, __SYS_O_NOCTTY = O_NOCTTY, __SYS_O_NONBLOCK = O_NONBLOCK, __SYS_O_RSYNC = O_RSYNC, __SYS_O_SYNC = O_SYNC, __SYS_O_TRUNC = O_TRUNC } syscall_open_flags_t; typedef enum { __SYS_F_OK = 0, __SYS_R_OK = 1, __SYS_W_OK = 2, __SYS_X_OK = 3 } syscall_access_flags_t; typedef enum { __SYS_GET_GS = 0, __SYS_SET_GS = 1, __SYS_GET_FS = 2, __SYS_SET_FS = 3, } syscall_prctl_options_t; #ifdef __kernel__ typedef syscall_prctl_options_t prctl_options_t; #endif typedef enum { __SYS_SEEK_SET = 0, __SYS_SEEK_CUR = 1, __SYS_SEEK_END = 2 } syscall_seek_whence_t; typedef enum { __SYS_SIGNULL = 0, /* Process abort signal. */ __SYS_SIGABRT = 1, /* Alarm clock. */ __SYS_SIGALRM = 2, /* Access to an undefined portion of a memory object. */ __SYS_SIGBUS = 3, /* Child process terminated, stopped, or continued. */ __SYS_SIGCHLD = 4, /* Continue executing, if stopped. */ __SYS_SIGCONT = 5, /* Erroneous arithmetic operation. */ __SYS_SIGFPE = 6, /* Hangup. */ __SYS_SIGHUP = 7, /* Illegal instruction. */ __SYS_SIGILL = 8, /* Terminal interrupt signal. */ __SYS_SIGINT = 9, /* Kill (cannot be caught or ignored). */ __SYS_SIGKILL = 10, /* Write on a pipe with no one to read it. */ __SYS_SIGPIPE = 11, /* Terminal quit signal. */ __SYS_SIGQUIT = 12, /* Invalid memory reference. */ __SYS_SIGSEGV = 13, /* Stop executing (cannot be caught or ignored). */ __SYS_SIGSTOP = 14, /* Termination signal. */ __SYS_SIGTERM = 15, /* Terminal stop signal. */ __SYS_SIGTSTP = 16, /* Background process attempting read. */ __SYS_SIGTTIN = 17, /* Background process attempting write. */ __SYS_SIGTTOU = 18, /* User-defined signal 1. */ __SYS_SIGUSR1 = 19, /* User-defined signal 2. */ __SYS_SIGUSR2 = 20, /* Pollable event. */ __SYS_SIGPOLL = 21, /* Profiling timer expired. */ __SYS_SIGPROF = 22, /* Bad system call. */ __SYS_SIGSYS = 23, /* Trace/breakpoint trap. */ __SYS_SIGTRAP = 24, /* High bandwidth data is available at a socket. */ __SYS_SIGURG = 25, /* Virtual timer expired. */ __SYS_SIGVTALRM = 26, /* CPU time limit exceeded. */ __SYS_SIGXCPU = 27, /* File size limit exceeded. */ __SYS_SIGXFSZ = 28, /** * Reserved * These are just to match Linux's signal numbers. */ __SYS_SIGCOMP1 = 29, __SYS_SIGCOMP2 = 30, __SYS_SIGCOMP3 = 31, /* Real-time signals. */ __SYS_SIGRTMIN = 32, __SYS_SIGRT_1 = 33, __SYS_SIGRT_2 = 34, __SYS_SIGRT_3 = 35, __SYS_SIGRT_4 = 36, __SYS_SIGRT_5 = 37, __SYS_SIGRT_6 = 38, __SYS_SIGRT_7 = 39, __SYS_SIGRT_8 = 40, __SYS_SIGRT_9 = 41, __SYS_SIGRT_10 = 42, __SYS_SIGRT_11 = 43, __SYS_SIGRT_12 = 44, __SYS_SIGRT_13 = 45, __SYS_SIGRT_14 = 46, __SYS_SIGRT_15 = 47, __SYS_SIGRT_16 = 48, __SYS_SIGRT_17 = 49, __SYS_SIGRT_18 = 50, __SYS_SIGRT_19 = 51, __SYS_SIGRT_20 = 52, __SYS_SIGRT_21 = 53, __SYS_SIGRT_22 = 54, __SYS_SIGRT_23 = 55, __SYS_SIGRT_24 = 56, __SYS_SIGRT_25 = 57, __SYS_SIGRT_26 = 58, __SYS_SIGRT_27 = 59, __SYS_SIGRT_28 = 60, __SYS_SIGRT_29 = 61, __SYS_SIGRT_30 = 62, __SYS_SIGRT_31 = 63, __SYS_SIGRTMAX = 64, /* Maximum signal number. */ __SYS_SIGNAL_MAX = __SYS_SIGRTMAX } syscall_signal_t; #ifdef __kernel__ typedef syscall_signal_t signal_t; #endif typedef enum { /** Terminate the process. */ __SYS_SIG_TERM = 0, /** Ignore the signal. */ __SYS_SIG_IGN = 1, /** Continue the process. */ __SYS_SIG_CONT = 2, /** Stop the process. */ __SYS_SIG_STOP = 3, /** Dump core. */ __SYS_SIG_CORE = 4 } syscall_signal_disposition_t; #ifdef __kernel__ typedef syscall_signal_disposition_t signal_disposition_t; #endif typedef enum { __SYS_SIG_BLOCK = 0, __SYS_SIG_UNBLOCK = 1, __SYS_SIG_SETMASK = 2 } syscall_signal_actions_t; typedef enum { __SYS_SA_NOCLDSTOP = 1, __SYS_SA_ONSTACK = 0x08000000, __SYS_SA_RESETHAND = 0x80000000, __SYS_SA_RESTART = 0x10000000, __SYS_SA_SIGINFO = 4, __SYS_SA_NOCLDWAIT = 2, __SYS_SA_NODEFER = 0x40000000, } syscall_signal_action_flags_t; typedef enum { __SYS_SIG_ERR = -1, __SYS_SIG_DFL = 0, ___SYS_SIG_IGN = 1 } syscall_signal_action_disposition_t; typedef enum { __SYS_CLOCK_MONOTONIC = 1, __SYS_CLOCK_PROCESS_CPUTIME_ID = 2, __SYS_CLOCK_REALTIME = 3, __SYS_CLOCK_THREAD_CPUTIME_ID = 4, } syscall_clockid_t; #ifndef __cplusplus _Static_assert((int)__SYS_SIG_IGN == (int)___SYS_SIG_IGN, "SIG_IGN values do not match"); #else static_assert((int)__SYS_SIG_IGN == (int)___SYS_SIG_IGN, "SIG_IGN values do not match"); #endif typedef int __SYS_clockid_t; typedef unsigned int __SYS_socklen_t; typedef struct FramebufferScreenInfo { __UINT32_TYPE__ Width; __UINT32_TYPE__ Height; __UINT32_TYPE__ Pitch; __UINT32_TYPE__ Bpp; __UINT32_TYPE__ Size; } FramebufferScreenInfo; /** * @brief Get framebuffer screen info * * @code * struct FramebufferScreenInfo info; * int ioctl(fd, FBIOGET_SCREEN_INFO, &info); * @endcode * * @param fd File descriptor of the framebuffer device * @param info Pointer to the framebuffer screen info structure */ #define FBIOGET_SCREEN_INFO 0xf0 struct kutsname { char sysname[65]; char release[65]; char version[65]; char machine[65]; }; /** * @brief List of syscalls * * @details This list contains all the syscalls of the Fennix Kernel API. * */ typedef enum { /* Initialization */ /** * @brief Set syscall version * * @code * int api_version(int version); * @endcode * * @details This syscall is used to set the version of the list. * To prevent applications from breaking on major changes, this should * be called at the very beginning of the program. * * @param version The version of the syscall list of which the program * was compiled with * * @return * - #EOK on success * - #EINVAL if the requested version is invalid * * @note If this syscall is not used, the latest version will be used. */ SYS_API_VERSION = 0, /* I/O */ /** * @brief Read from a file descriptor * * @code * ssize_t sys_read(int fildes, void *buf, size_t nbyte); * @endcode * * @details Reads up to `count` bytes from the file descriptor `fd` into * the buffer starting at `buf`. * * @param fd File descriptor to read from * @param buf Buffer where data will be stored * @param count Maximum number of bytes to read * * @return * - Number of bytes read on success * - 0 if the end of file is reached * - #EFAULT if the buffer is outside accessible address space * - #EBADF if `fd` is not a valid file descriptor */ SYS_READ = 100, /** * @brief Read from a file descriptor * * @code * ssize_t sys_pread(int fildes, void *buf, size_t nbyte, off_t offset); * @endcode * * @details Reads up to `count` bytes from the file descriptor `fd` into * the buffer starting at `buf`. * * @param fd File descriptor to read from * @param buf Buffer where data will be stored * @param count Maximum number of bytes to read * @param offset Offset in the file * * @return * - Number of bytes read on success * - 0 if the end of file is reached * - #EFAULT if the buffer is outside accessible address space * - #EBADF if `fd` is not a valid file descriptor */ SYS_PREAD, /** * @brief Write to a file descriptor * * @code * ssize_t sys_write(int fildes, const void *buf, size_t nbyte); * @endcode * * @details Writes up to `count` bytes from the buffer starting at `buf` * to the file descriptor `fd`. * * @param fd File descriptor to write to * @param buf Buffer containing data to write * @param count Number of bytes to write * * @return * - Number of bytes written on success * - #EFAULT if the buffer is outside accessible address space * - #EBADF if `fd` is not a valid file descriptor * - #EPIPE if writing to a pipe with no reader */ SYS_WRITE, /** * @brief Write to a file descriptor * * @code * ssize_t sys_pwrite(int fildes, const void *buf, size_t nbyte, off_t offset); * @endcode * * @details Writes up to `count` bytes from the buffer starting at `buf` * to the file descriptor `fd`. * * @param fd File descriptor to write to * @param buf Buffer containing data to write * @param count Number of bytes to write * @param offset Offset in the file * * @return * - Number of bytes written on success * - #EFAULT if the buffer is outside accessible address space * - #EBADF if `fd` is not a valid file descriptor */ SYS_PWRITE, /** * @brief Open a file * * @code * int open(const char *pathname, int flags, mode_t mode); * @endcode * * @details Opens the file specified by `pathname`. * * @param pathname Path to the file * @param flags Flags for file access mode\n * Supported values: * - #__SYS_O_RDONLY: Open file for reading only. * - #__SYS_O_WRONLY: Open file for writing only. * - #__SYS_O_RDWR: Open file for reading and writing. * - #__SYS_O_APPEND: Append data to the end of file. * - #__SYS_O_CREAT: Create file if it does not exist. * - #__SYS_O_DSYNC: * - #__SYS_O_EXCL: * - #__SYS_O_NOCTTY: * - #__SYS_O_NONBLOCK: * - #__SYS_O_RSYNC: * - #__SYS_O_SYNC: * - #__SYS_O_TRUNC: Truncate file to zero length. * @param mode Permissions for newly created file (if applicable) * * @return * - File descriptor on success * - #ENOENT if the file does not exist * - #EACCES if permissions are insufficient * * @see #syscall_open_flags_t */ SYS_OPEN, /** * @brief Close a file descriptor * * @code * int close(int fd); * @endcode * * @details Closes the file descriptor `fd`, releasing its resources. * * @param fd File descriptor to close * * @return * - #EOK on success * - #EBADF if `fd` is not a valid file descriptor */ SYS_CLOSE, /** * @brief Control a device * * @code * int ioctl(int fd, unsigned long request, void *argp); * @endcode * * @details Manipulates the underlying parameters of a device. * * @param fd File descriptor referring to the device * @param request Device-specific request code * @param argp Argument for the request * * @return * - #EOK on success * - #EBADF if `fd` is not valid * - #EINVAL if the request is invalid */ SYS_IOCTL, /** * @brief Function control * * @code * int fcntl(int fd, int cmd, void *arg); * @endcode * * @details Manipulates the underlying parameters of a device. * * @param fd File descriptor referring to the device * @param cmd Device-specific request code * @param arg Argument for the request * * @return * - #EOK on success * - #EBADF if `fd` is not valid * - #EINVAL if the request is invalid */ SYS_FCNTL, /* File Status */ /** * @brief Retrieve file status * * @code * int stat(const char *pathname, struct stat *statbuf); * @endcode * * @details Gets the status of the file specified by `pathname`. * * @param pathname Path to the file * @param statbuf Buffer to store file status * * @return * - #EOK on success * - #ENOENT if the file does not exist * - #EACCES if permissions are insufficient */ SYS_STAT = 200, /** * @brief Retrieve file status for an open file descriptor * * @code * int fstat(int fd, struct stat *statbuf); * @endcode * * @details Gets the status of the file referred to by `fd`. * * @param fd File descriptor * @param statbuf Buffer to store file status * * @return * - #EOK on success * - #EBADF if `fd` is not a valid file descriptor * - #EFAULT if `statbuf` is outside accessible address space */ SYS_FSTAT, /** * @brief Retrieve file status with symbolic link resolution * * @code * int lstat(const char *pathname, struct stat *statbuf); * @endcode * * @details Gets the status of the file specified by `pathname`, * but does not follow symbolic links. * * @param pathname Path to the file * @param statbuf Buffer to store file status * * @return * - #EOK on success * - #ENOENT if the file does not exist * - #EACCES if permissions are insufficient */ SYS_LSTAT, /** * @brief Check a file's accessibility * * @code * int access(const char *pathname, int mode); * @endcode * * @details Checks if the calling process can access the file specified * by `pathname` according to the specified `mode`. * * @param pathname Path to the file * @param mode Accessibility check mode\n * Supported values: * - #__SYS_F_OK: Check if the file exists * - #__SYS_R_OK: Check if the file is readable * - #__SYS_W_OK: Check if the file is writable * - #__SYS_X_OK: Check if the file is executable * * @return * - #EOK on success * - #EACCES if access is denied * - #ENOENT if the file does not exist * * @see #syscall_access_flags_t */ SYS_ACCESS, /** * @brief Change the size of a file * * @code * int truncate(const char *pathname, off_t length); * @endcode * * @details Sets the size of the file specified by `pathname` to `length`. * If the file is shorter, it is extended and the extended part is zero-filled. * * @param pathname Path to the file * @param length Desired file length * * @return * - #EOK on success * - #EINVAL if `length` is invalid * - #EACCES if permissions are insufficient */ SYS_TRUNCATE, /** * @brief Change the size of a file referred by a file descriptor * * @code * int ftruncate(int fd, off_t length); * @endcode * * @details Sets the size of the file referred to by `fd` to `length`. * * @param fd File descriptor * @param length Desired file length * * @return * - #EOK on success * - #EBADF if `fd` is not valid * - #EINVAL if `length` is invalid */ SYS_FTRUNCATE, /** * @brief Get the current file offset * * @code * off_t tell(int fd); * @endcode * * @details Returns the current file offset for the file referred to by `fd`. * * @param fd File descriptor * * @return * - Current file offset on success * - #EBADF if `fd` is not a valid file descriptor */ SYS_TELL, /** * @brief Set the file offset * * @code * off_t seek(int fd, off_t offset, int whence); * @endcode * * @details Sets the file offset for the file referred to by `fd` to the * specified `offset` according to the directive `whence`. * * @param fd File descriptor * @param offset Offset to set * @param whence Directive for setting the offset\n * Supported values: * - #__SYS_SEEK_SET: Set the offset to `offset` bytes * - #__SYS_SEEK_CUR: Set the offset to the current offset plus `offset` * - #__SYS_SEEK_END: Set the offset to the size of the file plus `offset` * * @return * - New file offset on success * - #EBADF if `fd` is not a valid file descriptor * - #EINVAL if `whence` is invalid */ SYS_SEEK, /* Process Control */ /** * @brief Terminate the calling process * * @code * void exit(int status); * @endcode * * @details Terminates the calling process with the specified `status`. * The status code is made available to the parent process. * * @param status Exit status code * * @return This function does not return. */ SYS_EXIT = 300, /** * @brief Create a child process * * @code * pid_t fork(void); * @endcode * * @details Creates a new process by duplicating the calling process. * The child process has its own copy of the parent's address space. * * @return * - 0 to the child process * - PID of the child to the parent process * - #ENOMEM if memory is insufficient */ SYS_FORK, /** * @brief Execute a program * * @code * int execve(const char *pathname, char *const argv[], char *const envp[]); * @endcode * * @details Replaces the current process image with a new process image * specified by `pathname`. * * @param pathname Path to the executable file * @param argv Argument vector * @param envp Environment variables * * @return * - Does not return on success * - #ENOENT if the file does not exist * - #EACCES if permissions are insufficient */ SYS_EXECVE, /** * @brief Get the process ID of the calling process * * @code * pid_t getpid(void); * @endcode * * @details Returns the process ID of the calling process. * * @return * - Process ID on success */ SYS_GETPID, /** * @brief Get the parent process ID * * @code * pid_t getppid(void); * @endcode * * @details Returns the parent process ID of the calling process. * * @return * - Parent process ID on success */ SYS_GETPPID, /** * @brief Wait for a child process to change state * * @code * pid_t waitpid(pid_t pid, int *wstatus, int options); * @endcode * * @details Waits for the child process specified by `pid` to change state. * * @param pid Process ID to wait for * @param wstatus Pointer to store the status information * @param options Options for waiting behavior * * @return * - Process ID of the child on success * - #ECHILD if no child processes exist */ SYS_WAITPID, /** * @brief Send a signal to a process * * @code * int kill(pid_t pid, int sig); * @endcode * * @details Sends the signal `sig` to the process specified by `pid`. * * @param pid Process ID * @param sig Signal to send * * @return * - #EOK on success * - #ESRCH if the process does not exist * - #EINVAL if `sig` is invalid */ SYS_KILL, /** * @brief Process/Thread Control * * @code * int prctl(syscall_prctl_options_t option, unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4); * @endcode * * @details Perform various operations on a process or thread. * * @param option Operation to perform * @param arg1 Argument 1 * @param arg2 Argument 2 * @param arg3 Argument 3 * @param arg4 Argument 4 * * @return * - #EOK on success * - #EINVAL if the operation is invalid * - #EFAULT if one of the arguments is invalid */ SYS_PRCTL, /* Memory */ /** * @brief Set the program break * * @code * int brk(void *end_data); * @endcode * * @details Increases or decreases the program’s data space, ending at `end_data`. * * @param end_data New program break location * * @return * - #EOK on success * - #ENOMEM if memory allocation fails */ SYS_BRK = 400, /** * @brief Map files or devices into memory * * @code * void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); * @endcode * * @details Maps a file or device into memory. This can be used for memory-mapped I/O or * for sharing memory between processes. * * @param addr Desired starting address of the mapping (NULL for automatic allocation) * @param length Length of the mapping * @param prot Desired memory protection\n * Supported values: * - #__SYS_PROT_READ: Readable * - #__SYS_PROT_WRITE: Writable * - #__SYS_PROT_EXEC: Executable * - #__SYS_PROT_NONE: No access * @param flags Mapping options\n * Supported values: * - #__SYS_MAP_SHARED: Share memory with other processes * - #__SYS_MAP_PRIVATE: Create a private copy of the file * - #__SYS_MAP_FIXED: Use `addr` as the starting address of the mapping * - #__SYS_MAP_ANONYMOUS: Create an anonymous mapping * @param fd File descriptor for the file to map * @param offset Offset in the file to start the mapping * * @return There are several possible return values: * - Pointer to mapped area on success * - #EACCES * - #EAGAIN * - #EBADF * - #EINVAL * - #EMFILE * - #ENODEV * - #ENOMEM * - #ENOTSUP * - #ENXIO * - #EOVERFLOW * * @see #syscall_mmap_flags_t */ SYS_MMAP, /** * @brief Unmap a mapped memory region * * @code * int munmap(void *addr, size_t length); * @endcode * * @details Unmaps a previously mapped memory region, making the memory available for reuse. * * @param addr Start address of the memory region * @param length Length of the memory region to unmap * * @return * - #EOK on success * - #EINVAL if the address or length is invalid * - #EFAULT if the memory region is not currently mapped */ SYS_MUNMAP, /** * @brief Change memory protection * * @code * int mprotect(void *addr, size_t length, int prot); * @endcode * * @details Sets the protection on the memory region starting at `addr` for `length`. * * @param addr Start address of the memory region * @param length Length of the memory region * @param prot Desired memory protection (e.g., PROT_READ, PROT_WRITE) * * @return * - #EOK on success * - #EACCES if protection cannot be set */ SYS_MPROTECT, /** * @brief Provide advice about memory usage * * @code * int madvise(void *addr, size_t length, int advice); * @endcode * * @details Provides advice to the kernel about the expected behavior of the memory region * starting at `addr` for `length`, such as whether it will be accessed randomly or sequentially. * * @param addr Start address of the memory region * @param length Length of the memory region * @param advice Desired advice (e.g., MADV_DONTNEED, MADV_SEQUENTIAL) * * @return * - #EOK on success * - #EINVAL if the parameters are invalid */ SYS_MADVISE, /* Communication */ /** * @brief Create a pipe * * @code * int pipe(int pipefd[2]); * @endcode * * @details Creates a pipe, returning two file descriptors in `pipefd`. One is for reading, * and the other is for writing. * * @param pipefd Array to store the two file descriptors * * @return * - #EOK on success * - #EMFILE if the process has too many open file descriptors */ SYS_PIPE = 500, /** * @brief Duplicate a file descriptor * * @code * int dup(int oldfd); * @endcode * * @details Duplicates the file descriptor `oldfd`, returning the new file descriptor. * * @param oldfd File descriptor to duplicate * * @return * - New file descriptor on success * - #EBADF if `oldfd` is invalid */ SYS_DUP, /** * @brief Duplicate a file descriptor to a specific value * * @code * int dup2(int oldfd, int newfd); * @endcode * * @details Duplicates `oldfd` to `newfd`. If `newfd` is already open, it will be closed first. * * @param oldfd File descriptor to duplicate * @param newfd File descriptor to duplicate `oldfd` to * * @return * - `newfd` on success * - #EBADF if `oldfd` is invalid * - #EINVAL if `newfd` is invalid */ SYS_DUP2, /** * @brief Create an endpoint for communication * * @code * int socket(int domain, int type, int protocol); * @endcode * * @details Creates an endpoint for communication, returning a socket file descriptor. * * @param domain Communication domain (e.g., AF_INET for IPv4) * @param type Type of socket (e.g., SOCK_STREAM for TCP) * @param protocol Protocol to use (e.g., IPPROTO_TCP) * * @return * - Socket file descriptor on success * - #EINVAL if parameters are invalid */ SYS_SOCKET, /** * @brief Bind a socket to a local address * * @code * int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); * @endcode * * @details Binds a socket to a local address so it can listen for incoming connections. * * @param sockfd Socket file descriptor * @param addr Address to bind to * @param addrlen Length of the address * * @return * - #EOK on success * - #EINVAL if the socket is invalid */ SYS_BIND, /** * @brief Connect to a remote address * * @code * int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); * @endcode * * @details Connects a socket to a remote address. * * @param sockfd Socket file descriptor * @param addr Remote address to connect to * @param addrlen Length of the address * * @return * - #EOK on success * - #EINVAL if parameters are invalid */ SYS_CONNECT, /** * @brief Listen for incoming connections on a socket * * @code * int listen(int sockfd, int backlog); * @endcode * * @details Sets a socket to listen for incoming connections, specifying the backlog queue size. * * @param sockfd Socket file descriptor * @param backlog Number of pending connections to allow * * @return * - #EOK on success * - #EINVAL if parameters are invalid */ SYS_LISTEN, /** * @brief Accept an incoming connection on a socket * * @code * int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); * @endcode * * @details Accepts an incoming connection on a listening socket, creating a new socket for communication. * * @param sockfd Socket file descriptor * @param addr Client address * @param addrlen Length of the address * * @return * - New socket file descriptor on success * - #EINVAL if parameters are invalid */ SYS_ACCEPT, /** * @brief Send data on a socket * * @code * ssize_t send(int sockfd, const void *buf, size_t len, int flags); * @endcode * * @details Sends data through a socket. * * @param sockfd Socket file descriptor * @param buf Data to send * @param len Length of the data * @param flags Flags for the send operation * * @return * - Number of bytes sent on success * - #EINVAL if parameters are invalid */ SYS_SEND, /** * @brief Receive data on a socket * * @code * ssize_t recv(int sockfd, void *buf, size_t len, int flags); * @endcode * * @details Receives data from a socket. * * @param sockfd Socket file descriptor * @param buf Buffer to store received data * @param len Maximum number of bytes to receive * @param flags Flags for the receive operation * * @return * - Number of bytes received on success * - #EINVAL if parameters are invalid */ SYS_RECV, /** * @brief Shut down part of a full-duplex connection * * @code * int shutdown(int sockfd, int how); * @endcode * * @details Shuts down part of a full-duplex connection on a socket. * * @param sockfd Socket file descriptor * @param how Determines which operations to shut down (e.g., SHUT_RD, SHUT_WR) * * @return * - #EOK on success * - #EINVAL if parameters are invalid */ SYS_SHUTDOWN, /* Time */ /** * @brief Get the current time * * @code * time_t time(time_t *t); * @endcode * * @details Retrieves the current calendar time as the number of seconds since the epoch. * * @param t Pointer to store the time (optional) * * @return * - Current time in seconds on success * - #__SYS_NULL if `t` is NULL */ SYS_TIME = 600, /** * @brief Get the current time of a specific clock * * @code * int clock_gettime(clockid_t clockid, struct timespec *tp); * @endcode * * @details Retrieves the current time for the specified clock (`CLOCK_REALTIME`, `CLOCK_MONOTONIC`, etc.). * * @param clockid Clock ID to query * @param tp Pointer to store the time * * @return * - #EOK on success * - #EINVAL if parameters are invalid */ SYS_CLOCK_GETTIME, /** * @brief Set the current time of a specific clock * * @code * int clock_settime(clockid_t clockid, const struct timespec *tp); * @endcode * * @details Sets the time for the specified clock (`CLOCK_REALTIME`, `CLOCK_MONOTONIC`, etc.). * * @param clockid Clock ID to set * @param tp Pointer to the time value * * @return * - #EOK on success * - #EINVAL if parameters are invalid */ SYS_CLOCK_SETTIME, /** * @brief Sleep for a specified time * * @code * int nanosleep(const struct timespec *req, struct timespec *rem); * @endcode * * @details Suspends the execution of the calling thread for the specified time duration. * * @param req Pointer to `timespec` specifying the time to sleep * @param rem Pointer to store remaining time if interrupted * * @return * - #EOK on success * - #EINTR if interrupted by a signal */ SYS_NANOSLEEP, /* Miscellaneous */ /** * @brief Get the current working directory * * @code * char *getcwd(char *buf, size_t size); * @endcode * * @details Retrieves the current working directory. * * @param buf Buffer to store the directory path * @param size Size of the buffer * * @return * - Pointer to `buf` on success * - #__SYS_NULL on error */ SYS_GETCWD = 700, /** * @brief Change the current working directory * * @code * int chdir(const char *path); * @endcode * * @details Changes the current working directory to the specified `path`. * * @param path New directory path * * @return * - #EOK on success * - #ENOENT if the directory does not exist * - #EACCES if permission is denied */ SYS_CHDIR, /** * @brief Create a new directory * * @code * int mkdir(const char *path, mode_t mode); * @endcode * * @details Creates a new directory at `path` with the specified permissions. * * @param path Path to the new directory * @param mode Directory permissions * * @return * - #EOK on success * - #EEXIST if the directory already exists * - #EACCES if permission is denied */ SYS_MKDIR, /** * @brief Remove an empty directory * * @code * int rmdir(const char *path); * @endcode * * @details Removes the empty directory specified by `path`. * * @param path Path to the directory * * @return * - #EOK on success * - #ENOTEMPTY if the directory is not empty */ SYS_RMDIR, /** * @brief Remove a file * * @code * int unlink(const char *pathname); * @endcode * * @details Removes the file specified by `pathname`. * * @param pathname Path to the file * * @return * - #EOK on success * - #ENOENT if the file does not exist * - #EACCES if permission is denied */ SYS_UNLINK, /** * @brief Rename a file or directory * * @code * int rename(const char *oldpath, const char *newpath); * @endcode * * @details Renames a file or directory from `oldpath` to `newpath`. * * @param oldpath Current name of the file or directory * @param newpath New name of the file or directory * * @return * - #EOK on success * - #EEXIST if the target exists * - #EACCES if permission is denied */ SYS_RENAME, /** * @brief Get unix name information * * @code * int uname(struct kutsname *buf); * @endcode * * @details Retrieves information about the operating system. * * @param buf Pointer to `kutsname` structure to store information * * @return * - #EOK on success * - #EFAULT if `buf` is outside accessible address space */ SYS_UNAME, /** * @brief Max number of syscalls * * @details This is used to determine the size of the `syscalls_t` array. * * @code * syscalls_t syscalls[SYS_MAX]; * @endcode * * @note This must be the last element in the list */ SYS_MAX } syscalls_t; /* Initialization */ /** @copydoc SYS_API_VERSION */ #define call_api_version(version) syscall1(SYS_API_VERSION, (scarg)version) /* I/O */ /** @copydoc SYS_READ */ #define call_read(fd, buf, count) syscall3(SYS_READ, (scarg)fd, (scarg)buf, (scarg)count) /** @copydoc SYS_PREAD */ #define call_pread(fd, buf, count, offset) syscall4(SYS_PREAD, (scarg)fd, (scarg)buf, (scarg)count, (scarg)offset) /** @copydoc SYS_WRITE */ #define call_write(fd, buf, count) syscall3(SYS_WRITE, (scarg)fd, (scarg)buf, (scarg)count) /** @copydoc SYS_PWRITE */ #define call_pwrite(fd, buf, count, offset) syscall4(SYS_PWRITE, (scarg)fd, (scarg)buf, (scarg)count, (scarg)offset) /** @copydoc SYS_OPEN */ #define call_open(pathname, flags, mode) syscall3(SYS_OPEN, (scarg)pathname, (scarg)flags, (scarg)mode) /** @copydoc SYS_CLOSE */ #define call_close(fd) syscall1(SYS_CLOSE, fd) /** @copydoc SYS_IOCTL */ #define call_ioctl(fd, request, argp) syscall3(SYS_IOCTL, (scarg)fd, (scarg)request, (scarg)argp) /** @copydoc SYS_FCNTL */ #define call_fcntl(fd, cmd, arg) syscall3(SYS_FCNTL, (scarg)fd, (scarg)cmd, (scarg)arg) /* File Status */ /** @copydoc SYS_STAT */ #define call_stat(pathname, statbuf) syscall2(SYS_STAT, (scarg)pathname, (scarg)statbuf) /** @copydoc SYS_FSTAT */ #define call_fstat(fd, statbuf) syscall2(SYS_FSTAT, (scarg)fd, (scarg)statbuf) /** @copydoc SYS_LSTAT */ #define call_lstat(pathname, statbuf) syscall2(SYS_LSTAT, (scarg)pathname, (scarg)statbuf) /** @copydoc SYS_ACCESS */ #define call_access(pathname, mode) syscall2(SYS_ACCESS, (scarg)pathname, (scarg)mode) /** @copydoc SYS_TRUNCATE */ #define call_truncate(pathname, length) syscall2(SYS_TRUNCATE, (scarg)pathname, (scarg)length) /** @copydoc SYS_FTRUNCATE */ #define call_ftruncate(fd, length) syscall2(SYS_FTRUNCATE, (scarg)fd, (scarg)length) /** @copydoc SYS_TELL */ #define call_tell(fd) syscall1(SYS_TELL, (scarg)fd) /** @copydoc SYS_SEEK */ #define call_seek(fd, offset, whence) syscall3(SYS_SEEK, (scarg)fd, (scarg)offset, (scarg)whence) /* Process Control */ /** @copydoc SYS_EXIT */ #define call_exit(status) syscall1(SYS_EXIT, (scarg)status) /** @copydoc SYS_FORK */ #define call_fork() syscall0(SYS_FORK) /** @copydoc SYS_EXECVE */ #define call_execve(pathname, argv, envp) syscall3(SYS_EXECVE, (scarg)pathname, (scarg)argv, (scarg)envp) /** @copydoc SYS_GETPID */ #define call_getpid() syscall0(SYS_GETPID) /** @copydoc SYS_GETPPID */ #define call_getppid() syscall0(SYS_GETPPID) /** @copydoc SYS_WAITPID */ #define call_waitpid(pid, wstatus, options) syscall3(SYS_WAITPID, (scarg)pid, (scarg)wstatus, (scarg)options) /** @copydoc SYS_KILL */ #define call_kill(pid, sig) syscall2(SYS_KILL, (scarg)pid, (scarg)sig) /** @copydoc SYS_PRCTL */ #define call_prctl(option, arg1, arg2, arg3, arg4) syscall5(SYS_PRCTL, (scarg)option, (scarg)arg1, (scarg)arg2, (scarg)arg3, (scarg)arg4) /* Memory */ /** @copydoc SYS_BRK */ #define call_brk(end_data) syscall1(SYS_BRK, (scarg)end_data) /** @copydoc SYS_MMAP */ #define call_mmap(addr, length, prot, flags, fd, offset) syscall6(SYS_MMAP, (scarg)addr, (scarg)length, (scarg)prot, (scarg)flags, (scarg)fd, (scarg)offset) /** @copydoc SYS_MUNMAP */ #define call_munmap(addr, length) syscall2(SYS_MUNMAP, (scarg)addr, (scarg)length) /** @copydoc SYS_MPROTECT */ #define call_mprotect(addr, length, prot) syscall3(SYS_MPROTECT, (scarg)addr, (scarg)length, (scarg)prot) /** @copydoc SYS_MADVISE */ #define call_madvise(addr, length, advice) syscall3(SYS_MADVISE, (scarg)addr, (scarg)length, (scarg)advice) /* Communication */ /** @copydoc SYS_PIPE */ #define call_pipe(pipefd) syscall1(SYS_PIPE, (scarg)pipefd) /** @copydoc SYS_DUP */ #define call_dup(oldfd) syscall1(SYS_DUP, (scarg)oldfd) /** @copydoc SYS_DUP2 */ #define call_dup2(oldfd, newfd) syscall2(SYS_DUP2, (scarg)oldfd, (scarg)newfd) /** @copydoc SYS_SOCKET */ #define call_socket(domain, type, protocol) syscall3(SYS_SOCKET, (scarg)domain, (scarg)type, (scarg)protocol) /** @copydoc SYS_BIND */ #define call_bind(sockfd, addr, addrlen) syscall3(SYS_BIND, (scarg)sockfd, (scarg)addr, (scarg)addrlen) /** @copydoc SYS_CONNECT */ #define call_connect(sockfd, addr, addrlen) syscall3(SYS_CONNECT, (scarg)sockfd, (scarg)addr, (scarg)addrlen) /** @copydoc SYS_LISTEN */ #define call_listen(sockfd, backlog) syscall2(SYS_LISTEN, (scarg)sockfd, (scarg)backlog) /** @copydoc SYS_ACCEPT */ #define call_accept(sockfd, addr, addrlen) syscall3(SYS_ACCEPT, (scarg)sockfd, (scarg)addr, (scarg)addrlen) /** @copydoc SYS_SEND */ #define call_send(sockfd, buf, len, flags) syscall4(SYS_SEND, (scarg)sockfd, (scarg)buf, (scarg)len, (scarg)flags) /** @copydoc SYS_RECV */ #define call_recv(sockfd, buf, len, flags) syscall4(SYS_RECV, (scarg)sockfd, (scarg)buf, (scarg)len, (scarg)flags) /** @copydoc SYS_SHUTDOWN */ #define call_shutdown(sockfd, how) syscall2(SYS_SHUTDOWN, (scarg)sockfd, (scarg)how) /* Time */ /** @copydoc SYS_TIME */ #define call_time(t) syscall1(SYS_TIME, t) /** @copydoc SYS_CLOCK_GETTIME */ #define call_clock_gettime(clockid, tp) syscall2(SYS_CLOCK_GETTIME, (scarg)clockid, (scarg)tp) /** @copydoc SYS_CLOCK_SETTIME */ #define call_clock_settime(clockid, tp) syscall2(SYS_CLOCK_SETTIME, (scarg)clockid, (scarg)tp) /** @copydoc SYS_NANOSLEEP */ #define call_nanosleep(req, rem) syscall2(SYS_NANOSLEEP, (scarg)req, (scarg)rem) /* Miscellaneous */ /** @copydoc SYS_GETCWD */ #define call_getcwd(buf, size) syscall2(SYS_GETCWD, (scarg)buf, (scarg)size) /** @copydoc SYS_CHDIR */ #define call_chdir(path) syscall1(SYS_CHDIR, (scarg)path) /** @copydoc SYS_MKDIR */ #define call_mkdir(path, mode) syscall2(SYS_MKDIR, (scarg)path, (scarg)mode) /** @copydoc SYS_RMDIR */ #define call_rmdir(path) syscall1(SYS_RMDIR, (scarg)path) /** @copydoc SYS_UNLINK */ #define call_unlink(pathname) syscall1(SYS_UNLINK, (scarg)pathname) /** @copydoc SYS_RENAME */ #define call_rename(oldpath, newpath) syscall2(SYS_RENAME, (scarg)oldpath, (scarg)newpath) /** @copydoc SYS_UNAME */ #define call_uname(buf) syscall1(SYS_UNAME, (scarg)buf) #endif // !__FENNIX_API_SYSTEM_CALLS_LIST_H__