mirror of
https://github.com/adtools/clib2.git
synced 2025-12-08 14:59:05 +00:00
The SIGABRT handler can no longer invoke abort() recursively.
This commit is contained in:
@@ -71,7 +71,7 @@ raise(int sig)
|
|||||||
assert( SIGABRT <= sig && sig <= SIGTERM );
|
assert( SIGABRT <= sig && sig <= SIGTERM );
|
||||||
|
|
||||||
/* This has to be a well-known and supported signal. */
|
/* This has to be a well-known and supported signal. */
|
||||||
if(sig < SIGABRT || sig > SIGTERM)
|
if (sig < SIGABRT || sig > SIGTERM)
|
||||||
{
|
{
|
||||||
SHOWMSG("unknown signal number");
|
SHOWMSG("unknown signal number");
|
||||||
|
|
||||||
@@ -80,48 +80,49 @@ raise(int sig)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Can we deliver the signal? */
|
/* Can we deliver the signal? */
|
||||||
if(FLAG_IS_CLEAR(__signals_blocked, (1 << sig)) &&
|
if (FLAG_IS_CLEAR(__signals_blocked, (1 << sig)) &&
|
||||||
FLAG_IS_CLEAR(local_signals_blocked, (1 << sig)))
|
FLAG_IS_CLEAR(local_signals_blocked, (1 << sig)))
|
||||||
{
|
{
|
||||||
signal_handler_t handler;
|
signal_handler_t handler;
|
||||||
|
|
||||||
/* Which handler is installed for this signal? */
|
/* Which handler is installed for this signal? */
|
||||||
handler = __signal_handler_table[sig - SIGABRT];
|
handler = __signal_handler_table[sig - SIGABRT];
|
||||||
|
|
||||||
/* Should we ignore this signal? */
|
/* Should we handle this signal rather than ignoring it? */
|
||||||
if(handler != SIG_IGN)
|
if (handler != SIG_IGN)
|
||||||
{
|
{
|
||||||
/* Block delivery of this signal to prevent recursion. */
|
/* Block delivery of this signal to prevent recursion. */
|
||||||
SET_FLAG(local_signals_blocked,(1 << sig));
|
SET_FLAG(local_signals_blocked, (1 << sig));
|
||||||
|
|
||||||
/* The default behaviour is to drop into abort(), or do
|
/* The default behaviour is to drop into abort(), or do
|
||||||
something very much like it. */
|
* something very much like it.
|
||||||
if(handler == SIG_DFL)
|
*/
|
||||||
|
if (handler == SIG_DFL)
|
||||||
{
|
{
|
||||||
SHOWMSG("this is the default handler");
|
SHOWMSG("this is the default handler");
|
||||||
|
|
||||||
if(sig == SIGINT)
|
if (sig == SIGINT)
|
||||||
{
|
{
|
||||||
char break_string[80];
|
char break_string[80];
|
||||||
|
|
||||||
/* Turn off ^C checking for good. */
|
/* Turn off ^C checking for good. */
|
||||||
__check_abort_enabled = FALSE;
|
__check_abort_enabled = FALSE;
|
||||||
|
|
||||||
Fault(ERROR_BREAK,NULL,break_string,(LONG)sizeof(break_string));
|
Fault(ERROR_BREAK, NULL, break_string, (LONG)sizeof(break_string));
|
||||||
|
|
||||||
__print_termination_message(break_string);
|
__print_termination_message(break_string);
|
||||||
|
|
||||||
SHOWMSG("bye, bye...");
|
SHOWMSG("bye, bye...");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Drop straight into abort(), which might call signal()
|
/* Drop straight into __abort(), which will
|
||||||
again but is otherwise guaranteed to eventually
|
eventually land us in _exit(). Note that
|
||||||
land us in _exit(). */
|
abort() calls raise(SIGABRT). */
|
||||||
abort();
|
__abort();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SHOWMSG("calling the handler");
|
SHOWMSG("calling the signal handler");
|
||||||
|
|
||||||
(*handler)(sig);
|
(*handler)(sig);
|
||||||
|
|
||||||
@@ -129,7 +130,7 @@ raise(int sig)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Unblock signal delivery again. */
|
/* Unblock signal delivery again. */
|
||||||
CLEAR_FLAG(local_signals_blocked,(1 << sig));
|
CLEAR_FLAG(local_signals_blocked, (1 << sig));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -46,15 +46,8 @@
|
|||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
||||||
void
|
void
|
||||||
abort(void)
|
__abort(void)
|
||||||
{
|
{
|
||||||
/* Try to call the signal handler that might be in charge of
|
|
||||||
handling cleanup operations, etc. */
|
|
||||||
raise(SIGABRT);
|
|
||||||
|
|
||||||
/* If the signal handler returns it means that we still have
|
|
||||||
to terminate the program. */
|
|
||||||
|
|
||||||
__check_abort_enabled = FALSE;
|
__check_abort_enabled = FALSE;
|
||||||
|
|
||||||
__print_termination_message(NULL);
|
__print_termination_message(NULL);
|
||||||
@@ -63,3 +56,17 @@ abort(void)
|
|||||||
does not trigger the exit trap. */
|
does not trigger the exit trap. */
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
void
|
||||||
|
abort(void)
|
||||||
|
{
|
||||||
|
/* Try to call the signal handler that might be in charge of
|
||||||
|
handling cleanup operations, etc. */
|
||||||
|
raise(SIGABRT);
|
||||||
|
|
||||||
|
/* If the signal handler returns it means that we still have
|
||||||
|
to terminate the program. */
|
||||||
|
__abort();
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user