From 7ee786388ae0d6f8c8cea7bf012cc11fdb5b534a Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sun, 16 Jan 2022 01:18:49 +0900 Subject: [PATCH] [wasm] wasm/missing.{c,h}: add missing libc stubs for wasi-libc --- configure.ac | 23 +++++ include/ruby/missing.h | 113 +++++++++++++++++++++++ io.c | 1 + missing/flock.c | 7 ++ wasm/GNUmakefile.in | 1 + wasm/missing.c | 199 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 344 insertions(+) create mode 100644 wasm/missing.c diff --git a/configure.ac b/configure.ac index c08889c803..f6f88901bd 100644 --- a/configure.ac +++ b/configure.ac @@ -1232,6 +1232,9 @@ main() RUBY_APPEND_OPTIONS(CFLAGS, -D_WASI_EMULATED_SIGNAL -D_WASI_EMULATED_MMAN -D_WASI_EMULATED_GETPID -D_WASI_EMULATED_PROCESS_CLOCKS) RUBY_APPEND_OPTIONS(CPPFLAGS, -D_WASI_EMULATED_SIGNAL -D_WASI_EMULATED_MMAN -D_WASI_EMULATED_GETPID -D_WASI_EMULATED_PROCESS_CLOCKS) POSTLINK="\$(WASMOPT) --asyncify \$(wasmoptflags) --pass-arg=asyncify-ignore-imports -o \$@ \$@${POSTLINK:+; $POSTLINK}" + # wasi-libc's sys/socket.h is not compatible with -std=gnu99, + # so re-declare shutdown in include/ruby/missing.h + ac_cv_func_shutdown=no ] [ LIBS="-lm $LIBS"]) : ${ORIG_LIBS=$LIBS} @@ -1294,6 +1297,7 @@ AC_CHECK_HEADERS(sanitizer/asan_interface.h) AC_CHECK_HEADERS(sanitizer/msan_interface.h) AC_CHECK_HEADERS(setjmpex.h) AC_CHECK_HEADERS(stdalign.h) +AC_CHECK_HEADERS(stdio.h) AC_CHECK_HEADERS(sys/attr.h) AC_CHECK_HEADERS(sys/eventfd.h) AC_CHECK_HEADERS(sys/fcntl.h) @@ -1967,6 +1971,8 @@ AC_CHECK_FUNCS(_longjmp) # used for AC_ARG_WITH(setjmp-type) test x$ac_cv_func__longjmp = xno && ac_cv_func__setjmp=no AC_CHECK_FUNCS(arc4random_buf) AC_CHECK_FUNCS(atan2l atan2f) +AC_CHECK_FUNCS(chmod) +AC_CHECK_FUNCS(chown) AC_CHECK_FUNCS(chroot) AC_CHECK_FUNCS(chsize) AC_CHECK_FUNCS(clock_gettime) @@ -1982,6 +1988,9 @@ AC_CHECK_FUNCS(dup3) AC_CHECK_FUNCS(eaccess) AC_CHECK_FUNCS(endgrent) AC_CHECK_FUNCS(eventfd) +AC_CHECK_FUNCS(execl) +AC_CHECK_FUNCS(execle) +AC_CHECK_FUNCS(execve) AC_CHECK_FUNCS(explicit_memset) AC_CHECK_FUNCS(fcopyfile) AC_CHECK_FUNCS(fchmod) @@ -1997,7 +2006,10 @@ AC_CHECK_FUNCS(ftruncate) AC_CHECK_FUNCS(ftruncate64) # used for Win32 platform AC_CHECK_FUNCS(getattrlist) AC_CHECK_FUNCS(getcwd) +AC_CHECK_FUNCS(getegid) AC_CHECK_FUNCS(getentropy) +AC_CHECK_FUNCS(geteuid) +AC_CHECK_FUNCS(getgid) AC_CHECK_FUNCS(getgidx) AC_CHECK_FUNCS(getgrnam) AC_CHECK_FUNCS(getgrnam_r) @@ -2006,6 +2018,7 @@ AC_CHECK_FUNCS(getlogin) AC_CHECK_FUNCS(getlogin_r) AC_CHECK_FUNCS(getpgid) AC_CHECK_FUNCS(getpgrp) +AC_CHECK_FUNCS(getppid) AC_CHECK_FUNCS(getpriority) AC_CHECK_FUNCS(getpwnam) AC_CHECK_FUNCS(getpwnam_r) @@ -2017,6 +2030,7 @@ AC_CHECK_FUNCS(getresuid) AC_CHECK_FUNCS(getrlimit) AC_CHECK_FUNCS(getsid) AC_CHECK_FUNCS(gettimeofday) # for making ac_cv_func_gettimeofday +AC_CHECK_FUNCS(getuid) AC_CHECK_FUNCS(getuidx) AC_CHECK_FUNCS(gmtime_r) AC_CHECK_FUNCS(grantpt) @@ -2024,6 +2038,7 @@ AC_CHECK_FUNCS(initgroups) AC_CHECK_FUNCS(ioctl) AC_CHECK_FUNCS(isfinite) AC_CHECK_FUNCS(issetugid) +AC_CHECK_FUNCS(kill) AC_CHECK_FUNCS(killpg) AC_CHECK_FUNCS(lchmod) AC_CHECK_FUNCS(lchown) @@ -2047,9 +2062,13 @@ AC_CHECK_FUNCS(mktime) AC_CHECK_FUNCS(mmap) AC_CHECK_FUNCS(mremap) AC_CHECK_FUNCS(openat) +AC_CHECK_FUNCS(pclose) +AC_CHECK_FUNCS(pipe) AC_CHECK_FUNCS(pipe2) AC_CHECK_FUNCS(poll) +AC_CHECK_FUNCS(popen) AC_CHECK_FUNCS(posix_fadvise) +AC_CHECK_FUNCS(posix_madvise) AC_CHECK_FUNCS(posix_memalign) AC_CHECK_FUNCS(ppoll) AC_CHECK_FUNCS(pread) @@ -2088,12 +2107,15 @@ AC_CHECK_FUNCS(spawnv) AC_CHECK_FUNCS(symlink) AC_CHECK_FUNCS(syscall) AC_CHECK_FUNCS(sysconf) +AC_CHECK_FUNCS(system) AC_CHECK_FUNCS(tanh) AC_CHECK_FUNCS(telldir) AC_CHECK_FUNCS(timegm) AC_CHECK_FUNCS(times) AC_CHECK_FUNCS(truncate) AC_CHECK_FUNCS(truncate64) # used for Win32 +AC_CHECK_FUNCS(tzset) +AC_CHECK_FUNCS(umask) AC_CHECK_FUNCS(unsetenv) AC_CHECK_FUNCS(utimensat) AC_CHECK_FUNCS(utimes) @@ -3807,6 +3829,7 @@ AS_CASE(["$target_os"], ], [wasi*], [ FIRSTMAKEFILE=GNUmakefile:wasm/GNUmakefile.in + AC_LIBOBJ([wasm/missing]) AC_LIBOBJ([wasm/runtime]) AC_LIBOBJ([wasm/fiber]) AC_LIBOBJ([wasm/machine]) diff --git a/include/ruby/missing.h b/include/ruby/missing.h index 1e97e294f1..aea6c9088d 100644 --- a/include/ruby/missing.h +++ b/include/ruby/missing.h @@ -33,6 +33,18 @@ # include #endif +#ifdef HAVE_SYS_STAT_H +# include +#endif + +#ifdef HAVE_UNISTD_H +# include +#endif + +#ifdef HAVE_STDIO_H +# include +#endif + #ifdef HAVE_IEEEFP_H # include #endif @@ -224,6 +236,107 @@ RUBY_EXTERN void setproctitle(const char *fmt, ...); RUBY_EXTERN void explicit_bzero(void *b, size_t len); #endif +#ifndef HAVE_TZSET +RUBY_EXTERN void tzset(void); +#endif + +#ifndef HAVE_POSIX_MADVISE +RUBY_EXTERN int posix_madvise(void *, size_t, int); +#endif + +#ifndef HAVE_GETEUID +RUBY_EXTERN rb_uid_t geteuid(void); +#endif + +#ifndef HAVE_GETUID +RUBY_EXTERN rb_uid_t getuid(void); +#endif + +#ifndef HAVE_GETEGID +RUBY_EXTERN rb_gid_t getegid(void); +#endif + +#ifndef HAVE_GETGID +RUBY_EXTERN rb_gid_t getgid(void); +#endif + +#ifndef HAVE_GETLOGIN +RUBY_EXTERN char *getlogin(void); +#endif + +#ifndef HAVE_GETPPID +RUBY_EXTERN rb_pid_t getppid(void); +#endif + +#ifndef HAVE_UMASK +RUBY_EXTERN rb_mode_t umask(rb_mode_t); +#endif + +#ifndef HAVE_CHMOD +RUBY_EXTERN int chmod(const char *, rb_mode_t); +#endif + +#ifndef HAVE_CHOWN +RUBY_EXTERN int chown(const char *, rb_uid_t, rb_gid_t); +#endif + +#ifndef HAVE_PCLOSE +RUBY_EXTERN int pclose(FILE *); +#endif + +#ifndef HAVE_POPEN +RUBY_EXTERN FILE *popen(const char *, const char *); +#endif + +#ifndef HAVE_PIPE +RUBY_EXTERN int pipe(int [2]); +#endif + +#ifndef HAVE_DUP +RUBY_EXTERN int dup(int); +#endif + +#ifndef HAVE_DUP2 +RUBY_EXTERN int dup2(int, int); +#endif + +#ifndef HAVE_KILL +RUBY_EXTERN int kill(rb_pid_t, int); +#endif + +#ifndef HAVE_EXECL +RUBY_EXTERN int execl(const char *, const char *, ...); +#endif + +#ifndef HAVE_EXECLE +RUBY_EXTERN int execle(const char *, const char *, ...); +#endif + +#ifndef HAVE_EXECV +RUBY_EXTERN int execv(const char *, char *const []); +#endif + +#ifndef HAVE_EXECVE +RUBY_EXTERN int execve(const char *, char *const [], char *const []); +#endif + +#ifndef HAVE_SHUTDOWN +RUBY_EXTERN int shutdown(int, int); +#endif + +#ifndef HAVE_SYSTEM +RUBY_EXTERN int system(const char *); +#endif + +#ifndef WNOHANG +# define WNOHANG 0 +#endif + +#ifndef HAVE_WAITPID +# define HAVE_WAITPID 1 +RUBY_EXTERN rb_pid_t waitpid(rb_pid_t, int *, int); +#endif + RBIMPL_SYMBOL_EXPORT_END() #endif /* RUBY_MISSING_H */ diff --git a/io.c b/io.c index 237bb9becc..e278f25cad 100644 --- a/io.c +++ b/io.c @@ -133,6 +133,7 @@ #include "internal/variable.h" #include "ruby/io.h" #include "ruby/io/buffer.h" +#include "ruby/missing.h" #include "ruby/thread.h" #include "ruby/util.h" #include "ruby_atomic.h" diff --git a/missing/flock.c b/missing/flock.c index c0b3f80601..9daf1c38cc 100644 --- a/missing/flock.c +++ b/missing/flock.c @@ -2,6 +2,13 @@ #include "ruby/ruby.h" #if defined _WIN32 +#elif defined __wasi__ +#include + +int flock(int fd, int operation) { + errno = EINVAL; + return -1; +} #elif defined HAVE_FCNTL && defined HAVE_FCNTL_H /* These are the flock() constants. Since this systems doesn't have diff --git a/wasm/GNUmakefile.in b/wasm/GNUmakefile.in index b3b427e023..4328dec9c6 100644 --- a/wasm/GNUmakefile.in +++ b/wasm/GNUmakefile.in @@ -8,6 +8,7 @@ wasmoptflags = @wasmoptflags@ WASM_OBJS = $(wasmdir)/machine_core.o $(wasmdir)/machine.o $(wasmdir)/setjmp.o $(wasmdir)/setjmp_core.o $(wasmdir)/fiber.o $(wasmdir)/runtime.o +wasm/missing.$(OBJEXT): $(wasmdir)/missing.c $(PLATFORM_D) wasm/fiber.$(OBJEXT): $(wasmdir)/fiber.c $(wasmdir)/fiber.h $(wasmdir)/asyncify.h $(PLATFORM_D) wasm/machine.$(OBJEXT): $(wasmdir)/machine.c $(srcdir)/wasm/machine.h $(wasmdir)/asyncify.h $(PLATFORM_D) wasm/setjmp.$(OBJEXT): $(wasmdir)/setjmp.c $(wasmdir)/setjmp.h $(wasmdir)/machine.h $(wasmdir)/asyncify.h $(PLATFORM_D) diff --git a/wasm/missing.c b/wasm/missing.c new file mode 100644 index 0000000000..5bbf988642 --- /dev/null +++ b/wasm/missing.c @@ -0,0 +1,199 @@ +#include +#include +#include "ruby/missing.h" + +// Produce weak symbols for missing functions to replace them with actual ones if exists. +#define WASM_MISSING_LIBC_FUNC __attribute__((weak)) + +WASM_MISSING_LIBC_FUNC +int +chmod(const char *pathname, rb_mode_t mode) +{ + errno = ENOTSUP; + return -1; +} + +WASM_MISSING_LIBC_FUNC +int +chown(const char *pathname, rb_uid_t owner, rb_gid_t group) +{ + errno = ENOTSUP; + return -1; +} + +WASM_MISSING_LIBC_FUNC +int +dup(int oldfd) +{ + errno = ENOTSUP; + return -1; +} + +WASM_MISSING_LIBC_FUNC +int +dup2(int oldfd, int newfd) +{ + errno = ENOTSUP; + return -1; +} + +WASM_MISSING_LIBC_FUNC +int +execl(const char *path, const char *arg, ...) +{ + errno = ENOTSUP; + return -1; +} + +WASM_MISSING_LIBC_FUNC +int +execle(const char *path, const char *arg, ...) +{ + errno = ENOTSUP; + return -1; +} + +WASM_MISSING_LIBC_FUNC +int +execv(const char *path, char *const argv[]) +{ + errno = ENOTSUP; + return -1; +} + +WASM_MISSING_LIBC_FUNC +int +execve(const char *filename, char *const argv[], char *const envp[]) +{ + errno = ENOTSUP; + return -1; +} + +WASM_MISSING_LIBC_FUNC +rb_uid_t +geteuid(void) +{ + return 0; +} + +WASM_MISSING_LIBC_FUNC +rb_uid_t +getuid(void) +{ + return 0; +} + +WASM_MISSING_LIBC_FUNC +rb_pid_t +getppid(void) +{ + return 0; +} + +WASM_MISSING_LIBC_FUNC +rb_gid_t +getegid(void) +{ + return 0; +} + +WASM_MISSING_LIBC_FUNC +rb_gid_t +getgid(void) +{ + return 0; +} + +WASM_MISSING_LIBC_FUNC +char * +getlogin(void) +{ + errno = ENOTSUP; + return NULL; +} + +WASM_MISSING_LIBC_FUNC +rb_mode_t +umask(rb_mode_t mask) +{ + return 0; +} + +WASM_MISSING_LIBC_FUNC +int +mprotect(const void *addr, size_t len, int prot) +{ + return 0; +} + +WASM_MISSING_LIBC_FUNC +int +pclose(FILE *stream) +{ + errno = ENOTSUP; + return -1; +} + +WASM_MISSING_LIBC_FUNC +FILE * +popen(const char *command, const char *type) +{ + errno = ENOTSUP; + return NULL; +} + +WASM_MISSING_LIBC_FUNC +int +pipe(int pipefd[2]) +{ + errno = ENOTSUP; + return -1; +} + +WASM_MISSING_LIBC_FUNC +int +posix_madvise(void *addr, size_t len, int advice) +{ + errno = ENOTSUP; + return -1; +} + +WASM_MISSING_LIBC_FUNC +int +kill(rb_pid_t pid, int sig) +{ + errno = ENOTSUP; + return -1; +} + + +WASM_MISSING_LIBC_FUNC +void +tzset(void) +{ + return; +} + +WASM_MISSING_LIBC_FUNC +int +shutdown(int s, int how) +{ + errno = ENOTSUP; + return -1; +} + +WASM_MISSING_LIBC_FUNC +int +system(const char *command) +{ + errno = ENOTSUP; + return -1; +} + +WASM_MISSING_LIBC_FUNC +pid_t +waitpid(pid_t pid, int *wstatus, int options) +{ + errno = ENOTSUP; + return -1; +}