signal handling made more generic
git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@290 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
parent
2d51021df7
commit
6951619ae2
2
C/init.c
2
C/init.c
@ -874,7 +874,7 @@ InitCodes(void)
|
|||||||
AtomArrow = LookupAtom("->");
|
AtomArrow = LookupAtom("->");
|
||||||
heap_regs->atom_assert = LookupAtom(":-");
|
heap_regs->atom_assert = LookupAtom(":-");
|
||||||
heap_regs->atom_alarm = LookupAtom("$alarm");
|
heap_regs->atom_alarm = LookupAtom("$alarm");
|
||||||
#if USE_SIGACTION
|
#if HAVE_SIGACTION
|
||||||
heap_regs->atom_sig_pending = LookupAtom("$sig_pending");
|
heap_regs->atom_sig_pending = LookupAtom("$sig_pending");
|
||||||
#endif
|
#endif
|
||||||
AtomBraces = LookupAtom("{}");
|
AtomBraces = LookupAtom("{}");
|
||||||
|
2
C/save.c
2
C/save.c
@ -1050,7 +1050,7 @@ restore_codes(void)
|
|||||||
heap_regs->atom_read = AtomAdjust(heap_regs->atom_read);
|
heap_regs->atom_read = AtomAdjust(heap_regs->atom_read);
|
||||||
heap_regs->atom_repeat = AtomAdjust(heap_regs->atom_repeat);
|
heap_regs->atom_repeat = AtomAdjust(heap_regs->atom_repeat);
|
||||||
heap_regs->atom_restore_regs = AtomAdjust(heap_regs->atom_restore_regs);
|
heap_regs->atom_restore_regs = AtomAdjust(heap_regs->atom_restore_regs);
|
||||||
#if USE_SIGACTION
|
#if HAVE_SIGACTION
|
||||||
heap_regs->atom_sig_pending = AtomAdjust(heap_regs->atom_sig_pending);
|
heap_regs->atom_sig_pending = AtomAdjust(heap_regs->atom_sig_pending);
|
||||||
#endif
|
#endif
|
||||||
heap_regs->atom_stack_free = AtomAdjust(heap_regs->atom_stack_free);
|
heap_regs->atom_stack_free = AtomAdjust(heap_regs->atom_stack_free);
|
||||||
|
68
C/sysbits.c
68
C/sysbits.c
@ -823,7 +823,6 @@ STATIC_PROTO (void InitSignals, (void));
|
|||||||
|
|
||||||
STATIC_PROTO (void HandleSIGSEGV, (int, siginfo_t *, ucontext_t *));
|
STATIC_PROTO (void HandleSIGSEGV, (int, siginfo_t *, ucontext_t *));
|
||||||
STATIC_PROTO (void HandleMatherr, (int, siginfo_t *, ucontext_t *));
|
STATIC_PROTO (void HandleMatherr, (int, siginfo_t *, ucontext_t *));
|
||||||
STATIC_PROTO (void HandleSIGUSER, (int, siginfo_t *, ucontext_t *));
|
|
||||||
STATIC_PROTO (void my_signal_info, (int, void (*)(int, siginfo_t *, ucontext_t *)));
|
STATIC_PROTO (void my_signal_info, (int, void (*)(int, siginfo_t *, ucontext_t *)));
|
||||||
STATIC_PROTO (void my_signal, (int, void (*)(int, siginfo_t *, ucontext_t *)));
|
STATIC_PROTO (void my_signal, (int, void (*)(int, siginfo_t *, ucontext_t *)));
|
||||||
|
|
||||||
@ -906,7 +905,6 @@ my_signal(int sig, void (*handler)(int, siginfo_t *, ucontext_t *))
|
|||||||
|
|
||||||
STATIC_PROTO (RETSIGTYPE HandleMatherr, (int));
|
STATIC_PROTO (RETSIGTYPE HandleMatherr, (int));
|
||||||
STATIC_PROTO (RETSIGTYPE HandleSIGSEGV, (int));
|
STATIC_PROTO (RETSIGTYPE HandleSIGSEGV, (int));
|
||||||
STATIC_PROTO (RETSIGTYPE HandleSIGUSER, (int));
|
|
||||||
STATIC_PROTO (void my_signal_info, (int, void (*)(int)));
|
STATIC_PROTO (void my_signal_info, (int, void (*)(int)));
|
||||||
STATIC_PROTO (void my_signal, (int, void (*)(int)));
|
STATIC_PROTO (void my_signal, (int, void (*)(int)));
|
||||||
|
|
||||||
@ -1011,7 +1009,7 @@ HandleSIGSEGV(int sig)
|
|||||||
SearchForTrailFault();
|
SearchForTrailFault();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_SIGACTION
|
#if HAVE_SIGACTION
|
||||||
|
|
||||||
static void
|
static void
|
||||||
my_signal_info(int sig, void (*handler)(int))
|
my_signal_info(int sig, void (*handler)(int))
|
||||||
@ -1253,40 +1251,10 @@ HandleALRM(int s)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if USE_SIGACTION
|
|
||||||
/* this routine is called if YAP received one of the signals that
|
|
||||||
can be handled by user code, currently SIGUSR1 and SIGUSR2 */
|
|
||||||
static RETSIGTYPE
|
|
||||||
#if (defined(__svr4__) || defined(__SVR4))
|
|
||||||
HandleSIGUSER (int s, siginfo_t *x, ucontext_t *y)
|
|
||||||
#else
|
|
||||||
HandleSIGUSER(int s)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
/* force the system to creep */
|
|
||||||
p_creep ();
|
|
||||||
/* raise the '$sig_pending' flag */
|
|
||||||
/* NOTE: shouldn't this be a queue? */
|
|
||||||
switch (s) {
|
|
||||||
case SIGUSR1:
|
|
||||||
PutValue(AtomSigPending, MkAtomTerm(LookupAtom("sig_usr1")));
|
|
||||||
break;
|
|
||||||
case SIGUSR2:
|
|
||||||
PutValue(AtomSigPending, MkAtomTerm(LookupAtom("sig_usr2")));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* should never be here, freak out and die! */
|
|
||||||
/* YapErrorWhatever(); */
|
|
||||||
;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* USE_SIGACTION */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function is called after a normal interrupt had been caught It allows
|
* This function is called after a normal interrupt had been caught.
|
||||||
* 6 possibilities : abort, continue, trace, debug, help, exit
|
* It allows 6 possibilities: abort, continue, trace, debug, help, exit.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(LIGHT) && !_MSC_VER && !defined(__MINGW32__) && !defined(LIGHT)
|
#if !defined(LIGHT) && !_MSC_VER && !defined(__MINGW32__) && !defined(LIGHT)
|
||||||
@ -1311,9 +1279,30 @@ ReceiveSignal (int s)
|
|||||||
case SIGKILL:
|
case SIGKILL:
|
||||||
exit_yap (SIGKILL, "\n\n\n[ Quit signal received ]\n\n");
|
exit_yap (SIGKILL, "\n\n\n[ Quit signal received ]\n\n");
|
||||||
#endif
|
#endif
|
||||||
|
case SIGUSR1:
|
||||||
|
/* force the system to creep */
|
||||||
|
p_creep ();
|
||||||
|
/* raise the '$sig_pending' flag */
|
||||||
|
/* NOTE: shouldn't this be a queue? */
|
||||||
|
PutValue(AtomSigPending, MkAtomTerm(LookupAtom("sig_usr1")));
|
||||||
|
break;
|
||||||
|
case SIGUSR2:
|
||||||
|
/* force the system to creep */
|
||||||
|
p_creep ();
|
||||||
|
/* raise the '$sig_pending' flag */
|
||||||
|
/* NOTE: shouldn't this be a queue? */
|
||||||
|
PutValue(AtomSigPending, MkAtomTerm(LookupAtom("sig_usr2")));
|
||||||
|
break;
|
||||||
|
case SIGHUP:
|
||||||
|
/* force the system to creep */
|
||||||
|
p_creep ();
|
||||||
|
/* raise the '$sig_pending' flag */
|
||||||
|
/* NOTE: shouldn't this be a queue? */
|
||||||
|
PutValue(AtomSigPending, MkAtomTerm(LookupAtom("sig_hup")));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
YP_fprintf(YP_stderr, "\n[ Unexpected signal ]\n");
|
YP_fprintf(YP_stderr, "\n[ Unexpected signal ]\n");
|
||||||
exit (FALSE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1340,6 +1329,9 @@ InitSignals (void)
|
|||||||
#if !defined(LIGHT) && !_MSC_VER && !defined(__MINGW32__) && !defined(LIGHT)
|
#if !defined(LIGHT) && !_MSC_VER && !defined(__MINGW32__) && !defined(LIGHT)
|
||||||
my_signal (SIGQUIT, ReceiveSignal);
|
my_signal (SIGQUIT, ReceiveSignal);
|
||||||
my_signal (SIGKILL, ReceiveSignal);
|
my_signal (SIGKILL, ReceiveSignal);
|
||||||
|
my_signal (SIGUSR1, ReceiveSignal);
|
||||||
|
my_signal (SIGUSR2, ReceiveSignal);
|
||||||
|
my_signal (SIGHUP, ReceiveSignal);
|
||||||
my_signal (SIGALRM, HandleALRM);
|
my_signal (SIGALRM, HandleALRM);
|
||||||
#endif
|
#endif
|
||||||
#if _MSC_VER || defined(__MINGW32__)
|
#if _MSC_VER || defined(__MINGW32__)
|
||||||
@ -1348,10 +1340,6 @@ InitSignals (void)
|
|||||||
#else
|
#else
|
||||||
my_signal (SIGINT, HandleSIGINT);
|
my_signal (SIGINT, HandleSIGINT);
|
||||||
#endif
|
#endif
|
||||||
#if USE_SIGACTION
|
|
||||||
my_signal (SIGUSR1, HandleSIGUSER);
|
|
||||||
my_signal (SIGUSR2, HandleSIGUSER);
|
|
||||||
#endif
|
|
||||||
#ifndef MPW
|
#ifndef MPW
|
||||||
my_signal (SIGFPE, HandleMatherr);
|
my_signal (SIGFPE, HandleMatherr);
|
||||||
#endif
|
#endif
|
||||||
|
4
H/Heap.h
4
H/Heap.h
@ -10,7 +10,7 @@
|
|||||||
* File: Heap.h *
|
* File: Heap.h *
|
||||||
* mods: *
|
* mods: *
|
||||||
* comments: Heap Init Structure *
|
* comments: Heap Init Structure *
|
||||||
* version: $Id: Heap.h,v 1.18 2002-01-09 17:19:36 stasinos Exp $ *
|
* version: $Id: Heap.h,v 1.19 2002-01-11 15:54:17 stasinos Exp $ *
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
/* information that can be stored in Code Space */
|
/* information that can be stored in Code Space */
|
||||||
@ -196,7 +196,7 @@ typedef struct various_codes {
|
|||||||
atom_read,
|
atom_read,
|
||||||
atom_repeat,
|
atom_repeat,
|
||||||
atom_restore_regs,
|
atom_restore_regs,
|
||||||
#if USE_SIGACTION
|
#if HAVE_SIGACTION
|
||||||
atom_sig_pending,
|
atom_sig_pending,
|
||||||
#endif
|
#endif
|
||||||
atom_stack_free,
|
atom_stack_free,
|
||||||
|
@ -201,8 +201,3 @@
|
|||||||
|
|
||||||
/* Is fflush(NULL) clobbering input streams? */
|
/* Is fflush(NULL) clobbering input streams? */
|
||||||
#undef BROKEN_FFLUSH_NULL
|
#undef BROKEN_FFLUSH_NULL
|
||||||
|
|
||||||
/* Should we do signal handling? */
|
|
||||||
#if HAVE_SIGNAL_H && HAVE_SIGACTION
|
|
||||||
#define USE_SIGACTION 1
|
|
||||||
#endif
|
|
||||||
|
39
pl/boot.yap
39
pl/boot.yap
@ -32,6 +32,12 @@ true :- true. % otherwise, $$compile will ignore this clause.
|
|||||||
),
|
),
|
||||||
'$system_catch'('$enter_top_level',Module,Error,user:'$Error'(Error)).
|
'$system_catch'('$enter_top_level',Module,Error,user:'$Error'(Error)).
|
||||||
|
|
||||||
|
read_sig :-
|
||||||
|
recorded('$sig_handler',X,_),
|
||||||
|
writeq(X),nl,
|
||||||
|
fail.
|
||||||
|
read_sig.
|
||||||
|
|
||||||
|
|
||||||
'$init_system' :-
|
'$init_system' :-
|
||||||
(
|
(
|
||||||
@ -40,6 +46,27 @@ true :- true. % otherwise, $$compile will ignore this clause.
|
|||||||
;
|
;
|
||||||
true
|
true
|
||||||
),
|
),
|
||||||
|
% If this is not here, the following get written twice in the idb. Why?
|
||||||
|
eraseall('$sig_handler'),
|
||||||
|
% The default interrupt handlers are kept, so that it's
|
||||||
|
% possible to revert to them with on_signal(S,_,default)
|
||||||
|
'$recordz'('$sig_handler',default(sig_hup,
|
||||||
|
(( exists('~/.yaprc') -> [-'~/.yaprc'] ; true ),
|
||||||
|
( exists('~/.prologrc') -> [-'~/.prologrc'] ; true ),
|
||||||
|
( exists('~/prolog.ini') -> [-'~/prolog.ini'] ; true ))), _),
|
||||||
|
'$recordz'('$sig_handler',default(sig_usr1,
|
||||||
|
(nl,writeq('[ Received user signal 1 ]'),nl,halt)), _),
|
||||||
|
'$recordz'('$sig_handler',default(sig_usr2,
|
||||||
|
(nl,writeq('[ Received user signal 2 ]'),nl,halt)), _),
|
||||||
|
% The current interrupt handlers are also set the default values
|
||||||
|
'$recordz'('$sig_handler',action(sig_hup,
|
||||||
|
(( exists('~/.yaprc') -> [-'~/.yaprc'] ; true ),
|
||||||
|
( exists('~/.prologrc') -> [-'~/.prologrc'] ; true ),
|
||||||
|
( exists('~/prolog.ini') -> [-'~/prolog.ini'] ; true ))), _),
|
||||||
|
'$recordz'('$sig_handler',action(sig_usr1,
|
||||||
|
(nl,writeq('[ Received user signal 1 ]'),nl,halt)), _),
|
||||||
|
'$recordz'('$sig_handler',action(sig_usr2,
|
||||||
|
(nl,writeq('[ Received user signal 2 ]'),nl,halt)), _),
|
||||||
'$set_yap_flags'(10,0),
|
'$set_yap_flags'(10,0),
|
||||||
'$set_value'('$gc',on),
|
'$set_value'('$gc',on),
|
||||||
'$init_catch',
|
'$init_catch',
|
||||||
@ -67,6 +94,7 @@ true :- true. % otherwise, $$compile will ignore this clause.
|
|||||||
true
|
true
|
||||||
).
|
).
|
||||||
|
|
||||||
|
|
||||||
%
|
%
|
||||||
% encapsulate $cut_by because of co-routining.
|
% encapsulate $cut_by because of co-routining.
|
||||||
%
|
%
|
||||||
@ -94,17 +122,6 @@ true :- true. % otherwise, $$compile will ignore this clause.
|
|||||||
'$enter_top_level' :-
|
'$enter_top_level' :-
|
||||||
'$alarm'(0, _),
|
'$alarm'(0, _),
|
||||||
fail.
|
fail.
|
||||||
% set the default user signal handlers
|
|
||||||
'$enter_top_level' :-
|
|
||||||
( '$recorded'('$sig_handler',_,_) ->
|
|
||||||
true
|
|
||||||
;
|
|
||||||
'$recordz'('$sig_handler',
|
|
||||||
action(sig_usr1,(format('Received user signal 1~n',[]),halt)), _),
|
|
||||||
'$recordz'('$sig_handler',
|
|
||||||
action(sig_usr2,(format('Received user signal 2~n',[]),halt)), _)
|
|
||||||
),
|
|
||||||
fail.
|
|
||||||
'$enter_top_level' :-
|
'$enter_top_level' :-
|
||||||
'$clean_up_dead_clauses',
|
'$clean_up_dead_clauses',
|
||||||
fail.
|
fail.
|
||||||
|
@ -720,8 +720,10 @@ debugging :-
|
|||||||
),
|
),
|
||||||
'$execute'(M:Goal).
|
'$execute'(M:Goal).
|
||||||
'$creep'(G) :-
|
'$creep'(G) :-
|
||||||
|
format( 'creeping...~n', [] ),
|
||||||
'$get_value'('$sig_pending', Signal),
|
'$get_value'('$sig_pending', Signal),
|
||||||
\+ Signal = [], !,
|
format( 'Signal == ~q~n', [Signal] ),
|
||||||
|
Signal \== [], !,
|
||||||
'$set_value'('$sig_pending', []),
|
'$set_value'('$sig_pending', []),
|
||||||
( '$recorded'('$sig_handler', action(Signal,A),_) ->
|
( '$recorded'('$sig_handler', action(Signal,A),_) ->
|
||||||
'$execute'(A),
|
'$execute'(A),
|
||||||
|
@ -231,11 +231,14 @@ alarm(Interval, Goal, Left) :-
|
|||||||
'$recordz'('$alarm_handler',M:Goal,_),
|
'$recordz'('$alarm_handler',M:Goal,_),
|
||||||
'$alarm'(Interval, Left).
|
'$alarm'(Interval, Left).
|
||||||
|
|
||||||
|
on_signal(Signal,OldAction,default) :-
|
||||||
|
recorded('$sig_handler', default(Signal,Action), Ref),
|
||||||
|
on_signal(Signal,OldAction,Action).
|
||||||
on_signal(Signal,OldAction,Action) :-
|
on_signal(Signal,OldAction,Action) :-
|
||||||
recorded('$sig_handler', action(Signal,OldAction), Ref),
|
recorded('$sig_handler', action(Signal,OldAction), Ref),
|
||||||
erase(Ref),
|
erase(Ref),
|
||||||
'$current_module'(M),
|
'$current_module'(M),
|
||||||
'$recordz'('$sig_handler', action(Signal,M:Action),Ref2).
|
'$recordz'('$sig_handler', action(Signal,M:Action), _).
|
||||||
|
|
||||||
|
|
||||||
%%% Saving and restoring a computation
|
%%% Saving and restoring a computation
|
||||||
|
Reference in New Issue
Block a user