From daf744276eaa60b7dc69aa9554ba0d37cc5813be Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Mon, 23 Jan 2012 10:15:01 +0000 Subject: [PATCH] Disabled dangerous abort handler actions while BURN_DRIVE_GRABBING --- cdrskin/cdrskin_timestamp.h | 2 +- libburn/drive.c | 33 +++++++++++++++----- libburn/init.c | 62 ++++++++++++++++++++++++++++++++----- libburn/init.h | 5 +++ libburn/libburn.h | 15 ++++++--- 5 files changed, 97 insertions(+), 20 deletions(-) diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index b7d01de..5fc48c2 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2012.01.22.125357" +#define Cdrskin_timestamP "2012.01.22.182854" diff --git a/libburn/drive.c b/libburn/drive.c index bccf6df..d288a37 100644 --- a/libburn/drive.c +++ b/libburn/drive.c @@ -486,9 +486,10 @@ int burn_drive_grab_stdio(struct burn_drive *d, int flag) int burn_drive_grab(struct burn_drive *d, int le) { int errcode; - /* ts A61125 - B10314 */ - int ret, sose; + /* ts A61125 - B20122 */ + int ret, sose, signal_action_mem = -1; + sose = d->silent_on_scsi_error; if (!d->released) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020189, LIBDAX_MSGS_SEV_FATAL, @@ -505,26 +506,40 @@ int burn_drive_grab(struct burn_drive *d, int le) errcode = d->grab(d); if (errcode == 0) return 0; + + burn_grab_prepare_sig_action(&signal_action_mem, 0); d->busy = BURN_DRIVE_GRABBING; if (le) d->load(d); + if (d->cancel || burn_is_aborting(0)) + {ret = 0; goto ex;} d->lock(d); + if (d->cancel || burn_is_aborting(0)) + {ret = 0; goto ex;} /* ts A61118 */ d->start_unit(d); + if (d->cancel || burn_is_aborting(0)) + {ret = 0; goto ex;} /* ts A61202 : gave bit1 of le a meaning */ - sose = d->silent_on_scsi_error; if (!le) d->silent_on_scsi_error = 1; /* ts A61125 : outsourced media state inquiry aspects */ ret = burn_drive_inquire_media(d); + if (d->cancel || burn_is_aborting(0)) + {ret = 0; goto ex;} burn_drive_send_default_page_05(d, 0); + if (d->cancel || burn_is_aborting(0)) + {ret = 0; goto ex;} + +ex:; d->silent_on_scsi_error = sose; d->busy = BURN_DRIVE_IDLE; + burn_grab_restore_sig_action(signal_action_mem, 0); return ret; } @@ -748,7 +763,7 @@ void burn_drive_release(struct burn_drive *d, int le) /* API */ int burn_drive_re_assess(struct burn_drive *d, int flag) { - int ret; + int ret, signal_action_mem; if (d->released) { libdax_msgs_submit(libdax_messenger, d->global_index, @@ -765,10 +780,12 @@ int burn_drive_re_assess(struct burn_drive *d, int flag) return ret; } + burn_grab_prepare_sig_action(&signal_action_mem, 0); d->busy = BURN_DRIVE_GRABBING; ret = burn_drive_inquire_media(d); burn_drive_send_default_page_05(d, 0); d->busy = BURN_DRIVE_IDLE; + burn_grab_restore_sig_action(signal_action_mem, 0); d->released = 0; return ret; } @@ -1388,7 +1405,7 @@ int burn_drive_forget(struct burn_drive *d, int force) if(occup > 0) if(force < 1) return 0; - if(occup > 10) + if(occup >= 10) return 0; /* >>> do any drive calming here */; @@ -2364,13 +2381,15 @@ int burn_abort_5(int patience, } - if(occup <= 10) { + if(occup < 10) { + if (!drive_array[i].cancel) + burn_drive_cancel(&(drive_array[i])); if (drive_array[i].drive_role != 1) /* occup == -1 comes early */ usleep(1000000); burn_drive_forget(&(drive_array[i]), 1); } else if(occup <= 100) { - if(first_round) + if (!drive_array[i].cancel) burn_drive_cancel(&(drive_array[i])); still_not_done++; } else if(occup <= 1000) { diff --git a/libburn/init.c b/libburn/init.c index 8a4c2c6..2e4babf 100644 --- a/libburn/init.c +++ b/libburn/init.c @@ -1,7 +1,7 @@ /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens - Copyright (c) 2006 - 2011 Thomas Schmitt + Copyright (c) 2006 - 2012 Thomas Schmitt Provided under GPL version 2 or later. */ @@ -362,6 +362,23 @@ char *burn_util_thread_id(pid_t pid, pthread_t tid, char text[80]) return text; } + +/* ts B20122 */ +/* @param value 0=return rather than exit(value) +*/ +int burn_abort_exit(int value) +{ + 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); + if (value) + exit(value); + burn_global_abort_level = -2; + return(1); +} + + int burn_builtin_abort_handler(void *handle, int signum, int flag) { @@ -476,13 +493,9 @@ int burn_builtin_abort_handler(void *handle, int signum, int flag) "%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); - burn_global_abort_level = -2; - return(1); + burn_abort_exit(0); + return (1); } @@ -550,6 +563,41 @@ int burn_init_catch_on_abort(int flag) } +/* B20122 */ +/* Temporarily disable builtin actions 0,1,2 to avoid that burn_abort() + waits for its own thread to end grabbing. +*/ +int burn_grab_prepare_sig_action(int *signal_action_mem, int flag) +{ + *signal_action_mem = -1; + if (burn_global_signal_handler == burn_builtin_abort_handler && + burn_builtin_signal_action >= 0 && + burn_builtin_signal_action <= 2) { + *signal_action_mem = burn_builtin_signal_action; + burn_builtin_signal_action = 3; + } + return 1; +} + + +/* B20122 */ +/* Re-enable builtin actions 0,1,2 and perform delayed signal reactions +*/ +int burn_grab_restore_sig_action(int signal_action_mem, int flag) +{ + if (signal_action_mem >= 0) + burn_builtin_signal_action = signal_action_mem; + if (burn_is_aborting(0) && signal_action_mem >= 0) { + if (signal_action_mem == 0 || signal_action_mem == 1) { + burn_abort_exit(1); /* Never comes back */ + } else if (signal_action_mem == 2) { + burn_builtin_triggered_action = signal_action_mem; + } + } + return 1; +} + + /* ts A70223 : API */ void burn_allow_untested_profiles(int yes) { diff --git a/libburn/init.h b/libburn/init.h index 813219d..4fe4224 100644 --- a/libburn/init.h +++ b/libburn/init.h @@ -48,4 +48,9 @@ void *burn_alloc_mem(size_t size, size_t count, int flag); } +/* B20122 */ +int burn_grab_prepare_sig_action(int *signal_action_mem, int flag); +int burn_grab_restore_sig_action(int signal_action_mem, int flag); + + #endif /* BURN__INIT_H */ diff --git a/libburn/libburn.h b/libburn/libburn.h index 65c8121..3091eeba 100644 --- a/libburn/libburn.h +++ b/libburn/libburn.h @@ -3622,12 +3622,17 @@ typedef int (*burn_abort_handler_t)(void *handle, int signum, int flag); @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. flag will be 0. + @param handler A function to be called on signals, if the handling bits + in parameter mode are set 0. + It will get parameter handle as argument. flag will be 0. It should finally call burn_abort(). See there. - @param mode : bit0 - bit3: - Receiving signals: - 0 Call handler(handle, signum, 0) on nearly all signals + If the handler function returns 2 or -2, then the wrapping + signal handler of libburn will return and let the program + continue its operations. Any other return value causes + exit(1). + @param mode : bit0 - bit3: Handling of received signals: + 0 Install libburn wrapping signal handler, which will 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