xorriso  1.5.4.pl02
About: GNU xorriso creates, loads, manipulates and writes ISO 9660 filesystem images with Rock Ridge extensions. It is suitable for incremental data backup and for production of bootable ISO 9660 images. GNU xorriso is a statical compilation of the libraries libburn, libisofs, libisoburn, and libjte.
  Fossies Dox: xorriso-1.5.4.pl02.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

cleanup.c
Go to the documentation of this file.
1 /*
2  cleanup.c , Copyright 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
3 
4  A signal handler which cleans up an application and exits.
5 
6  Provided under GPLv2+ license within GPL projects, BSD license elsewise.
7 */
8 
9 /*
10  cc -g -o cleanup -DCleanup_standalonE cleanup.c
11 */
12 
13 #ifdef HAVE_CONFIG_H
14 #include "../config.h"
15 #endif
16 
17 #include <sys/types.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <errno.h>
23 
24 #include <signal.h>
25 typedef void (*sighandler_t)(int);
26 
27 
28 #include "cleanup.h"
29 
30 
31 #ifndef Cleanup_has_no_libburn_os_H
32 
33 
34 #include "../libburn/os.h"
35 
36 /* see os.h for name of particular os-*.h where this is defined */
37 static int signal_list[]= { BURN_OS_SIGNAL_MACRO_LIST , -1};
38 static char *signal_name_list[]= { BURN_OS_SIGNAL_NAME_LIST , "@"};
42 
43 
44 #else /* ! Cleanup_has_no_libburn_os_H */
45 
46 
47 /* Outdated. GNU/Linux only.
48  For backward compatibility with pre-libburn-0.2.3 */
49 
50 /* Signals to be caught */
51 static int signal_list[]= {
52  SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT,
53  SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM,
54  SIGUSR1, SIGUSR2, SIGXCPU, SIGTSTP, SIGTTIN,
55  SIGTTOU,
56  SIGBUS, SIGPOLL, SIGPROF, SIGSYS, SIGTRAP,
57  SIGVTALRM, SIGXCPU, SIGXFSZ, -1
58 };
59 static char *signal_name_list[]= {
60  "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT",
61  "SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM",
62  "SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN",
63  "SIGTTOU",
64  "SIGBUS", "SIGPOLL", "SIGPROF", "SIGSYS", "SIGTRAP",
65  "SIGVTALRM", "SIGXCPU", "SIGXFSZ", "@"
66 };
67 static int signal_list_count= 24;
68 
69 /* Signals not to be caught */
70 static int non_signal_list[]= {
71  SIGKILL, SIGCHLD, SIGSTOP, SIGCONT, SIGURG, SIGWINCH, -1
72 };
73 static int non_signal_list_count= 6;
74 
75 
76 #endif /* Cleanup_has_no_libburn_os_H */
77 
78 
79 
80 /* run time dynamic part */
81 static char cleanup_msg[4096]= {""};
82 static int cleanup_exiting= 0;
83 static int cleanup_has_reported= -1234567890;
84 
85 static void *cleanup_app_handle= NULL;
88 
89 
90 static int Cleanup_handler_exit(int exit_value, int signum, int flag)
91 {
92  int ret;
93 
94  if(cleanup_msg[0]!=0 && cleanup_has_reported!=signum) {
95  fprintf(stderr,"\n%s\n",cleanup_msg);
96  cleanup_has_reported= signum;
97  }
99  if(cleanup_app_handler!=NULL) {
100  ret= (*cleanup_app_handler)(cleanup_app_handle,signum,0);
101  if(ret==2 || ret==-2)
102  return(2);
103  }
104  if(cleanup_exiting) {
105  fprintf(stderr,"cleanup: ABORT : repeat by pid=%.f, signum=%d\n",
106  (double) getpid(), signum);
107  return(0);
108  }
109  cleanup_exiting= 1;
110  alarm(0);
112  if(cleanup_app_handler!=NULL) {
113  ret= (*cleanup_app_handler)(cleanup_app_handle,signum,0);
114  if(ret==2 || ret==-2)
115  return(2);
116  }
117  exit(exit_value);
118 }
119 
120 
121 static void Cleanup_handler_generic(int signum)
122 {
123  int i;
124 
125  sprintf(cleanup_msg,"UNIX-SIGNAL caught: %d errno= %d",signum,errno);
126  for(i= 0; i<signal_list_count; i++)
127  if(signum==signal_list[i]) {
128  sprintf(cleanup_msg,"UNIX-SIGNAL: %s errno= %d",
129  signal_name_list[i],errno);
130  break;
131  }
132  Cleanup_handler_exit(1,signum,0);
133 }
134 
135 
136 static char *Cleanup_signo_to_name(int signo)
137 {
138  int i;
139  for(i= 0; i < signal_list_count; i++)
140  if(signal_list[i] == signo)
141  return(signal_name_list[i]);
142  return("");
143 }
144 
145 
146 int Cleanup_set_handlers(void *handle, Cleanup_app_handler_T handler, int flag)
147 /*
148  bit0= set to default handlers
149  bit1= set to ignore
150  bit2= set cleanup_perform_app_handler_first
151  bit3= set SIGABRT to handler (makes sense with bits 0 or 1)
152  bit8= set SIGPIPE to SIGIGN
153 */
154 {
155  int i,j,max_sig= -1,min_sig= 0x7fffffff;
156  char *sig_name;
157  sighandler_t sig_handler;
158 
159  cleanup_msg[0]= 0;
160  cleanup_app_handle= handle;
161  cleanup_app_handler= handler;
162 
163  /* <<< make cleanup_exiting thread safe to get rid of this */
164  if(flag&4)
166 
167 
168  if(flag&1)
169  sig_handler= SIG_DFL;
170  else if(flag&2)
171  sig_handler= SIG_IGN;
172  else
173  sig_handler= Cleanup_handler_generic;
174  /* set all signal numbers between the lowest and highest in the list
175  except those in the non-signal list */
176  for(i= 0; i<signal_list_count; i++) {
177  if(signal_list[i]>max_sig)
178  max_sig= signal_list[i];
179  if(signal_list[i]<min_sig)
180  min_sig= signal_list[i];
181  }
182  for(i= min_sig; i<=max_sig; i++) {
183  for(j= 0; j<non_signal_list_count; j++)
184  if(i==non_signal_list[j])
185  break;
186  if(j>=non_signal_list_count) {
187  /* Avoid to use particular SIG macros which might not be defined.
188  If they are defined, then their names are in the name list.
189  */
190  if(flag & (8 | 256))
191  sig_name= Cleanup_signo_to_name(i);
192  else
193  sig_name= "";
194  if((flag & 8) && strcmp(sig_name, "SIGABRT") == 0)
195  signal(i,Cleanup_handler_generic);
196  else if((flag & 256) && strcmp(sig_name, "SIGPIPE") == 0)
197  signal(i, SIG_IGN);
198  else
199  signal(i,sig_handler);
200  }
201  }
202  return(1);
203 }
204 
205 
206 #ifdef Cleanup_standalonE
207 
208 struct Demo_apP {
209  char *msg;
210 };
211 
212 
213 int Demo_app_handler(struct Demo_apP *demoapp, int signum, int flag)
214 {
215  printf("Handling exit of demo application on signal %d. msg=\"%s\"\n",
216  signum,demoapp->msg);
217  return(1);
218 }
219 
220 
221 main()
222 {
223  struct Demo_apP demoapp;
224 
225  demoapp.msg= "Good Bye";
226  Cleanup_set_handlers(&demoapp,(Cleanup_app_handler_T) Demo_app_handler,0);
227 
228  if(1) { /* change to 0 in order to wait for external signals */
229  char *cpt= NULL, c= ' ';
230  printf("Intentionally provoking SIGSEGV ...\n");
231  c= *cpt;
232  printf("Strange: The system ignored a SIGSEGV: c= %u\n", (unsigned int) c);
233  } else {
234  printf("killme: %d\n",getpid());
235  sleep(3600);
236  }
237 
238  Cleanup_set_handlers(NULL,NULL,1);
239  exit(0);
240 }
241 
242 #endif /* Cleanup_standalonE */
static void Cleanup_handler_generic(int signum)
Definition: cleanup.c:121
static int Cleanup_handler_exit(int exit_value, int signum, int flag)
Definition: cleanup.c:90
int Cleanup_set_handlers(void *handle, Cleanup_app_handler_T handler, int flag)
Definition: cleanup.c:146
static int signal_list_count
Definition: cleanup.c:39
static int non_signal_list_count
Definition: cleanup.c:41
static int signal_list[]
Definition: cleanup.c:37
static void * cleanup_app_handle
Definition: cleanup.c:85
static int non_signal_list[]
Definition: cleanup.c:40
static int cleanup_has_reported
Definition: cleanup.c:83
static char * Cleanup_signo_to_name(int signo)
Definition: cleanup.c:136
void(* sighandler_t)(int)
Definition: cleanup.c:25
static int cleanup_exiting
Definition: cleanup.c:82
static char * signal_name_list[]
Definition: cleanup.c:38
static Cleanup_app_handler_T cleanup_app_handler
Definition: cleanup.c:86
static char cleanup_msg[4096]
Definition: cleanup.c:81
static int cleanup_perform_app_handler_first
Definition: cleanup.c:87
int(* Cleanup_app_handler_T)(void *, int, int)
Definition: cleanup.h:19
int main(int argc, char *argv[])
#define BURN_OS_SIGNAL_COUNT
Definition: os-dummy.h:29
#define BURN_OS_SIGNAL_NAME_LIST
Definition: os-dummy.h:23
#define BURN_OS_NON_SIGNAL_MACRO_LIST
Definition: os-dummy.h:56
#define BURN_OS_SIGNAL_MACRO_LIST
Definition: os-dummy.h:17
#define BURN_OS_NON_SIGNAL_COUNT
Definition: os-dummy.h:61