]> git.proxmox.com Git - wasi-libc.git/commitdiff
Replace old <signal.h> support with emulated <signal.h> support. (#183)
authorDan Gohman <sunfish@mozilla.com>
Fri, 29 May 2020 20:07:52 +0000 (13:07 -0700)
committerGitHub <noreply@github.com>
Fri, 29 May 2020 20:07:52 +0000 (13:07 -0700)
wasm doesn't support signals, so provide an emulation layer, enabled
with -D_WASI_EMULATED_SIGNAL and -lwasi-emulated-signal.

Makefile
basics/sources/abort.c
expected/wasm32-wasi/include-all.c
expected/wasm32-wasi/predefined-macros.txt
libc-bottom-half/headers/public/__header_bits_signal.h [deleted file]
libc-bottom-half/signal/signal.c [new file with mode: 0644]
libc-top-half/musl/arch/wasm32/bits/signal.h
libc-top-half/musl/include/signal.h
libc-top-half/musl/src/conf/sysconf.c
libc-top-half/musl/src/include/signal.h

index 48b09b007be1a069916fa2ea94f4b81b81c5e10d..d904be5de868dba0ddfa0d88236c658ff291eb84 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -62,6 +62,11 @@ LIBC_BOTTOM_HALF_ALL_SOURCES = \
     $(shell find $(LIBC_BOTTOM_HALF_SOURCES) -name \*.c)
 LIBWASI_EMULATED_MMAN_SOURCES = \
     $(shell find $(LIBC_BOTTOM_HALF_DIR)/mman -name \*.c)
+LIBWASI_EMULATED_SIGNAL_SOURCES = \
+    $(shell find $(LIBC_BOTTOM_HALF_DIR)/signal -name \*.c)
+LIBWASI_EMULATED_SIGNAL_MUSL_SOURCES = \
+    $(LIBC_TOP_HALF_MUSL_SRC_DIR)/signal/psignal.c \
+    $(LIBC_TOP_HALF_MUSL_SRC_DIR)/string/strsignal.c
 LIBC_BOTTOM_HALF_CRT_SOURCES = $(wildcard $(LIBC_BOTTOM_HALF_DIR)/crt/*.c)
 LIBC_TOP_HALF_DIR = $(CURDIR)/libc-top-half
 LIBC_TOP_HALF_MUSL_DIR = $(LIBC_TOP_HALF_DIR)/musl
@@ -232,6 +237,8 @@ MUSL_PRINTSCAN_OBJS = $(call objs,$(MUSL_PRINTSCAN_SOURCES))
 MUSL_PRINTSCAN_LONG_DOUBLE_OBJS = $(patsubst %.o,%.long-double.o,$(MUSL_PRINTSCAN_OBJS))
 MUSL_PRINTSCAN_NO_FLOATING_POINT_OBJS = $(patsubst %.o,%.no-floating-point.o,$(MUSL_PRINTSCAN_OBJS))
 LIBWASI_EMULATED_MMAN_OBJS = $(call objs,$(LIBWASI_EMULATED_MMAN_SOURCES))
+LIBWASI_EMULATED_SIGNAL_OBJS = $(call objs,$(LIBWASI_EMULATED_SIGNAL_SOURCES))
+LIBWASI_EMULATED_SIGNAL_MUSL_OBJS = $(call objs,$(LIBWASI_EMULATED_SIGNAL_MUSL_SOURCES))
 
 # These variables describe the locations of various files and
 # directories in the generated sysroot tree.
@@ -333,6 +340,8 @@ $(SYSROOT_LIB)/libc-printscan-no-floating-point.a: $(MUSL_PRINTSCAN_NO_FLOATING_
 
 $(SYSROOT_LIB)/libwasi-emulated-mman.a: $(LIBWASI_EMULATED_MMAN_OBJS)
 
+$(SYSROOT_LIB)/libwasi-emulated-signal.a: $(LIBWASI_EMULATED_SIGNAL_OBJS) $(LIBWASI_EMULATED_SIGNAL_MUSL_OBJS)
+
 %.a:
        @mkdir -p "$(@D)"
        # On Windows, the commandline for the ar invocation got too long, so it needs to be split up.
@@ -352,6 +361,9 @@ $(MUSL_PRINTSCAN_NO_FLOATING_POINT_OBJS): WASM_CFLAGS += \
            -D__wasilibc_printscan_no_floating_point \
            -D__wasilibc_printscan_floating_point_support_option="\"remove -lc-printscan-no-floating-point from the link command\""
 
+$(LIBWASI_EMULATED_SIGNAL_MUSL_OBJS): WASM_CFLAGS += \
+           -D_WASI_EMULATED_SIGNAL
+
 $(OBJDIR)/%.long-double.o: $(CURDIR)/%.c include_dirs
        @mkdir -p "$(@D)"
        "$(WASM_CC)" $(WASM_CFLAGS) -MD -MP -o $@ -c $<
@@ -374,7 +386,7 @@ startup_files $(LIBC_BOTTOM_HALF_ALL_OBJS): WASM_CFLAGS += \
     -I$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC_INC) \
     -I$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC)
 
-$(LIBC_TOP_HALF_ALL_OBJS) $(MUSL_PRINTSCAN_LONG_DOUBLE_OBJS) $(MUSL_PRINTSCAN_NO_FLOATING_POINT_OBJS): WASM_CFLAGS += \
+$(LIBC_TOP_HALF_ALL_OBJS) $(MUSL_PRINTSCAN_LONG_DOUBLE_OBJS) $(MUSL_PRINTSCAN_NO_FLOATING_POINT_OBJS) $(LIBWASI_EMULATED_SIGNAL_MUSL_OBJS): WASM_CFLAGS += \
     -I$(LIBC_TOP_HALF_MUSL_SRC_DIR)/include \
     -I$(LIBC_TOP_HALF_MUSL_SRC_DIR)/internal \
     -I$(LIBC_TOP_HALF_MUSL_DIR)/arch/wasm32 \
@@ -434,7 +446,8 @@ libc: include_dirs \
     $(SYSROOT_LIB)/libc.a \
     $(SYSROOT_LIB)/libc-printscan-long-double.a \
     $(SYSROOT_LIB)/libc-printscan-no-floating-point.a \
-    $(SYSROOT_LIB)/libwasi-emulated-mman.a
+    $(SYSROOT_LIB)/libwasi-emulated-mman.a \
+    $(SYSROOT_LIB)/libwasi-emulated-signal.a
 
 finish: startup_files libc
        #
@@ -458,7 +471,7 @@ finish: startup_files libc
        @# since these dependencies can vary between llvm versions.
        "$(WASM_NM)" --defined-only "$(SYSROOT_LIB)"/libc.a "$(SYSROOT_LIB)"/*.o \
            |grep ' [[:upper:]] ' |sed 's/.* [[:upper:]] //' |LC_ALL=C sort > "$(SYSROOT_SHARE)/defined-symbols.txt"
-       for undef_sym in $$("$(WASM_NM)" --undefined-only "$(SYSROOT_LIB)"/*.a "$(SYSROOT_LIB)"/*.o \
+       for undef_sym in $$("$(WASM_NM)" --undefined-only "$(SYSROOT_LIB)"/libc.a "$(SYSROOT_LIB)"/libc-*.a "$(SYSROOT_LIB)"/*.o \
            |grep ' U ' |sed 's/.* U //' |LC_ALL=C sort |uniq); do \
            grep -q '\<'$$undef_sym'\>' "$(SYSROOT_SHARE)/defined-symbols.txt" || echo $$undef_sym; \
        done | grep -v "^__mul" > "$(SYSROOT_SHARE)/undefined-symbols.txt"
@@ -469,7 +482,7 @@ finish: startup_files libc
        # Generate a test file that includes all public header files.
        #
        cd "$(SYSROOT)" && \
-         for header in $$(find include -type f -not -name mman.h |grep -v /bits/); do \
+         for header in $$(find include -type f -not -name mman.h -not -name signal.h |grep -v /bits/); do \
              echo '#include <'$$header'>' | sed 's/include\///' ; \
        done |LC_ALL=C sort >share/$(MULTIARCH_TRIPLE)/include-all.c ; \
        cd - >/dev/null
index bb1c7dd49d111ee959558f4c228d1c47e7178819..95fe2be045bc6d6de9d44d311cc34fd74f48bb27 100644 (file)
@@ -1,6 +1,6 @@
 #include <stdlib.h>
 
 void abort(void) {
-    // WASI doesn't yet support signals, so just trap to halt the program.
+    // wasm doesn't support signals, so just trap to halt the program.
     __builtin_trap();
 }
index e801c08725e86badd52bc78aabf0a331fffcd032..f6ecbce4d35d863f4538505b3796d68ae6cc1ad7 100644 (file)
@@ -4,7 +4,6 @@
 #include <__function___isatty.h>
 #include <__functions_malloc.h>
 #include <__functions_memcpy.h>
-#include <__header_bits_signal.h>
 #include <__header_dirent.h>
 #include <__header_fcntl.h>
 #include <__header_inttypes.h>
 #include <sched.h>
 #include <search.h>
 #include <semaphore.h>
-#include <signal.h>
 #include <stdalign.h>
 #include <stdbool.h>
 #include <stdc-predef.h>
 #include <sys/reg.h>
 #include <sys/resource.h>
 #include <sys/select.h>
-#include <sys/signal.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/stropts.h>
index 595f343e4874ab9aa281eea5ebb5ab89a6dce082..3962db9506b8fd3ef469b5ed9da873163caaab6a 100644 (file)
 #define BLK_RESTART 0x10
 #define BREAK 243
 #define BUFSIZ 1024
-#define BUS_ADRALN 1
-#define BUS_ADRERR 2
-#define BUS_MCEERR_AO 5
-#define BUS_MCEERR_AR 4
-#define BUS_OBJERR 3
 #define BYTE_ORDER __BYTE_ORDER
 #define CANBSIZ 255
 #define CBRK CEOL
 #define CHRTYPE '3'
 #define CINTR CTRL('c')
 #define CKILL CTRL('u')
-#define CLD_CONTINUED 6
-#define CLD_DUMPED 3
-#define CLD_EXITED 1
-#define CLD_KILLED 2
-#define CLD_STOPPED 5
-#define CLD_TRAPPED 4
 #define CLNEXT CTRL('v')
 #define CLOCKS_PER_SEC ((clock_t)1000000000)
 #define CLOCK_MONOTONIC (&_CLOCK_MONOTONIC)
 #define FORM_C 3
 #define FORM_N 1
 #define FORM_T 2
-#define FPE_FLTDIV 3
-#define FPE_FLTINV 7
-#define FPE_FLTOVF 4
-#define FPE_FLTRES 6
-#define FPE_FLTSUB 8
-#define FPE_FLTUND 5
-#define FPE_INTDIV 1
-#define FPE_INTOVF 2
 #define FP_ILOGB0 FP_ILOGBNAN
 #define FP_ILOGBNAN (-1-0x7fffffff)
 #define FP_INFINITE 1
 #define IGMP_V2_MEMBERSHIP_REPORT 0x16
 #define IGMP_v1_ROUTER 1
 #define IGMP_v2_ROUTER 2
-#define ILL_BADSTK 8
-#define ILL_COPROC 7
-#define ILL_ILLADR 3
-#define ILL_ILLOPC 1
-#define ILL_ILLOPN 2
-#define ILL_ILLTRP 4
-#define ILL_PRVOPC 5
-#define ILL_PRVREG 6
 #define IN6ADDRSZ NS_IN6ADDRSZ
 #define IN6ADDR_ANY_INIT { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
 #define IN6ADDR_LOOPBACK_INIT { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
 #define SEEK_END __WASI_WHENCE_END
 #define SEEK_SET __WASI_WHENCE_SET
 #define SEGSIZE 512
-#define SEGV_ACCERR 2
-#define SEGV_BNDERR 3
-#define SEGV_MAPERR 1
-#define SEGV_PKUERR 4
 #define SEM_FAILED ((sem_t *)0)
 #define SERVFAIL ns_r_servfail
 #define SHORTBITS (sizeof(short) * 8)
 #define SHUT_RD __WASI_SDFLAGS_RD
 #define SHUT_RDWR (SHUT_RD | SHUT_WR)
 #define SHUT_WR __WASI_SDFLAGS_WR
-#define SIGABRT __WASI_SIGNAL_ABRT
-#define SIGALRM __WASI_SIGNAL_ALRM
-#define SIGBUS __WASI_SIGNAL_BUS
-#define SIGCHLD __WASI_SIGNAL_CHLD
-#define SIGCONT __WASI_SIGNAL_CONT
-#define SIGEV_NONE 1
-#define SIGEV_SIGNAL 0
-#define SIGEV_THREAD 2
-#define SIGFPE __WASI_SIGNAL_FPE
-#define SIGHUP __WASI_SIGNAL_HUP
-#define SIGILL __WASI_SIGNAL_ILL
-#define SIGINT __WASI_SIGNAL_INT
-#define SIGIO SIGPOLL
-#define SIGIOT SIGABRT
-#define SIGKILL __WASI_SIGNAL_KILL
-#define SIGPIPE __WASI_SIGNAL_PIPE
-#define SIGPOLL __WASI_SIGNAL_POLL
-#define SIGPROF __WASI_SIGNAL_PROF
-#define SIGPWR __WASI_SIGNAL_PWR
-#define SIGQUIT __WASI_SIGNAL_QUIT
-#define SIGSEGV __WASI_SIGNAL_SEGV
-#define SIGSTOP __WASI_SIGNAL_STOP
-#define SIGSYS __WASI_SIGNAL_SYS
-#define SIGTERM __WASI_SIGNAL_TERM
-#define SIGTRAP __WASI_SIGNAL_TRAP
-#define SIGTSTP __WASI_SIGNAL_TSTP
-#define SIGTTIN __WASI_SIGNAL_TTIN
-#define SIGTTOU __WASI_SIGNAL_TTOU
-#define SIGUNUSED SIGSYS
-#define SIGURG __WASI_SIGNAL_URG
-#define SIGUSR1 __WASI_SIGNAL_USR1
-#define SIGUSR2 __WASI_SIGNAL_USR2
-#define SIGVTALRM __WASI_SIGNAL_VTALRM
-#define SIGWINCH __WASI_SIGNAL_WINCH
-#define SIGXCPU __WASI_SIGNAL_XCPU
-#define SIGXFSZ __WASI_SIGNAL_XFSZ
 #define SIG_ATOMIC_MAX INT32_MAX
 #define SIG_ATOMIC_MIN INT32_MIN
-#define SIG_BLOCK 0
-#define SIG_HOLD ((void (*)(int)) 2)
-#define SIG_SETMASK 2
-#define SIG_UNBLOCK 1
 #define SIZE_MAX UINT32_MAX
-#define SI_ASYNCIO (-4)
-#define SI_ASYNCNL (-60)
-#define SI_KERNEL 128
 #define SI_LOAD_SHIFT 16
-#define SI_MESGQ (-3)
-#define SI_QUEUE (-1)
-#define SI_SIGIO (-5)
-#define SI_TIMER (-2)
-#define SI_TKILL (-6)
-#define SI_USER 0
 #define SLC_ABORT 7
 #define SLC_ACK 0x80
 #define SLC_AO 4
 #define _SC_XOPEN_XPG4 100
 #define _SEARCH_H 
 #define _SEMAPHORE_H 
-#define _SIGNAL_H 
 #define _SIZE_T 
 #define _STDALIGN_H 
 #define _STDBOOL_H 
 #define __wasilibc___errno_values_h 
 #define __wasilibc___fd_set_h 
 #define __wasilibc___function___isatty_h 
-#define __wasilibc___header_bits_signal_h 
 #define __wasilibc___header_dirent_h 
 #define __wasilibc___header_fcntl_h 
 #define __wasilibc___header_netinet_in_h 
 #define rr_code rr_hdr.icmp6_code
 #define rr_seqnum rr_hdr.icmp6_data32[0]
 #define rr_type rr_hdr.icmp6_type
-#define sa_handler __sa_handler.sa_handler
-#define sa_sigaction __sa_handler.sa_sigaction
 #define scalbln(x,y) __tg_real_2_1(scalbln, (x), (y))
 #define scalbn(x,y) __tg_real_2_1(scalbn, (x), (y))
 #define scandir64 scandir
 #define setbit(x,i) __bitop(x,i,|=)
-#define si_addr __si_fields.__sigfault.si_addr
-#define si_addr_lsb __si_fields.__sigfault.si_addr_lsb
-#define si_arch __si_fields.__sigsys.si_arch
-#define si_band __si_fields.__sigpoll.si_band
-#define si_call_addr __si_fields.__sigsys.si_call_addr
-#define si_fd __si_fields.__sigpoll.si_fd
-#define si_int si_value.sival_int
-#define si_lower __si_fields.__sigfault.__first.__addr_bnd.si_lower
-#define si_overrun __si_fields.__si_common.__first.__timer.si_overrun
-#define si_pid __si_fields.__si_common.__first.__piduid.si_pid
-#define si_pkey __si_fields.__sigfault.__first.si_pkey
-#define si_ptr si_value.sival_ptr
-#define si_status __si_fields.__si_common.__second.__sigchld.si_status
-#define si_stime __si_fields.__si_common.__second.__sigchld.si_stime
-#define si_syscall __si_fields.__sigsys.si_syscall
-#define si_timerid __si_fields.__si_common.__first.__timer.si_timerid
-#define si_uid __si_fields.__si_common.__first.__piduid.si_uid
-#define si_upper __si_fields.__sigfault.__first.__addr_bnd.si_upper
-#define si_utime __si_fields.__si_common.__second.__sigchld.si_utime
-#define si_value __si_fields.__si_common.__second.si_value
 #define signbit(x) (__builtin_signbit(x))
 #define sin(x) __tg_real_complex(sin, (x))
 #define sinh(x) __tg_real_complex(sinh, (x))
diff --git a/libc-bottom-half/headers/public/__header_bits_signal.h b/libc-bottom-half/headers/public/__header_bits_signal.h
deleted file mode 100644 (file)
index 4631259..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef __wasilibc___header_bits_signal_h
-#define __wasilibc___header_bits_signal_h
-
-#include <wasi/api.h>
-
-#define SIGHUP    __WASI_SIGNAL_HUP
-#define SIGINT    __WASI_SIGNAL_INT
-#define SIGQUIT   __WASI_SIGNAL_QUIT
-#define SIGILL    __WASI_SIGNAL_ILL
-#define SIGTRAP   __WASI_SIGNAL_TRAP
-#define SIGABRT   __WASI_SIGNAL_ABRT
-#define SIGBUS    __WASI_SIGNAL_BUS
-#define SIGFPE    __WASI_SIGNAL_FPE
-#define SIGKILL   __WASI_SIGNAL_KILL
-#define SIGUSR1   __WASI_SIGNAL_USR1
-#define SIGSEGV   __WASI_SIGNAL_SEGV
-#define SIGUSR2   __WASI_SIGNAL_USR2
-#define SIGPIPE   __WASI_SIGNAL_PIPE
-#define SIGALRM   __WASI_SIGNAL_ALRM
-#define SIGTERM   __WASI_SIGNAL_TERM
-#define SIGCHLD   __WASI_SIGNAL_CHLD
-#define SIGCONT   __WASI_SIGNAL_CONT
-#define SIGSTOP   __WASI_SIGNAL_STOP
-#define SIGTSTP   __WASI_SIGNAL_TSTP
-#define SIGTTIN   __WASI_SIGNAL_TTIN
-#define SIGTTOU   __WASI_SIGNAL_TTOU
-#define SIGURG    __WASI_SIGNAL_URG
-#define SIGXCPU   __WASI_SIGNAL_XCPU
-#define SIGXFSZ   __WASI_SIGNAL_XFSZ
-#define SIGVTALRM __WASI_SIGNAL_VTALRM
-#define SIGPROF   __WASI_SIGNAL_PROF
-#define SIGWINCH  __WASI_SIGNAL_WINCH
-#define SIGPOLL   __WASI_SIGNAL_POLL
-#define SIGPWR    __WASI_SIGNAL_PWR
-#define SIGSYS    __WASI_SIGNAL_SYS
-
-#define SIGIOT    SIGABRT
-#define SIGIO     SIGPOLL
-#define SIGUNUSED SIGSYS
-
-#endif
diff --git a/libc-bottom-half/signal/signal.c b/libc-bottom-half/signal/signal.c
new file mode 100644 (file)
index 0000000..1c24dfd
--- /dev/null
@@ -0,0 +1,142 @@
+// Userspace emulation of `raise` and `signal`.
+//
+// WebAssembly doesn't support asynchronous signal delivery, so we can't
+// support it in WASI libc. But we can make things like `raise` work.
+
+#define _WASI_EMULATED_SIGNAL
+#define _ALL_SOURCE
+#define _GNU_SOURCE
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <assert.h>
+
+void __SIG_IGN(int sig) {
+    // do nothing
+}
+
+_Noreturn
+void __SIG_ERR(int sig) {
+    __builtin_trap();
+}
+
+_Noreturn
+static void core_handler(int sig) {
+    fprintf(stderr, "Program recieved fatal signal: %s\n", strsignal(sig));
+    abort();
+}
+
+_Noreturn
+static void terminate_handler(int sig) {
+    fprintf(stderr, "Program recieved termination signal: %s\n", strsignal(sig));
+    abort();
+}
+
+_Noreturn
+static void stop_handler(int sig) {
+    fprintf(stderr, "Program recieved stop signal: %s\n", strsignal(sig));
+    abort();
+}
+
+static void continue_handler(int sig) {
+    // do nothing
+}
+
+static const sighandler_t default_handlers[_NSIG] = {
+    // Default behavior: "core".
+    [SIGABRT] = core_handler,
+    [SIGBUS] = core_handler,
+    [SIGFPE] = core_handler,
+    [SIGILL] = core_handler,
+#if SIGIOT != SIGABRT
+    [SIGIOT] = core_handler,
+#endif
+    [SIGQUIT] = core_handler,
+    [SIGSEGV] = core_handler,
+    [SIGSYS] = core_handler,
+    [SIGTRAP] = core_handler,
+    [SIGXCPU] = core_handler,
+    [SIGXFSZ] = core_handler,
+#if defined(SIGUNUSED) && SIGUNUSED != SIGSYS
+    [SIGUNUSED] = core_handler,
+#endif
+
+    // Default behavior: ignore.
+    [SIGCHLD] = SIG_IGN,
+#if defined(SIGCLD) && SIGCLD != SIGCHLD
+    [SIGCLD] = SIG_IGN,
+#endif
+    [SIGURG] = SIG_IGN,
+    [SIGWINCH] = SIG_IGN,
+
+    // Default behavior: "continue".
+    [SIGCONT] = continue_handler,
+
+    // Default behavior: "stop".
+    [SIGSTOP] = stop_handler,
+    [SIGTSTP] = stop_handler,
+    [SIGTTIN] = stop_handler,
+    [SIGTTOU] = stop_handler,
+
+    // Default behavior: "terminate".
+    [SIGHUP] = terminate_handler,
+    [SIGINT] = terminate_handler,
+    [SIGKILL] = terminate_handler,
+    [SIGUSR1] = terminate_handler,
+    [SIGUSR2] = terminate_handler,
+    [SIGPIPE] = terminate_handler,
+    [SIGALRM] = terminate_handler,
+    [SIGTERM] = terminate_handler,
+    [SIGSTKFLT] = terminate_handler,
+    [SIGVTALRM] = terminate_handler,
+    [SIGPROF] = terminate_handler,
+    [SIGIO] = terminate_handler,
+#if SIGPOLL != SIGIO
+    [SIGPOLL] = terminate_handler,
+#endif
+    [SIGPWR] = terminate_handler,
+};
+
+static sighandler_t handlers[_NSIG];
+
+int raise(int sig) {
+    if (sig < 0 || sig >= _NSIG) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    sighandler_t func = handlers[sig];
+
+    if (func == NULL) {
+        default_handlers[sig](sig);
+    } else {
+        func(sig);
+    }
+
+    return 0;
+}
+
+void (*signal(int sig, void (*func)(int)))(int) {
+    assert(SIG_DFL == NULL);
+
+    if (sig < 0 || sig >= _NSIG) {
+        errno = EINVAL;
+        return SIG_ERR;
+    }
+
+    if (sig == SIGKILL || sig == SIGSTOP) {
+        errno = EINVAL;
+        return SIG_ERR;
+    }
+
+    sighandler_t old = handlers[sig];
+
+    handlers[sig] = func;
+
+    return old;
+}
+
+extern __typeof(signal) bsd_signal __attribute__((weak, alias("signal")));
+extern __typeof(signal) __sysv_signal __attribute__((weak, alias("signal")));
index 547108772cb9984c535a4213e3114e184f5fbc4a..77e8d8c61e8c31a1104f12625ccf8b0ea17c4bf0 100644 (file)
@@ -1 +1,40 @@
-#include <__header_bits_signal.h>
+#ifdef _WASI_EMULATED_SIGNAL
+
+#define SIGHUP    1
+#define SIGINT    2
+#define SIGQUIT   3
+#define SIGILL    4
+#define SIGTRAP   5
+#define SIGABRT   6
+#define SIGIOT    SIGABRT
+#define SIGBUS    7
+#define SIGFPE    8
+#define SIGKILL   9
+#define SIGUSR1   10
+#define SIGSEGV   11
+#define SIGUSR2   12
+#define SIGPIPE   13
+#define SIGALRM   14
+#define SIGTERM   15
+#define SIGSTKFLT 16
+#define SIGCHLD   17
+#define SIGCONT   18
+#define SIGSTOP   19
+#define SIGTSTP   20
+#define SIGTTIN   21
+#define SIGTTOU   22
+#define SIGURG    23
+#define SIGXCPU   24
+#define SIGXFSZ   25
+#define SIGVTALRM 26
+#define SIGPROF   27
+#define SIGWINCH  28
+#define SIGIO     29
+#define SIGPOLL   29
+#define SIGPWR    30
+#define SIGSYS    31
+#define SIGUNUSED SIGSYS
+
+#define _NSIG 65
+
+#endif
index 068234f4c0238de815998417407455ffdb74a572..a83503294d35604a36c111b1607b0b9ae6e0da20 100644 (file)
@@ -1,3 +1,7 @@
+#ifndef _WASI_EMULATED_SIGNAL
+#error "wasm lacks signal support; to enable minimal signal emulation, \
+compile with -D_WASI_EMULATED_SIGNAL and link with -lwasi-emulated-signal"
+#else
 #ifndef _SIGNAL_H
 #define _SIGNAL_H
 
@@ -15,7 +19,6 @@ extern "C" {
 #ifdef _GNU_SOURCE
 #define __ucontext ucontext
 #endif
-#endif
 
 #define __NEED_size_t
 #define __NEED_pid_t
@@ -44,6 +47,7 @@ extern "C" {
 #define SI_KERNEL 128
 
 typedef struct sigaltstack stack_t;
+#endif
 
 #endif
 
@@ -53,6 +57,7 @@ typedef struct sigaltstack stack_t;
  || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
  || defined(_BSD_SOURCE)
 
+#ifdef __wasilibc_unmodified_upstream /* WASI has no sigaction */
 #define SIG_HOLD ((void (*)(int)) 2)
 
 #define FPE_INTDIV 1
@@ -190,6 +195,7 @@ struct sigevent {
 #define SIGEV_SIGNAL 0
 #define SIGEV_NONE 1
 #define SIGEV_THREAD 2
+#endif
 
 #ifdef __wasilibc_unmodified_upstream /* WASI has no realtime signals */
 int __libc_current_sigrtmin(void);
@@ -218,13 +224,15 @@ int sigtimedwait(const sigset_t *__restrict, siginfo_t *__restrict, const struct
 int sigqueue(pid_t, int, union sigval);
 #endif
 
+#ifdef __wasilibc_unmodified_upstream /* WASI has no threads yet */
 int pthread_sigmask(int, const sigset_t *__restrict, sigset_t *__restrict);
 int pthread_kill(pthread_t, int);
+#endif
 
-#ifdef __wasilibc_unmodified_upstream /* WASI has no signals */
+#ifdef __wasilibc_unmodified_upstream /* WASI has no siginfo */
 void psiginfo(const siginfo_t *, const char *);
-void psignal(int, const char *);
 #endif
+void psignal(int, const char *);
 
 #endif
 
@@ -256,7 +264,6 @@ void (*sigset(int, void (*)(int)))(int);
 #endif
 #endif
 
-#ifdef __wasilibc_unmodified_upstream /* WASI has no signals */
 #if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
 #define NSIG _NSIG
 typedef void (*sig_t)(int);
@@ -265,6 +272,7 @@ typedef void (*sig_t)(int);
 #ifdef _GNU_SOURCE
 typedef void (*sighandler_t)(int);
 void (*bsd_signal(int, void (*)(int)))(int);
+#ifdef __wasilibc_unmodified_upstream /* WASI has no signal sets */
 int sigisemptyset(const sigset_t *);
 int sigorset (sigset_t *, const sigset_t *, const sigset_t *);
 int sigandset(sigset_t *, const sigset_t *, const sigset_t *);
@@ -272,19 +280,30 @@ int sigandset(sigset_t *, const sigset_t *, const sigset_t *);
 #define SA_NOMASK SA_NODEFER
 #define SA_ONESHOT SA_RESETHAND
 #endif
+#endif
 
+#ifdef __wasilibc_unmodified_upstream /* 1 is a valid function pointer on wasm */
 #define SIG_ERR  ((void (*)(int))-1)
 #define SIG_DFL  ((void (*)(int)) 0)
 #define SIG_IGN  ((void (*)(int)) 1)
+#else
+void __SIG_ERR(int);
+void __SIG_IGN(int);
+#define SIG_ERR  (__SIG_ERR)
+#define SIG_DFL  ((void (*)(int)) 0)
+#define SIG_IGN  (__SIG_IGN)
 #endif
 
+#ifdef __wasilibc_unmodified_upstream /* Make sig_atomic_t 64-bit on wasm64 */
 typedef int sig_atomic_t;
+#else
+typedef long sig_atomic_t;
+#endif
 
-#ifdef __wasilibc_unmodified_upstream /* WASI has no signals */
 void (*signal(int, void (*)(int)))(int);
-#endif
 int raise(int);
 
+#ifdef __wasilibc_unmodified_upstream /* WASI has no sigtimedwait */
 #if _REDIR_TIME64
 #if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
  || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
@@ -292,9 +311,11 @@ int raise(int);
 __REDIR(sigtimedwait, __sigtimedwait_time64);
 #endif
 #endif
+#endif
 
 #ifdef __cplusplus
 }
 #endif
 
 #endif
+#endif
index 7e3f2906794d1bd1cfd02b24f7f05ea2fdfe41eb..d58da7f14eebbade38bad764be46095e840889f2 100644 (file)
@@ -2,7 +2,9 @@
 #include <limits.h>
 #include <errno.h>
 #include <sys/resource.h>
+#ifdef __wasilibc_unmodified_upstream // WASI has no realtime signals
 #include <signal.h>
+#endif
 #include <sys/sysinfo.h>
 #include "syscall.h"
 #include "libc.h"
index bb5667841a66009715b7c3687ca73cf28b49616b..46de698d999b9962bb38fe48e8167af347bba66f 100644 (file)
@@ -3,6 +3,7 @@
 
 #include "../../include/signal.h"
 
+#ifdef __wasilibc_unmodified_upstream // WASI has no sigaction
 hidden int __sigaction(int, const struct sigaction *, struct sigaction *);
 
 hidden void __block_all_sigs(void *);
@@ -10,5 +11,6 @@ hidden void __block_app_sigs(void *);
 hidden void __restore_sigs(void *);
 
 hidden void __get_handler_set(sigset_t *);
+#endif
 
 #endif