#include "unistd.h"
#include "syscall.h"
#include "errno.h"
#include "termios.h"
int read(int fd, void* buf, size_t count) {
return __syscall_ret(_syscall3(SYS_READ, fd, (int)buf, (int)count));
}
int write(int fd, const void* buf, size_t count) {
return __syscall_ret(_syscall3(SYS_WRITE, fd, (int)buf, (int)count));
}
int open(const char* path, int flags, ...) {
(void)flags; /* mode arg unused by kernel currently */
return __syscall_ret(_syscall2(SYS_OPEN, (int)path, flags));
}
int close(int fd) {
return __syscall_ret(_syscall1(SYS_CLOSE, fd));
}
int lseek(int fd, int offset, int whence) {
return __syscall_ret(_syscall3(SYS_LSEEK, fd, offset, whence));
}
int dup(int oldfd) {
return __syscall_ret(_syscall1(SYS_DUP, oldfd));
}
int dup2(int oldfd, int newfd) {
return __syscall_ret(_syscall2(SYS_DUP2, oldfd, newfd));
}
int pipe(int fds[2]) {
return __syscall_ret(_syscall1(SYS_PIPE, (int)fds));
}
int fork(void) {
return __syscall_ret(_syscall0(SYS_FORK));
}
int execve(const char* path, char* const argv[], char* const envp[]) {
return __syscall_ret(_syscall3(SYS_EXECVE, (int)path, (int)argv, (int)envp));
}
int execveat(int dirfd, const char* path, char* const argv[], char* const envp[], int flags) {
return __syscall_ret(_syscall5(SYS_EXECVEAT, dirfd, (int)path, (int)argv, (int)envp, flags));
}
int getpid(void) {
return _syscall0(SYS_GETPID);
}
int getppid(void) {
return _syscall0(SYS_GETPPID);
}
int chdir(const char* path) {
return __syscall_ret(_syscall1(SYS_CHDIR, (int)path));
}
int getcwd(char* buf, size_t size) {
return __syscall_ret(_syscall2(SYS_GETCWD, (int)buf, (int)size));
}
int mkdir(const char* path, ...) {
return __syscall_ret(_syscall1(SYS_MKDIR, (int)path));
}
int unlink(const char* path) {
return __syscall_ret(_syscall1(SYS_UNLINK, (int)path));
}
int rmdir(const char* path) {
return __syscall_ret(_syscall1(SYS_RMDIR, (int)path));
}
int setsid(void) {
return __syscall_ret(_syscall0(SYS_SETSID));
}
int setpgid(int pid, int pgid) {
return __syscall_ret(_syscall2(SYS_SETPGID, pid, pgid));
}
int getpgrp(void) {
return __syscall_ret(_syscall0(SYS_GETPGRP));
}
int gettid(void) {
return _syscall0(SYS_GETTID);
}
int fsync(int fd) {
return __syscall_ret(_syscall1(SYS_FSYNC, fd));
}
int fdatasync(int fd) {
return __syscall_ret(_syscall1(SYS_FDATASYNC, fd));
}
int pread(int fd, void* buf, size_t count, int offset) {
return __syscall_ret(_syscall4(SYS_PREAD, fd, (int)buf, (int)count, offset));
}
int pwrite(int fd, const void* buf, size_t count, int offset) {
return __syscall_ret(_syscall4(SYS_PWRITE, fd, (int)buf, (int)count, offset));
}
int access(const char* path, int mode) {
return __syscall_ret(_syscall2(SYS_ACCESS, (int)path, mode));
}
int getuid(void) {
return _syscall0(SYS_GETUID);
}
int getgid(void) {
return _syscall0(SYS_GETGID);
}
int geteuid(void) {
return _syscall0(SYS_GETEUID);
}
int getegid(void) {
return _syscall0(SYS_GETEGID);
}
int setuid(int uid) {
return __syscall_ret(_syscall1(SYS_SETUID, uid));
}
int setgid(int gid) {
return __syscall_ret(_syscall1(SYS_SETGID, gid));
}
int seteuid(int euid) {
return __syscall_ret(_syscall1(SYS_SETEUID, euid));
}
int setegid(int egid) {
return __syscall_ret(_syscall1(SYS_SETEGID, egid));
}
int truncate(const char* path, int length) {
return __syscall_ret(_syscall2(SYS_TRUNCATE, (int)path, length));
}
int ftruncate(int fd, int length) {
return __syscall_ret(_syscall2(SYS_FTRUNCATE, fd, length));
}
unsigned int alarm(unsigned int seconds) {
return (unsigned int)_syscall1(SYS_ALARM, (int)seconds);
}
int setitimer(int which, const void* new_value, void* old_value) {
return __syscall_ret(_syscall3(SYS_SETITIMER, which, (int)new_value, (int)old_value));
}
int getitimer(int which, void* curr_value) {
return __syscall_ret(_syscall2(SYS_GETITIMER, which, (int)curr_value));
}
int flock(int fd, int operation) {
return __syscall_ret(_syscall2(SYS_FLOCK, fd, operation));
}
void* brk(void* addr) {
return (void*)_syscall1(SYS_BRK, (int)addr);
}
int isatty(int fd) {
/* POSIX: isatty() returns 1 if fd refers to a terminal, 0 otherwise.
* Implementation: try TCGETS ioctl; if it succeeds, fd is a tty. */
struct { uint32_t a,b,c,d; uint8_t e[8]; } t;
int rc = _syscall3(SYS_IOCTL, fd, 0x5401 /* TCGETS */, (int)&t);
return (rc == 0) ? 1 : 0;
}
int waitpid(int pid, int* status, int options) {
return __syscall_ret(_syscall3(SYS_WAITPID, pid, (int)status, options));
}
int getdents(int fd, void* buf, size_t count) {
return __syscall_ret(_syscall3(SYS_GETDENTS, fd, (int)buf, (int)count));
}
int stat(const char* path, void* buf) {
return __syscall_ret(_syscall2(SYS_STAT, (int)path, (int)buf));
}
int fstat(int fd, void* buf) {
return __syscall_ret(_syscall2(SYS_FSTAT, fd, (int)buf));
}
int chmod(const char* path, int mode) {
return __syscall_ret(_syscall2(SYS_CHMOD, (int)path, mode));
}
int chown(const char* path, int owner, int group) {
return __syscall_ret(_syscall3(SYS_CHOWN, (int)path, owner, group));
}
int link(const char* oldpath, const char* newpath) {
return __syscall_ret(_syscall2(SYS_LINK, (int)oldpath, (int)newpath));
}
int symlink(const char* target, const char* linkpath) {
return __syscall_ret(_syscall2(SYS_SYMLINK, (int)target, (int)linkpath));
}
int readlink(const char* path, char* buf, size_t bufsiz) {
return __syscall_ret(_syscall3(SYS_READLINK, (int)path, (int)buf, (int)bufsiz));
}
int tcgetattr(int fd, struct termios* t) {
return __syscall_ret(_syscall3(SYS_IOCTL, fd, 0x5401 /* TCGETS */, (int)t));
}
int tcsetattr(int fd, int actions, const struct termios* t) {
int cmd = 0x5402; /* TCSETS */
if (actions == 1) cmd = 0x5403; /* TCSETSW */
else if (actions == 2) cmd = 0x5404; /* TCSETSF */
return __syscall_ret(_syscall3(SYS_IOCTL, fd, cmd, (int)t));
}
void _exit(int status) {
_syscall1(SYS_EXIT, status);
/* If exit syscall somehow returns, loop forever.
* Cannot use hlt — it's privileged and causes #GP in ring 3. */
for (;;) __asm__ volatile("nop");
}
int execle(const char* path, const char* arg, ...) {
/* Walk varargs to find argv[] and the trailing envp */
const char* args[32];
int n = 0;
__builtin_va_list ap;
__builtin_va_start(ap, arg);
args[n++] = arg;
while (n < 31) {
const char* a = __builtin_va_arg(ap, const char*);
args[n++] = a;
if (!a) break;
}
args[n] = (void*)0;
char* const* envp = __builtin_va_arg(ap, char* const*);
__builtin_va_end(ap);
return execve(path, (char* const*)args, envp);
}
static char _login_buf[32] = "root";
char* getlogin(void) {
return _login_buf;
}
int getlogin_r(char* buf, size_t bufsize) {
extern size_t strlen(const char*);
extern void* memcpy(void*, const void*, size_t);
const char* name = getlogin();
size_t len = strlen(name);
if (len + 1 > bufsize) return 34; /* ERANGE */
memcpy(buf, name, len + 1);
return 0;
}
long confstr(int name, char* buf, size_t len) {
(void)name;
const char* val = "/bin:/usr/bin";
extern size_t strlen(const char*);
size_t vlen = strlen(val) + 1;
if (buf && len > 0) {
size_t copy = vlen < len ? vlen : len;
extern void* memcpy(void*, const void*, size_t);
memcpy(buf, val, copy);
if (copy < vlen && len > 0) buf[len - 1] = '\0';
}
return (long)vlen;
}
void* sbrk(int increment) {
void* cur = brk((void*)0);
if (increment == 0) return cur;
void* new_end = (void*)((char*)cur + increment);
void* result = brk(new_end);
if ((unsigned int)result < (unsigned int)new_end) return (void*)-1;
return cur;
}