| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #include <errno.h> |
| #include <stdio.h> |
| #include <sys/types.h> |
| #include <unistd.h> |
| #include <string.h> |
| #include <sys/resource.h> |
| #include <sys/stat.h> |
| #include <time.h> |
| #include <sys/utsname.h> |
| #include <emscripten/syscalls.h> |
| #include <emscripten/console.h> |
| #include <emscripten/version.h> |
| #include <emscripten/stack.h> |
|
|
| static int g_pid = 42; |
| static int g_pgid = 42; |
| static int g_ppid = 1; |
| static int g_sid = 42; |
|
|
| #ifdef NDEBUG |
| #define REPORT(name) |
| #else |
| #define REPORT(name) \ |
| emscripten_err("warning: unsupported syscall: __syscall_" #name); |
| #endif |
|
|
| #define UNIMPLEMENTED(name, args) \ |
| weak int __syscall_##name args { \ |
| REPORT(name); \ |
| return -ENOSYS; \ |
| } |
|
|
| #define STRINGIFY(s) #s |
| #define STR(s) STRINGIFY(s) |
|
|
| weak int __syscall_uname(intptr_t buf) { |
| if (!buf) { |
| return -EFAULT; |
| } |
| const char* full_version = STR(__EMSCRIPTEN_MAJOR__) "." \ |
| STR(__EMSCRIPTEN_MINOR__) "." \ |
| STR(__EMSCRIPTEN_TINY__); |
|
|
| struct utsname *utsname = (struct utsname *)buf; |
|
|
| strcpy(utsname->sysname, "Emscripten"); |
| strcpy(utsname->nodename, "emscripten"); |
| strcpy(utsname->release, full_version); |
| strcpy(utsname->version, "#1"); |
| #ifdef __wasm64__ |
| strcpy(utsname->machine, "wasm64"); |
| #else |
| strcpy(utsname->machine, "wasm32"); |
| #endif |
| return 0; |
| } |
|
|
| weak int __syscall_setpgid(int pid, int pgid) { |
| if (pid && pid != g_pid) { |
| return -ESRCH; |
| } |
| if (pgid && pgid != g_pgid) { |
| return -EPERM; |
| } |
| return 0; |
| } |
|
|
| weak int __syscall_sync() { |
| return 0; |
| } |
|
|
| weak int __syscall_getsid(int pid) { |
| if (pid && pid != g_pid) { |
| return -ESRCH; |
| } |
| return g_sid; |
| } |
|
|
| weak int __syscall_getpgid(int pid) { |
| if (pid && pid != g_pid) { |
| return -ESRCH; |
| } |
| return g_pgid; |
| } |
|
|
| weak int __syscall_getpid() { |
| return g_pid; |
| } |
|
|
| weak int __syscall_getppid() { |
| return g_ppid; |
| } |
|
|
| weak int __syscall_linkat(int olddirfd, intptr_t oldpath, int newdirfd, intptr_t newpath, int flags) { |
| return -EMLINK; |
| } |
|
|
| weak int __syscall_getgroups32(int size, intptr_t list) { |
| if (size < 1) { |
| return -EINVAL; |
| } |
| ((gid_t*)list)[0] = 0; |
| return 1; |
| } |
|
|
| weak int __syscall_setsid() { |
| return 0; |
| } |
|
|
| struct kusage { |
| long utime_tv_sec; |
| long utime_tv_usec; |
| long stime_tv_sec; |
| long stime_tv_usec; |
| }; |
|
|
| weak int __syscall_getrusage(int who, intptr_t usage) { |
| REPORT(getrusage); |
| struct kusage *u = (struct kusage*)usage; |
| u->utime_tv_sec = 1; |
| u->utime_tv_usec = 2; |
| u->stime_tv_sec = 3; |
| u->stime_tv_usec = 4; |
| return 0; |
| } |
|
|
| weak int __syscall_getpriority(int which, int who) { |
| return 0; |
| } |
|
|
| weak int __syscall_setpriority(int which, int who, int prio) { |
| return -EPERM; |
| } |
|
|
| weak int __syscall_setdomainname(intptr_t name, size_t size) { |
| return -EPERM; |
| } |
|
|
| weak int __syscall_getuid32(void) { |
| return 0; |
| } |
|
|
| weak int __syscall_getgid32(void) { |
| return 0; |
| } |
|
|
| weak int __syscall_geteuid32(void) { |
| return 0; |
| } |
|
|
| weak int __syscall_getegid32(void) { |
| return 0; |
| } |
|
|
| weak int __syscall_getresuid32(intptr_t ruid, intptr_t euid, intptr_t suid) { |
| *((uid_t *)ruid) = 0; |
| *((uid_t *)euid) = 0; |
| *((uid_t *)suid) = 0; |
| return 0; |
| } |
|
|
| weak int __syscall_getresgid32(intptr_t ruid, intptr_t euid, intptr_t suid) { |
| REPORT(getresgid32); |
| *((uid_t *)ruid) = 0; |
| *((uid_t *)euid) = 0; |
| *((uid_t *)suid) = 0; |
| return 0; |
| } |
|
|
| weak int __syscall_pause() { |
| REPORT(pause); |
| return -EINTR; |
| } |
|
|
| weak int __syscall_madvise(intptr_t addr, size_t length, int advice) { |
| REPORT(madvise); |
| |
| return 0; |
| } |
|
|
| weak int __syscall_mlock(intptr_t addr, size_t len) { |
| REPORT(mlock); |
| return 0; |
| } |
|
|
| weak int __syscall_munlock(intptr_t addr, size_t len) { |
| REPORT(munlock); |
| return 0; |
| } |
|
|
| weak int __syscall_mprotect(size_t addr, size_t len, int prot) { |
| REPORT(mprotect); |
| return 0; |
| } |
|
|
| weak int __syscall_mremap(intptr_t old_addr, size_t old_size, size_t new_size, int flags, intptr_t new_addr) { |
| REPORT(mremap); |
| return -ENOMEM; |
| } |
|
|
| weak int __syscall_mlockall(int flags) { |
| REPORT(mlockall); |
| return 0; |
| } |
|
|
| weak int __syscall_munlockall() { |
| REPORT(munlockall); |
| return 0; |
| } |
|
|
| weak int __syscall_prlimit64(int pid, int resource, intptr_t new_limit, intptr_t old_limit) { |
| REPORT(prlimit64); |
| struct rlimit *old = (struct rlimit *)old_limit; |
| if (new_limit) { |
| return -EPERM; |
| } |
| if (old) { |
| if (resource == RLIMIT_NOFILE) { |
| |
| old->rlim_cur = 4096; |
| old->rlim_max = 4096; |
| } else if (resource == RLIMIT_STACK) { |
| uintptr_t end = emscripten_stack_get_end(); |
| uintptr_t base = emscripten_stack_get_base(); |
|
|
| old->rlim_cur = base - end; |
| |
| old->rlim_max = base - end; |
| } else { |
| |
| old->rlim_cur = RLIM_INFINITY; |
| old->rlim_max = RLIM_INFINITY; |
| } |
| } |
| return 0; |
| } |
|
|
| weak int __syscall_setsockopt(int sockfd, int level, int optname, intptr_t optval, size_t optlen, int dummy) { |
| REPORT(setsockopt); |
| return -ENOPROTOOPT; |
| } |
|
|
| UNIMPLEMENTED(acct, (intptr_t filename)) |
| UNIMPLEMENTED(mincore, (intptr_t addr, size_t length, intptr_t vec)) |
| UNIMPLEMENTED(recvmmsg, (int sockfd, intptr_t msgvec, size_t vlen, int flags, ...)) |
| UNIMPLEMENTED(sendmmsg, (int sockfd, intptr_t msgvec, size_t vlen, int flags, ...)) |
| UNIMPLEMENTED(shutdown, (int sockfd, int how, int dummy, int dummy2, int dummy3, int dummy4)) |
| UNIMPLEMENTED(socketpair, (int domain, int type, int protocol, intptr_t fds, int dummy, int dummy2)) |
| UNIMPLEMENTED(wait4,(int pid, intptr_t wstatus, int options, int rusage)) |
|
|