size-read-fd <fd> init-fd <input-port> >>size
data-read-fd <fd> >>data ;
+SYMBOL: dispatch-signal-hook
+
+dispatch-signal-hook [ [ drop ] ] initialize
+
: signal-pipe-fd ( -- n )
OBJ-SIGNAL-PIPE special-object ; inline
+: signal-pipe-loop ( port -- )
+ '[
+ int heap-size _ io:stream-read
+ dup [ int deref dispatch-signal-hook get call( x -- ) ] when*
+ ] loop ;
+
: start-signal-pipe-thread ( -- )
- signal-pipe-fd [ <fd> init-fd <input-port>
- '[ [ 4 _ io:stream-read ] loop ] "Signals" spawn drop
+ signal-pipe-fd [
+ <fd> init-fd <input-port>
+ '[ _ signal-pipe-loop ] "Signals" spawn drop
] when* ;
M: unix init-stdio
FUNCTION: int utimes ( c-string path, timeval[2] times ) ;
FUNCTION: ssize_t write ( int fd, void* buf, size_t nbytes ) ;
+FUNCTION: int kill ( pid_t pid, int signal ) ;
+FUNCTION: int raise ( int signal ) ;
+
"librt" "librt.so" cdecl add-library
--- /dev/null
+USING: calendar continuations io kernel math namespaces threads
+tools.test unix.ffi unix.signals ;
+IN: unix.signals.tests
+
+SYMBOL: sigusr1-count
+0 sigusr1-count set-global
+
+CONSTANT: test-sigusr1-handler [ 1 sigusr1-count +@ ]
+
+"=========" print
+"NOTE: This test uses SIGUSR1. It may break or cause unwanted behavior" print
+"if other SIGUSR1 handlers are installed." print
+"=========" print flush
+
+test-sigusr1-handler SIGUSR1 add-signal-handler
+[
+
+ [ 1 ] [
+ sigusr1-count get-global
+ SIGUSR1 raise drop
+ 0.5 seconds sleep
+ sigusr1-count get-global
+ swap -
+ ] unit-test
+
+] [ test-sigusr1-handler SIGUSR1 remove-signal-handler ] [ ] cleanup
+
+[ 0 ] [
+ sigusr1-count get-global
+ SIGUSR1 raise drop
+ 0.5 seconds sleep
+ sigusr1-count get-global swap -
+] unit-test
+
--- /dev/null
+! (c)2011 Joe Groff bsd license
+USING: assocs io.backend.unix kernel namespaces sequences
+threads ;
+IN: unix.signals
+
+<PRIVATE
+
+SYMBOL: signal-handlers
+
+signal-handlers [ H{ } ] initialize
+
+PRIVATE>
+
+: dispatch-signal ( sig -- )
+ signal-handlers get-global at [ in-thread ] each ;
+
+: add-signal-handler ( handler: ( -- ) sig -- )
+ signal-handlers get-global push-at ;
+
+: remove-signal-handler ( handler sig -- )
+ signal-handlers get-global at [ remove! drop ] [ drop ] if* ;
+
+[ dispatch-signal ] dispatch-signal-hook set-global
init_sigaction_with_handler(&enqueue_sigaction, enqueue_signal_handler);
sigaction_safe(SIGWINCH,&enqueue_sigaction,NULL);
+ sigaction_safe(SIGUSR1,&enqueue_sigaction,NULL);
+ sigaction_safe(SIGCONT,&enqueue_sigaction,NULL);
+ sigaction_safe(SIGURG,&enqueue_sigaction,NULL);
+ sigaction_safe(SIGIO,&enqueue_sigaction,NULL);
+ sigaction_safe(SIGPROF,&enqueue_sigaction,NULL);
+ sigaction_safe(SIGVTALRM,&enqueue_sigaction,NULL);
#ifdef SIGINFO
sigaction_safe(SIGINFO,&enqueue_sigaction,NULL);
#endif