Implemented new API function burn_set_signal_handling(), libburner uses it
parent
b3bea43074
commit
3b16ef699f
@ -1 +1 @@
|
||||
#define Cdrskin_timestamP "2006.10.02.103418"
|
||||
#define Cdrskin_timestamP "2006.10.03.162719"
|
||||
|
@ -0,0 +1,191 @@
|
||||
/*
|
||||
cleanup.c , Copyright 2006 Thomas Schmitt <scdbackup@gmx.net>
|
||||
|
||||
A signal handler which cleans up an application and exits.
|
||||
|
||||
Provided under GPL license within GPL projects, BSD license elsewise.
|
||||
*/
|
||||
|
||||
/*
|
||||
cc -g -o cleanup -DCleanup_standalonE cleanup.c
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <signal.h>
|
||||
typedef void (*sighandler_t)(int);
|
||||
|
||||
|
||||
#include "cleanup.h"
|
||||
|
||||
/* Signals to be caught */
|
||||
static int signal_list[]= {
|
||||
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT,
|
||||
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM,
|
||||
SIGUSR1, SIGUSR2, SIGXCPU, SIGTSTP, SIGTTIN,
|
||||
SIGTTOU,
|
||||
SIGBUS, SIGPOLL, SIGPROF, SIGSYS, SIGTRAP,
|
||||
SIGVTALRM, SIGXCPU, SIGXFSZ, -1
|
||||
};
|
||||
static char *signal_name_list[]= {
|
||||
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT",
|
||||
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM",
|
||||
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN",
|
||||
"SIGTTOU",
|
||||
"SIGBUS", "SIGPOLL", "SIGPROF", "SIGSYS", "SIGTRAP",
|
||||
"SIGVTALRM", "SIGXCPU", "SIGXFSZ", "@"
|
||||
};
|
||||
static int signal_list_count= 24;
|
||||
|
||||
/* Signals not to be caught */
|
||||
static int non_signal_list[]= {
|
||||
SIGKILL, SIGCHLD, SIGSTOP, SIGURG, -1
|
||||
};
|
||||
static int non_signal_list_count= 4;
|
||||
|
||||
|
||||
/* run time dynamic part */
|
||||
static char cleanup_msg[4096]= {""};
|
||||
static int cleanup_exiting= 0;
|
||||
|
||||
static void *cleanup_app_handle= NULL;
|
||||
static Cleanup_app_handler_T cleanup_app_handler= NULL;
|
||||
static int cleanup_perform_app_handler_first= 0;
|
||||
|
||||
|
||||
static int Cleanup_handler_exit(int exit_value, int signum, int flag)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if(cleanup_perform_app_handler_first)
|
||||
if(cleanup_app_handler!=NULL) {
|
||||
ret= (*cleanup_app_handler)(cleanup_app_handle,signum,0);
|
||||
if(ret==2 || ret==-2)
|
||||
return(2);
|
||||
}
|
||||
if(cleanup_exiting) {
|
||||
if(cleanup_msg[0]!=0)
|
||||
fprintf(stderr,"%s\n",cleanup_msg);
|
||||
fprintf(stderr,"cleanup: ABORT : repeat by pid=%d, signum=%d\n",
|
||||
getpid(),signum);
|
||||
return(0);
|
||||
}
|
||||
cleanup_exiting= 1;
|
||||
if(cleanup_msg[0]!=0)
|
||||
fprintf(stderr,"\n%s\n",cleanup_msg);
|
||||
alarm(0);
|
||||
if(!cleanup_perform_app_handler_first)
|
||||
if(cleanup_app_handler!=NULL) {
|
||||
ret= (*cleanup_app_handler)(cleanup_app_handle,signum,0);
|
||||
if(ret==2 || ret==-2)
|
||||
return(2);
|
||||
}
|
||||
exit(exit_value);
|
||||
}
|
||||
|
||||
|
||||
static void Cleanup_handler_generic(int signum)
|
||||
{
|
||||
int i;
|
||||
|
||||
sprintf(cleanup_msg,"UNIX-SIGNAL caught: %d errno= %d",signum,errno);
|
||||
for(i= 0; i<signal_list_count; i++)
|
||||
if(signum==signal_list[i]) {
|
||||
sprintf(cleanup_msg,"UNIX-SIGNAL: %s errno= %d",
|
||||
signal_name_list[i],errno);
|
||||
break;
|
||||
}
|
||||
Cleanup_handler_exit(1,signum,0);
|
||||
}
|
||||
|
||||
|
||||
int Cleanup_set_handlers(void *handle, Cleanup_app_handler_T handler, int flag)
|
||||
/*
|
||||
bit0= set to default handlers
|
||||
bit1= set to ignore
|
||||
bit2= set cleanup_perform_app_handler_first
|
||||
bit3= set SIGABRT to handler (makes sense with bits 0 or 1)
|
||||
*/
|
||||
{
|
||||
int i,j,max_sig= -1,min_sig= 0x7fffffff;
|
||||
sighandler_t sig_handler;
|
||||
|
||||
cleanup_msg[0]= 0;
|
||||
cleanup_app_handle= handle;
|
||||
cleanup_app_handler= handler;
|
||||
|
||||
/* <<< make cleanup_exiting thread safe to get rid of this */
|
||||
if(flag&4)
|
||||
cleanup_perform_app_handler_first= 1;
|
||||
|
||||
|
||||
if(flag&1)
|
||||
sig_handler= SIG_DFL;
|
||||
else if(flag&2)
|
||||
sig_handler= SIG_IGN;
|
||||
else
|
||||
sig_handler= Cleanup_handler_generic;
|
||||
/* set all signal numbers between the lowest and highest in the list
|
||||
except those in the non-signal list */
|
||||
for(i= 0; i<signal_list_count; i++) {
|
||||
if(signal_list[i]>max_sig)
|
||||
max_sig= signal_list[i];
|
||||
if(signal_list[i]<min_sig)
|
||||
min_sig= signal_list[i];
|
||||
}
|
||||
for(i= min_sig; i<=max_sig; i++) {
|
||||
for(j= 0; j<non_signal_list_count; j++)
|
||||
if(i==non_signal_list[j])
|
||||
break;
|
||||
if(j>=non_signal_list_count) {
|
||||
if(i==SIGABRT && (flag&8))
|
||||
signal(i,Cleanup_handler_generic);
|
||||
else
|
||||
signal(i,sig_handler);
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
#ifdef Cleanup_standalonE
|
||||
|
||||
struct Demo_apP {
|
||||
char *msg;
|
||||
};
|
||||
|
||||
|
||||
int Demo_app_handler(struct Demo_apP *demoapp, int signum, int flag)
|
||||
{
|
||||
printf("Handling exit of demo application on signal %d. msg=\"%s\"\n",
|
||||
signum,demoapp->msg);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
main()
|
||||
{
|
||||
struct Demo_apP demoapp;
|
||||
|
||||
demoapp.msg= "Good Bye";
|
||||
Cleanup_set_handlers(&demoapp,(Cleanup_app_handler_T) Demo_app_handler,0);
|
||||
|
||||
if(1) { /* change to 0 in order to wait for external signals */
|
||||
char *cpt= NULL,c;
|
||||
printf("Intentionally provoking SIGSEGV ...\n");
|
||||
c= *cpt;
|
||||
} else {
|
||||
printf("killme: %d\n",getpid());
|
||||
sleep(3600);
|
||||
}
|
||||
|
||||
Cleanup_set_handlers(NULL,NULL,1);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#endif /* Cleanup_standalonE */
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
cleanup.c , Copyright 2006 Thomas Schmitt <scdbackup@gmx.net>
|
||||
|
||||
A signal handler which cleans up an application and exits.
|
||||
|
||||
Provided under GPL license within GPL projects, BSD license elsewise.
|
||||
*/
|
||||
|
||||
#ifndef Cleanup_includeD
|
||||
#define Cleanup_includeD 1
|
||||
|
||||
|
||||
/** Layout of an application provided cleanup function using an application
|
||||
provided handle as first argument and the signal number as second
|
||||
argument. The third argument is a flag bit field with no defined bits yet.
|
||||
If the handler returns 2 or -2 then it has delegated exit() to some other
|
||||
instance and the Cleanup handler shall return rather than exit.
|
||||
*/
|
||||
typedef int (*Cleanup_app_handler_T)(void *, int, int);
|
||||
|
||||
|
||||
/** Establish exiting signal handlers on (hopefully) all signals that are
|
||||
not ignored by default or non-catchable.
|
||||
@param handle Opaque object which knows how to cleanup application
|
||||
@param handler Function which uses handle to perform application cleanup
|
||||
@param flag Control Bitfield
|
||||
bit0= reset to default signal handling
|
||||
*/
|
||||
int Cleanup_set_handlers(void *handle, Cleanup_app_handler_T handler,
|
||||
int flag);
|
||||
|
||||
|
||||
#endif /* ! Cleanup_includeD */
|
||||
|
Loading…
Reference in New Issue