int sys_fcntl(int fd, int cmd, int arg) { int r = -EBADF; file_t* f = file_get(fd); if (f) { r = frontend_syscall(SYS_fcntl, f->kfd, cmd, arg, 0, 0, 0, 0); file_decref(f); } return r; }
void file_decref(struct file* f) { // if you decref too many times, you'll clobber memory :( spin_lock(&f->lock); if(--f->refcnt == 0) { int ret = frontend_syscall(0,APPSERVER_SYSCALL_close,f->fd,0,0,0,NULL); assert(ret == 0); kmem_cache_free(struct_file_cache,f); } else spin_unlock(&f->lock); }
long sys_fstatat(int dirfd, const char* name, void* st, int flags) { if(name[0] == '/'){ return sys_stat(name, st); } file_t* dir = file_get(dirfd); if(dir) { size_t name_size = strlen(name)+1; populate_mapping(st, sizeof(struct stat), PROT_WRITE); return frontend_syscall(SYS_fstatat, dir->kfd, (uintptr_t)name, name_size, (uintptr_t)st, flags); } return -EBADF; }
static size_t parse_args(arg_buf* args) { long r = frontend_syscall(SYS_getmainvars, va2pa(args), sizeof(*args), 0, 0, 0, 0, 0); kassert(r == 0); uint64_t* pk_argv = &args->buf[1]; // pk_argv[0] is the proxy kernel itself. skip it and any flags. size_t pk_argc = args->buf[0], arg = 1; for ( ; arg < pk_argc && *(char*)(uintptr_t)pk_argv[arg] == '-'; arg++) handle_option((const char*)(uintptr_t)pk_argv[arg]); for (size_t i = 0; arg + i < pk_argc; i++) args->argv[i] = (char*)(uintptr_t)pk_argv[arg + i]; return pk_argc - arg; }
struct file* file_open_from_fd(struct proc* p, int fd) { struct file* f = NULL; if(!(f = kmem_cache_alloc(struct_file_cache,0))) goto out; f->fd = frontend_syscall(p->pid,APPSERVER_SYSCALL_kdup,fd,0,0,0,NULL); if(f->fd == -1) { kmem_cache_free(struct_file_cache,f); f = NULL; goto out; } spinlock_init(&f->lock); f->refcnt = 1; out: return f; }
long sys_getcwd(const char* buf, size_t size) { populate_mapping(buf, size, PROT_WRITE); return frontend_syscall(SYS_getcwd, (uintptr_t)buf, size, 0, 0, 0, 0, 0); }
long sys_mkdir(const char* name, int mode) { size_t name_size = strlen(name)+1; return frontend_syscall(SYS_mkdir, (uintptr_t)name, name_size, mode, 0, 0); }
long sys_unlink(const char* name, size_t len) { size_t name_size = strlen(name)+1; return frontend_syscall(SYS_unlink, (uintptr_t)name, name_size, 0, 0, 0); }
int sys_access(const char *name, int mode){ size_t name_size = strlen(name)+1; return frontend_syscall(SYS_access, (uintptr_t)name, name_size, mode, 0, 0); }
long sys_lstat(const char* name, void* st) { size_t name_size = strlen(name)+1; populate_mapping(st, sizeof(struct stat), PROT_WRITE); return frontend_syscall(SYS_lstat, (uintptr_t)name, name_size, (uintptr_t)st, 0, 0); }
int sys_chdir(const char *path) { return frontend_syscall(SYS_chdir, va2pa(path), 0, 0, 0, 0, 0, 0); }
void sys_exit(int code) { frontend_syscall(SYS_exit, code, 0, 0, 0); while (1); }
void __diediedie(uint32_t srcid, uint32_t code, uint32_t a1, uint32_t a2) { int32_t errno; frontend_syscall(0,APPSERVER_SYSCALL_exit,(int)code,0,0,0,&errno); while(1); }