Implemented new API function burn_set_signal_handling(), libburner uses it
This commit is contained in:
parent
b3bea43074
commit
3b16ef699f
@ -12,6 +12,8 @@ libburn_libburn_la_SOURCES = \
|
|||||||
libburn/async.c \
|
libburn/async.c \
|
||||||
libburn/async.h \
|
libburn/async.h \
|
||||||
libburn/back_hacks.h \
|
libburn/back_hacks.h \
|
||||||
|
libburn/cleanup.c \
|
||||||
|
libburn/cleanup.h \
|
||||||
libburn/crc.c \
|
libburn/crc.c \
|
||||||
libburn/crc.h \
|
libburn/crc.h \
|
||||||
libburn/debug.c \
|
libburn/debug.c \
|
||||||
@ -119,7 +121,8 @@ test_iso_SOURCES = test/iso.c
|
|||||||
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
|
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
|
||||||
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_0_2_3
|
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_0_2_3
|
||||||
cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
|
cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
|
||||||
cdrskin_cdrskin_SOURCES = cdrskin/cdrskin.c cdrskin/cdrfifo.c cdrskin/cdrfifo.h cdrskin/cleanup.c cdrskin/cleanup.h cdrskin/cdrskin_timestamp.h
|
cdrskin_cdrskin_SOURCES = cdrskin/cdrskin.c cdrskin/cdrfifo.c cdrskin/cdrfifo.h cdrskin/cdrskin_timestamp.h
|
||||||
|
## cdrskin_cdrskin_SOURCES = cdrskin/cdrskin.c cdrskin/cdrfifo.c cdrskin/cdrfifo.h cdrskin/cleanup.c cdrskin/cleanup.h cdrskin/cdrskin_timestamp.h
|
||||||
##
|
##
|
||||||
## Open questions: how to compute $timestamp and express -DX="$timestamp"
|
## Open questions: how to compute $timestamp and express -DX="$timestamp"
|
||||||
##
|
##
|
||||||
|
@ -186,6 +186,7 @@ or
|
|||||||
#ifdef Cdrskin_new_api_tesT
|
#ifdef Cdrskin_new_api_tesT
|
||||||
|
|
||||||
/* put macros under test caveat here */
|
/* put macros under test caveat here */
|
||||||
|
#define Cdrskin_libburn_has_cleanup_handleR 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -273,7 +274,12 @@ or
|
|||||||
|
|
||||||
#include <libburn/libburn.h>
|
#include <libburn/libburn.h>
|
||||||
|
|
||||||
|
#ifdef Cdrskin_libburn_has_cleanup_handleR
|
||||||
|
#define Cleanup_set_handlers burn_set_signal_handling
|
||||||
|
#define Cleanup_app_handler_T burn_abort_handler_t
|
||||||
|
#else
|
||||||
#include "cleanup.h"
|
#include "cleanup.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/** The size of a string buffer for pathnames and similar texts */
|
/** The size of a string buffer for pathnames and similar texts */
|
||||||
@ -2652,11 +2658,10 @@ int Cdrskin_abort_handler(struct CdrskiN *skin, int signum, int flag)
|
|||||||
if(getpid()!=skin->control_pid) {
|
if(getpid()!=skin->control_pid) {
|
||||||
if(skin->verbosity>=Cdrskin_verbose_debuG)
|
if(skin->verbosity>=Cdrskin_verbose_debuG)
|
||||||
ClN(fprintf(stderr,
|
ClN(fprintf(stderr,
|
||||||
"cdrskin_debug: ABORT : Thread rejected: pid=%d, signum=%d\n",
|
"\ncdrskin_debug: ABORT : [%d] Thread rejected: pid=%d, signum=%d\n",
|
||||||
getpid(),signum));
|
skin->control_pid,getpid(),signum));
|
||||||
return(2); /* do only process the control thread */
|
return(-2); /* do only process the control thread */
|
||||||
}
|
}
|
||||||
|
|
||||||
if(skin->preskin->abort_handler==3)
|
if(skin->preskin->abort_handler==3)
|
||||||
Cleanup_set_handlers(NULL,NULL,2); /* ignore all signals */
|
Cleanup_set_handlers(NULL,NULL,2); /* ignore all signals */
|
||||||
else if(skin->preskin->abort_handler==4)
|
else if(skin->preskin->abort_handler==4)
|
||||||
|
@ -1 +1 @@
|
|||||||
#define Cdrskin_timestamP "2006.10.02.103418"
|
#define Cdrskin_timestamP "2006.10.03.162719"
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
A signal handler which cleans up an application and exits.
|
A signal handler which cleans up an application and exits.
|
||||||
|
|
||||||
Provided under GPL license within cdrskin and under BSD license elsewise.
|
Provided under GPL license within GPL projects, BSD license elsewise.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -65,7 +65,7 @@ static int Cleanup_handler_exit(int exit_value, int signum, int flag)
|
|||||||
if(cleanup_perform_app_handler_first)
|
if(cleanup_perform_app_handler_first)
|
||||||
if(cleanup_app_handler!=NULL) {
|
if(cleanup_app_handler!=NULL) {
|
||||||
ret= (*cleanup_app_handler)(cleanup_app_handle,signum,0);
|
ret= (*cleanup_app_handler)(cleanup_app_handle,signum,0);
|
||||||
if(ret==2)
|
if(ret==2 || ret==-2)
|
||||||
return(2);
|
return(2);
|
||||||
}
|
}
|
||||||
if(cleanup_exiting) {
|
if(cleanup_exiting) {
|
||||||
@ -77,11 +77,14 @@ static int Cleanup_handler_exit(int exit_value, int signum, int flag)
|
|||||||
}
|
}
|
||||||
cleanup_exiting= 1;
|
cleanup_exiting= 1;
|
||||||
if(cleanup_msg[0]!=0)
|
if(cleanup_msg[0]!=0)
|
||||||
fprintf(stderr,"%s\n",cleanup_msg);
|
fprintf(stderr,"\n%s\n",cleanup_msg);
|
||||||
alarm(0);
|
alarm(0);
|
||||||
if(!cleanup_perform_app_handler_first)
|
if(!cleanup_perform_app_handler_first)
|
||||||
if(cleanup_app_handler!=NULL)
|
if(cleanup_app_handler!=NULL) {
|
||||||
(*cleanup_app_handler)(cleanup_app_handle,signum,0);
|
ret= (*cleanup_app_handler)(cleanup_app_handle,signum,0);
|
||||||
|
if(ret==2 || ret==-2)
|
||||||
|
return(2);
|
||||||
|
}
|
||||||
exit(exit_value);
|
exit(exit_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,8 +118,12 @@ int Cleanup_set_handlers(void *handle, Cleanup_app_handler_T handler, int flag)
|
|||||||
cleanup_msg[0]= 0;
|
cleanup_msg[0]= 0;
|
||||||
cleanup_app_handle= handle;
|
cleanup_app_handle= handle;
|
||||||
cleanup_app_handler= handler;
|
cleanup_app_handler= handler;
|
||||||
|
|
||||||
|
/* <<< make cleanup_exiting thread safe to get rid of this */
|
||||||
if(flag&4)
|
if(flag&4)
|
||||||
cleanup_perform_app_handler_first= 1;
|
cleanup_perform_app_handler_first= 1;
|
||||||
|
|
||||||
|
|
||||||
if(flag&1)
|
if(flag&1)
|
||||||
sig_handler= SIG_DFL;
|
sig_handler= SIG_DFL;
|
||||||
else if(flag&2)
|
else if(flag&2)
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
A signal handler which cleans up an application and exits.
|
A signal handler which cleans up an application and exits.
|
||||||
|
|
||||||
Provided under GPL license within cdrskin and under BSD license elsewise.
|
Provided under GPL license within GPL projects, BSD license elsewise.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef Cleanup_includeD
|
#ifndef Cleanup_includeD
|
||||||
@ -13,7 +13,7 @@
|
|||||||
/** Layout of an application provided cleanup function using an application
|
/** Layout of an application provided cleanup function using an application
|
||||||
provided handle as first argument and the signal number as second
|
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.
|
argument. The third argument is a flag bit field with no defined bits yet.
|
||||||
If the handler returns 2 then it has delegated exit() to some other
|
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.
|
instance and the Cleanup handler shall return rather than exit.
|
||||||
*/
|
*/
|
||||||
typedef int (*Cleanup_app_handler_T)(void *, int, int);
|
typedef int (*Cleanup_app_handler_T)(void *, int, int);
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
debug_opts=
|
debug_opts=
|
||||||
def_opts=
|
def_opts=
|
||||||
libvers="-DCdrskin_libburn_0_2_3"
|
libvers="-DCdrskin_libburn_0_2_3"
|
||||||
|
cleanup_src_or_obj="cdrskin/cleanup.c"
|
||||||
libdax_msgs_o="libburn/libdax_msgs.o"
|
libdax_msgs_o="libburn/libdax_msgs.o"
|
||||||
do_strip=0
|
do_strip=0
|
||||||
static_opts=
|
static_opts=
|
||||||
@ -24,10 +25,12 @@ do
|
|||||||
then
|
then
|
||||||
libvers="-DCdrskin_libburn_cvs_A60220_tS"
|
libvers="-DCdrskin_libburn_cvs_A60220_tS"
|
||||||
libdax_msgs_o="libburn/message.o"
|
libdax_msgs_o="libburn/message.o"
|
||||||
|
cleanup_src_or_obj="cdrskin/cleanup.c"
|
||||||
elif test "$i" = "-libburn_0_2_2"
|
elif test "$i" = "-libburn_0_2_2"
|
||||||
then
|
then
|
||||||
libvers="-DCdrskin_libburn_0_2_2"
|
libvers="-DCdrskin_libburn_0_2_2"
|
||||||
libdax_msgs_o="libburn/message.o"
|
libdax_msgs_o="libburn/message.o"
|
||||||
|
cleanup_src_or_obj="cdrskin/cleanup.c"
|
||||||
elif test "$i" = "-libburn_0_2_3"
|
elif test "$i" = "-libburn_0_2_3"
|
||||||
then
|
then
|
||||||
libvers="-DCdrskin_libburn_0_2_3"
|
libvers="-DCdrskin_libburn_0_2_3"
|
||||||
@ -35,9 +38,11 @@ do
|
|||||||
elif test "$i" = "-newapi" -o "$i" = "-experimental"
|
elif test "$i" = "-newapi" -o "$i" = "-experimental"
|
||||||
then
|
then
|
||||||
def_opts="$def_opts -DCdrskin_new_api_tesT"
|
def_opts="$def_opts -DCdrskin_new_api_tesT"
|
||||||
|
cleanup_src_or_obj="libburn/cleanup.o"
|
||||||
elif test "$i" = "-oldfashioned"
|
elif test "$i" = "-oldfashioned"
|
||||||
then
|
then
|
||||||
def_opts="$def_opts -DCdrskin_oldfashioned_api_usE"
|
def_opts="$def_opts -DCdrskin_oldfashioned_api_usE"
|
||||||
|
cleanup_src_or_obj="cdrskin/cleanup.c"
|
||||||
elif test "$i" = "-do_not_compile_cdrskin"
|
elif test "$i" = "-do_not_compile_cdrskin"
|
||||||
then
|
then
|
||||||
compile_cdrskin=0
|
compile_cdrskin=0
|
||||||
@ -85,7 +90,7 @@ echo "Build timestamp : $timestamp"
|
|||||||
|
|
||||||
if test "$compile_cdrskin"
|
if test "$compile_cdrskin"
|
||||||
then
|
then
|
||||||
echo "compiling program cdrskin/cdrskin.c $static_opts $debug_opts $libvers $def_opts"
|
echo "compiling program cdrskin/cdrskin.c $static_opts $debug_opts $libvers $def_opts $cleanup_src_or_obj"
|
||||||
cc $warn_opts -I. $static_opts $debug_opts $libvers $def_opts \
|
cc $warn_opts -I. $static_opts $debug_opts $libvers $def_opts \
|
||||||
-DCdrskin_build_timestamP='"'"$timestamp"'"' \
|
-DCdrskin_build_timestamP='"'"$timestamp"'"' \
|
||||||
\
|
\
|
||||||
@ -93,7 +98,8 @@ then
|
|||||||
\
|
\
|
||||||
cdrskin/cdrskin.c \
|
cdrskin/cdrskin.c \
|
||||||
$fifo_source \
|
$fifo_source \
|
||||||
cdrskin/cleanup.c \
|
\
|
||||||
|
$cleanup_src_or_obj \
|
||||||
\
|
\
|
||||||
libburn/async.o \
|
libburn/async.o \
|
||||||
libburn/debug.o \
|
libburn/debug.o \
|
||||||
|
191
libburn/cleanup.c
Normal file
191
libburn/cleanup.c
Normal file
@ -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 */
|
34
libburn/cleanup.h
Normal file
34
libburn/cleanup.h
Normal file
@ -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 */
|
||||||
|
|
@ -38,6 +38,15 @@ int burn_sg_open_o_nonblock = 1;
|
|||||||
int burn_sg_open_abort_busy = 0;
|
int burn_sg_open_abort_busy = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A61002 */
|
||||||
|
|
||||||
|
#include "cleanup.h"
|
||||||
|
|
||||||
|
/* Parameters for builtin abort handler */
|
||||||
|
static char abort_message_prefix[81] = {"libburn : "};
|
||||||
|
static pid_t abort_control_pid= 0;
|
||||||
|
|
||||||
|
|
||||||
/* ts A60925 : ticket 74 */
|
/* ts A60925 : ticket 74 */
|
||||||
/** Create the messenger object for libburn. */
|
/** Create the messenger object for libburn. */
|
||||||
int burn_msgs_initialize(void)
|
int burn_msgs_initialize(void)
|
||||||
@ -197,3 +206,40 @@ ex:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int burn_builtin_abort_handler(void *handle, int signum, int flag)
|
||||||
|
{
|
||||||
|
if(getpid() != abort_control_pid)
|
||||||
|
return -2;
|
||||||
|
Cleanup_set_handlers(NULL, NULL, 2);
|
||||||
|
fprintf(stderr,"%sABORT : Trying to shut down drive and library\n",
|
||||||
|
abort_message_prefix);
|
||||||
|
fprintf(stderr,
|
||||||
|
"%sABORT : Wait the normal burning time before any kill -9\n",
|
||||||
|
abort_message_prefix);
|
||||||
|
close(0); /* somehow stdin as input blocks abort until EOF */
|
||||||
|
burn_abort(4440, burn_abort_pacifier, abort_message_prefix);
|
||||||
|
fprintf(stderr,
|
||||||
|
"\n%sABORT : Program done. Even if you do not see a shell prompt.\n\n",
|
||||||
|
abort_message_prefix);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_set_signal_handling(void *handle, burn_abort_handler_t handler,
|
||||||
|
int mode)
|
||||||
|
{
|
||||||
|
if(handler == NULL && mode == 0) {
|
||||||
|
handler = burn_builtin_abort_handler;
|
||||||
|
/*
|
||||||
|
fprintf(stderr, "libburn_experimental: activated burn_builtin_abort_handler() with handle '%s'\n",(handle==NULL ? "libburn : " : (char *) handle));
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
strcpy(abort_message_prefix, "libburn : ");
|
||||||
|
if(handle != NULL)
|
||||||
|
strncpy(abort_message_prefix, (char *) handle,
|
||||||
|
sizeof(abort_message_prefix)-1);
|
||||||
|
abort_message_prefix[sizeof(abort_message_prefix)-1] = 0;
|
||||||
|
abort_control_pid= getpid();
|
||||||
|
Cleanup_set_handlers(handle, (Cleanup_app_handler_T) handler, mode|4);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -392,7 +392,14 @@ int burn_initialize(void);
|
|||||||
void burn_finish(void);
|
void burn_finish(void);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A61002 */
|
||||||
/** Abort any running drive operation and finally call burn_finish().
|
/** Abort any running drive operation and finally call burn_finish().
|
||||||
|
You MUST calm down the busy drive if an aborting event occurs during a
|
||||||
|
burn run. For that you may call this function either from your own signal
|
||||||
|
handling code or indirectly by activating the builtin signal handling:
|
||||||
|
burn_set_signal_handling("my_app_name : ", NULL, 0);
|
||||||
|
Else you may eventually call burn_drive_cancel() on the active drive and
|
||||||
|
wait for it to assume state BURN_DRIVE_IDLE.
|
||||||
@param patience Maximum number of seconds to wait for drives to finish
|
@param patience Maximum number of seconds to wait for drives to finish
|
||||||
@param pacifier_func If not NULL: a function to produce appeasing messages.
|
@param pacifier_func If not NULL: a function to produce appeasing messages.
|
||||||
See burn_abort_pacifier() for an example.
|
See burn_abort_pacifier() for an example.
|
||||||
@ -406,6 +413,8 @@ int burn_abort(int patience,
|
|||||||
|
|
||||||
/** A pacifier function suitable for burn_abort.
|
/** A pacifier function suitable for burn_abort.
|
||||||
@param handle If not NULL, a pointer to a text suitable for printf("%s")
|
@param handle If not NULL, a pointer to a text suitable for printf("%s")
|
||||||
|
@param patience Maximum number of seconds to wait
|
||||||
|
@param elapsed Elapsed number of seconds
|
||||||
*/
|
*/
|
||||||
int burn_abort_pacifier(void *handle, int patience, int elapsed);
|
int burn_abort_pacifier(void *handle, int patience, int elapsed);
|
||||||
|
|
||||||
@ -1071,6 +1080,29 @@ int burn_msgs_obtain(char *minimum_severity,
|
|||||||
char severity[]);
|
char severity[]);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A61002 */
|
||||||
|
/* The prototype of a handler function suitable for burn_set_abort_handling().
|
||||||
|
Such a function has to return -2 if it does not want the process to
|
||||||
|
exit with value 1.
|
||||||
|
*/
|
||||||
|
typedef int (*burn_abort_handler_t)(void *handle, int signum, int flag);
|
||||||
|
|
||||||
|
/** Control builtin signal handling. See also burn_abort().
|
||||||
|
@param handle Opaque handle eventually pointing to an application
|
||||||
|
provided memory object
|
||||||
|
@param handler A function to be called on signals. It will get handle as
|
||||||
|
argument. It should finally call burn_abort(). See there.
|
||||||
|
@param mode : 0 call handler(handle, signum, 0) on nearly all signals
|
||||||
|
1 enable system default reaction on all signals
|
||||||
|
2 try to ignore nearly all signals
|
||||||
|
10 like mode 2 but handle SIGABRT like with mode 0
|
||||||
|
Arguments (text, NULL, 0) activate the builtin abort handler. It will
|
||||||
|
eventually call burn_abort() and then perform exit(1). If text is not NULL
|
||||||
|
then it is used as prefix for pacifier messages of burn_abort_pacifier().
|
||||||
|
*/
|
||||||
|
void burn_set_signal_handling(void *handle, burn_abort_handler_t handler,
|
||||||
|
int mode);
|
||||||
|
|
||||||
#ifndef DOXYGEN
|
#ifndef DOXYGEN
|
||||||
|
|
||||||
BURN_END_DECLS
|
BURN_END_DECLS
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
Before you can do anything, you have to initialize libburn by
|
Before you can do anything, you have to initialize libburn by
|
||||||
burn_initialize()
|
burn_initialize()
|
||||||
|
and provide some signal and abort handling, e.g. by the builtin handler, by
|
||||||
|
burn_set_signal_handling()
|
||||||
as it is done in main() at the end of this file. Then you aquire a
|
as it is done in main() at the end of this file. Then you aquire a
|
||||||
drive in an appropriate way conforming to the API. The two main
|
drive in an appropriate way conforming to the API. The two main
|
||||||
approaches are shown here in application functions:
|
approaches are shown here in application functions:
|
||||||
@ -248,10 +250,8 @@ int libburner_aquire_by_driveno(int *driveno)
|
|||||||
|
|
||||||
To our knowledge it is hardly possible to abort an ongoing blank operation
|
To our knowledge it is hardly possible to abort an ongoing blank operation
|
||||||
because after start it is entirely handled by the drive.
|
because after start it is entirely handled by the drive.
|
||||||
So expect a blank run to survive the end of the blanking process and be
|
So expect signal handling to wait the normal blanking timespan until it
|
||||||
patient for the usual timespan of a normal blank run. Only after that
|
can allow the process to end. External kill -9 will not help the drive.
|
||||||
time has surely elapsed, only then you should start any rescue attempts
|
|
||||||
with the drive. If necessary at all.
|
|
||||||
*/
|
*/
|
||||||
int libburner_blank_disc(struct burn_drive *drive, int blank_fast)
|
int libburner_blank_disc(struct burn_drive *drive, int blank_fast)
|
||||||
{
|
{
|
||||||
@ -322,25 +322,11 @@ int libburner_regrab(struct burn_drive *drive) {
|
|||||||
|
|
||||||
|
|
||||||
/** Brings the preformatted image (ISO 9660, afio, ext2, whatever) onto media.
|
/** Brings the preformatted image (ISO 9660, afio, ext2, whatever) onto media.
|
||||||
|
|
||||||
To make sure your image is fully readable on any Linux machine, this
|
To make sure your image is fully readable on any Linux machine, this
|
||||||
function adds 300 kB of padding to the track.
|
function adds 300 kB of padding to the track.
|
||||||
|
|
||||||
Without a signal handler it is quite dangerous to abort the process
|
In case of external signals expect abort handling of an ongoing burn to
|
||||||
while this function is active. See cdrskin/cdrskin.c and its usage
|
last up to a minute. Wait the normal burning timespan before any kill -9.
|
||||||
of cdrskin/cleanup.[ch] for an example of application provided
|
|
||||||
abort handling. It must cope with 2 of 3 threads reporting for
|
|
||||||
being handled.
|
|
||||||
|
|
||||||
Without signal handler have ready a command line
|
|
||||||
cdrecord dev=... -reset
|
|
||||||
with a dev= previously inquired by cdrecord [dev=ATA] -scanbus
|
|
||||||
in order to get your drive out of shock state after raw abort.
|
|
||||||
Thanks to Joerg Schilling for helping out unquestioned. :)
|
|
||||||
|
|
||||||
In general, libburn is less prone to system problems than cdrecord,
|
|
||||||
i believe. But cdrecord had long years of time to complete itself.
|
|
||||||
We are still practicing. Help us with that. :))
|
|
||||||
*/
|
*/
|
||||||
int libburner_payload(struct burn_drive *drive, const char *source_adr,
|
int libburner_payload(struct burn_drive *drive, const char *source_adr,
|
||||||
off_t size)
|
off_t size)
|
||||||
@ -590,6 +576,10 @@ int main(int argc, char **argv)
|
|||||||
exit(33);
|
exit(33);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Activate the default signal handler which eventually will try to
|
||||||
|
properly shutdown drive and library on aborting events. */
|
||||||
|
burn_set_signal_handling("libburner : ", NULL, 0);
|
||||||
|
|
||||||
/** Note: driveno might change its value in this call */
|
/** Note: driveno might change its value in this call */
|
||||||
ret = libburner_aquire_drive(drive_adr, &driveno);
|
ret = libburner_aquire_drive(drive_adr, &driveno);
|
||||||
if (ret<=0) {
|
if (ret<=0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user