On 4-Jan-06, at 12:36 AM, Christian wrote:
At 10:18 Uhr -0500 03.01.2006, Marc Feeley wrote:
CTRL-C does not generate an exception. It simply calls the current user-interrupt-handler.
Ok, thanks, that makes perfect sense.
Two small followup questions about things I might need in the future:
- can other signals than SIGINT be catched, too? I guess that you
haven't added that since it's platform specific. I might write a small C layer for my programs on unix, but then my question is: how do I register an interrupt callback in gambit's runtime (I guess I'll have to save the signal number and values into some global and then let gambit run a callback synchronously at a safe point)?
It is possible using undocumented procedures. Here's what you want:
(c-declare #<<c-declare-end
#include <signal.h>
void handler (int sig) { if (sig == SIGUSR1) ___EXT(___raise_interrupt) (___INTR_6); else ___EXT(___raise_interrupt) (___INTR_7); }
void install_SIGUSR_handlers () { signal (SIGUSR1, handler); signal (SIGUSR2, handler); }
c-declare-end )
(define install-SIGUSR-handlers (c-lambda () void "install_SIGUSR_handlers"))
(define (install-handlers) (##interrupt-vector-set! 6 (lambda () (println 'got-SIGUSR1))) (##interrupt-vector-set! 7 (lambda () (println 'got-SIGUSR2))) (install-SIGUSR-handlers))
(install-handlers)
(define my-pid (##os-getpid))
(display "executing kill -USR1\n")
(shell-command (string-append "kill -USR1 " (number->string my-pid)))
(display "executing kill -USR2\n")
(shell-command (string-append "kill -USR2 " (number->string my-pid)))
(display "done\n")
; Output: ; ; executing kill -USR1 ; got-SIGUSR1 ; executing kill -USR2 ; got-SIGUSR2 ; done
- maybe it's rather theoretical, but there is probably a time frame
between the start of a program and the time when it sets user- interrupt-handler where sending SIGINT still makes the program "hang" in the debugger. Could gambit delay installing of a SIGINT signal handler so that the program behaves in the default way until the user actually installs a handler?(*) That should also be better if gambit is to be embedded in a C program which wants to catch signals itself.
Good point. Currently Gambit, under Unix, starts off with SIGINT terminating the program (that's the default Unix SIGINT handler), then the runtime system installs a handler that ignores SIGINT, then it installs a handler that starts a REPL.
I'm planning to change this so that the default user-interrupt- handler behaves like exceptions, i.e. the default will be to terminate the program after displaying "*** INTERRUPTED IN ...". With the runtime option "-:d" the system will instead start a REPL. With the runtime option "-:d0" the program will terminate silently. However, when inside a REPL (such as the one normally started in interactive mode), a SIGINT will start a nested REPL.
(*) that leads to another question I've been wondering about: parameterize doesn't accept procedures which aren't parameters (it checks their type). This makes the above suggestion impossible to be implement transparently of course, since it would require running code other than just for setting the dynamic value (**).
I don't understand what you mean.
What's the reason for this restriction?
Parameters are special procedures that contain a key. This key is used to lookup the binding of the parameter. The machinery is quite complex (see _thread.scm).
((**) without this, the user would have to run some (user-interrupt- initialize!) hook first -- at least, that might be better for thread safety?)
Thanks Christian. _______________________________________________ Gambit-list mailing list Gambit-list@iro.umontreal.ca http://mailman.iro.umontreal.ca/mailman/listinfo/gambit-list