Mercurial > hg > freeDiameter
comparison libfreeDiameter/signal.c @ 236:60f34df3e025
Remove dependency on signalent.h
author | Sebastien Decugis <sdecugis@nict.go.jp> |
---|---|
date | Mon, 08 Mar 2010 14:10:30 +0900 |
parents | 8773740401a5 |
children | 5df55136361b |
comparison
equal
deleted
inserted
replaced
235:8773740401a5 | 236:60f34df3e025 |
---|---|
35 | 35 |
36 #include "libfD.h" | 36 #include "libfD.h" |
37 | 37 |
38 #include <signal.h> | 38 #include <signal.h> |
39 | 39 |
40 /* List of signal names */ | |
41 #ifdef HAVE_SIGNALENT_H | |
42 const char *const fd_sig_str[] = { | |
43 # include "signalent.h" | |
44 }; | |
45 const int fd_sig_nstr = sizeof fd_sig_str / sizeof fd_sig_str[0]; | |
46 #endif /* HAVE_SIGNALENT_H */ | |
47 | |
48 /* A structure to hold the registered signal handlers */ | 40 /* A structure to hold the registered signal handlers */ |
49 struct sig_hdl { | 41 struct sig_hdl { |
50 struct fd_list chain; /* Link in the sig_hdl_list ordered by signal */ | 42 struct fd_list chain; /* Link in the sig_hdl_list ordered by signal */ |
51 int signal; /* The signal this handler is registered for */ | 43 int signal; /* The signal this handler is registered for */ |
52 void (*sig_hdl)(int);/* The callback to call when the signal is caught */ | 44 void (*sig_hdl)(int);/* The callback to call when the signal is caught */ |
62 static pthread_attr_t detached; | 54 static pthread_attr_t detached; |
63 | 55 |
64 /* Note if the module was initialized */ | 56 /* Note if the module was initialized */ |
65 static int sig_initialized = 0; | 57 static int sig_initialized = 0; |
66 | 58 |
59 /* signals short names list */ | |
60 static int abbrevs_init(void); | |
61 | |
67 /* Initialize the support for signals */ | 62 /* Initialize the support for signals */ |
68 int fd_sig_init(void) | 63 int fd_sig_init(void) |
69 { | 64 { |
70 sigset_t sig_all; | 65 sigset_t sig_all; |
71 | 66 |
72 TRACE_ENTRY(""); | 67 TRACE_ENTRY(""); |
73 | 68 |
74 if (sig_initialized) | 69 if (sig_initialized) |
75 return 0; | 70 return 0; |
71 | |
72 /* Initialize the list of abbreviations */ | |
73 CHECK_FCT(abbrevs_init()); | |
76 | 74 |
77 /* Block all signals from the current thread and all its future children, so that signals are delivered only to our sig_hdl->sig_thr */ | 75 /* Block all signals from the current thread and all its future children, so that signals are delivered only to our sig_hdl->sig_thr */ |
78 sigfillset(&sig_all); | 76 sigfillset(&sig_all); |
79 CHECK_POSIX( pthread_sigmask(SIG_BLOCK, &sig_all, NULL) ); | 77 CHECK_POSIX( pthread_sigmask(SIG_BLOCK, &sig_all, NULL) ); |
80 | 78 |
94 { | 92 { |
95 struct sig_hdl * me = arg; | 93 struct sig_hdl * me = arg; |
96 char buf[40]; | 94 char buf[40]; |
97 | 95 |
98 /* Name this thread */ | 96 /* Name this thread */ |
99 snprintf(buf, sizeof(buf), "cb %d:%s:%s", me->signal, SIGNALSTR(me->signal), me->modname); | 97 snprintf(buf, sizeof(buf), "cb %d:%s:%s", me->signal, fd_sig_abbrev(me->signal), me->modname); |
100 fd_log_threadname ( buf ); | 98 fd_log_threadname ( buf ); |
101 | 99 |
102 TRACE_ENTRY("%p", me); | 100 TRACE_ENTRY("%p", me); |
103 | 101 |
104 /* Call the signal handler */ | 102 /* Call the signal handler */ |
118 char buf[40]; | 116 char buf[40]; |
119 | 117 |
120 ASSERT(arg); | 118 ASSERT(arg); |
121 | 119 |
122 /* Name this thread */ | 120 /* Name this thread */ |
123 snprintf(buf, sizeof(buf), "catch %d:%s:%s", me->signal, SIGNALSTR(me->signal), me->modname); | 121 snprintf(buf, sizeof(buf), "catch %d:%s:%s", me->signal, fd_sig_abbrev(me->signal), me->modname); |
124 fd_log_threadname ( buf ); | 122 fd_log_threadname ( buf ); |
125 | 123 |
126 TRACE_ENTRY("%p", me); | 124 TRACE_ENTRY("%p", me); |
127 | 125 |
128 sigemptyset(&ss); | 126 sigemptyset(&ss); |
141 /* Create the thread that will call the handler */ | 139 /* Create the thread that will call the handler */ |
142 CHECK_POSIX_DO( pthread_create( &th, &detached, signal_caller, arg ), break ); | 140 CHECK_POSIX_DO( pthread_create( &th, &detached, signal_caller, arg ), break ); |
143 } | 141 } |
144 | 142 |
145 /* An error occurred... What should we do ? */ | 143 /* An error occurred... What should we do ? */ |
146 TRACE_DEBUG(INFO, "!!! ERROR !!! The signal catcher for %d:%s:%s is terminating!", me->signal, SIGNALSTR(me->signal), me->modname); | 144 TRACE_DEBUG(INFO, "!!! ERROR !!! The signal catcher for %d:%s:%s is terminating!", me->signal, fd_sig_abbrev(me->signal), me->modname); |
147 | 145 |
148 /* Better way to handle this ? */ | 146 /* Better way to handle this ? */ |
149 ASSERT(0); | 147 ASSERT(0); |
150 return NULL; | 148 return NULL; |
151 } | 149 } |
177 | 175 |
178 if (nh->signal < signal) | 176 if (nh->signal < signal) |
179 continue; | 177 continue; |
180 if (nh->signal == signal) { | 178 if (nh->signal == signal) { |
181 matched = 1; | 179 matched = 1; |
182 TRACE_DEBUG(INFO, "Signal %d (%s) is already registered by module '%s'", signal, SIGNALSTR(signal), nh->modname); | 180 TRACE_DEBUG(INFO, "Signal %d (%s) is already registered by module '%s'", signal, fd_sig_abbrev(signal), nh->modname); |
183 } | 181 } |
184 break; | 182 break; |
185 } | 183 } |
186 if (!matched) | 184 if (!matched) |
187 /* Insert the new element before the next handle */ | 185 /* Insert the new element before the next handle */ |
213 fd_log_debug("%*sList of registered signal handlers:\n", indent, ""); | 211 fd_log_debug("%*sList of registered signal handlers:\n", indent, ""); |
214 | 212 |
215 for (li = sig_hdl_list.next; li != &sig_hdl_list; li = li->next) { | 213 for (li = sig_hdl_list.next; li != &sig_hdl_list; li = li->next) { |
216 struct sig_hdl * h = (struct sig_hdl *)li; | 214 struct sig_hdl * h = (struct sig_hdl *)li; |
217 | 215 |
218 fd_log_debug("%*s - sig %*d (%s) => %p in module %s\n", indent, "", 2, h->signal, SIGNALSTR(h->signal), h->sig_hdl, h->modname); | 216 fd_log_debug("%*s - sig %*d (%s) => %p in module %s\n", indent, "", 2, h->signal, fd_sig_abbrev(h->signal), h->sig_hdl, h->modname); |
219 } | 217 } |
220 CHECK_POSIX_DO(pthread_mutex_unlock(&sig_hdl_lock), /* continue */); | 218 CHECK_POSIX_DO(pthread_mutex_unlock(&sig_hdl_lock), /* continue */); |
221 | 219 |
222 return; | 220 return; |
223 } | 221 } |
286 | 284 |
287 /* Destroy the thread attribute */ | 285 /* Destroy the thread attribute */ |
288 CHECK_POSIX_DO( pthread_attr_destroy(&detached), /* continue */ ); | 286 CHECK_POSIX_DO( pthread_attr_destroy(&detached), /* continue */ ); |
289 return; | 287 return; |
290 } | 288 } |
289 | |
290 | |
291 /**************************************************************************************/ | |
292 | |
293 static char **abbrevs; | |
294 static size_t abbrevs_nr = 0; | |
295 | |
296 /* Initialize the array of signals */ | |
297 static int abbrevs_init(void) | |
298 { | |
299 int i; | |
300 | |
301 #define SIGNAL_MAX_LIMIT 100 /* Do not save signals with value > this */ | |
302 | |
303 /* The raw list of signals in the system -- might be incomplete, add any signal you need */ | |
304 struct sig_abb_raw { | |
305 int sig; | |
306 char *name; | |
307 } abbrevs_raw[] = { | |
308 { 0, "[unknown signal]" } | |
309 #define RAW_SIGNAL( _sig ) ,{ _sig, #_sig } | |
310 #ifdef SIGBUS | |
311 RAW_SIGNAL( SIGBUS ) | |
312 #endif /* SIGBUS */ | |
313 #ifdef SIGTTIN | |
314 RAW_SIGNAL( SIGTTIN ) | |
315 #endif /* SIGTTIN */ | |
316 #ifdef SIGTTOU | |
317 RAW_SIGNAL( SIGTTOU ) | |
318 #endif /* SIGTTOU */ | |
319 #ifdef SIGPROF | |
320 RAW_SIGNAL( SIGPROF ) | |
321 #endif /* SIGPROF */ | |
322 #ifdef SIGALRM | |
323 RAW_SIGNAL( SIGALRM ) | |
324 #endif /* SIGALRM */ | |
325 #ifdef SIGFPE | |
326 RAW_SIGNAL( SIGFPE ) | |
327 #endif /* SIGFPE */ | |
328 #ifdef SIGSTKFLT | |
329 RAW_SIGNAL( SIGSTKFLT ) | |
330 #endif /* SIGSTKFLT */ | |
331 #ifdef SIGSTKSZ | |
332 RAW_SIGNAL( SIGSTKSZ ) | |
333 #endif /* SIGSTKSZ */ | |
334 #ifdef SIGUSR1 | |
335 RAW_SIGNAL( SIGUSR1 ) | |
336 #endif /* SIGUSR1 */ | |
337 #ifdef SIGURG | |
338 RAW_SIGNAL( SIGURG ) | |
339 #endif /* SIGURG */ | |
340 #ifdef SIGIO | |
341 RAW_SIGNAL( SIGIO ) | |
342 #endif /* SIGIO */ | |
343 #ifdef SIGQUIT | |
344 RAW_SIGNAL( SIGQUIT ) | |
345 #endif /* SIGQUIT */ | |
346 #ifdef SIGABRT | |
347 RAW_SIGNAL( SIGABRT ) | |
348 #endif /* SIGABRT */ | |
349 #ifdef SIGTRAP | |
350 RAW_SIGNAL( SIGTRAP ) | |
351 #endif /* SIGTRAP */ | |
352 #ifdef SIGVTALRM | |
353 RAW_SIGNAL( SIGVTALRM ) | |
354 #endif /* SIGVTALRM */ | |
355 #ifdef SIGSEGV | |
356 RAW_SIGNAL( SIGSEGV ) | |
357 #endif /* SIGSEGV */ | |
358 #ifdef SIGCONT | |
359 RAW_SIGNAL( SIGCONT ) | |
360 #endif /* SIGCONT */ | |
361 #ifdef SIGPIPE | |
362 RAW_SIGNAL( SIGPIPE ) | |
363 #endif /* SIGPIPE */ | |
364 #ifdef SIGWINCH | |
365 RAW_SIGNAL( SIGWINCH ) | |
366 #endif /* SIGWINCH */ | |
367 #ifdef SIGXFSZ | |
368 RAW_SIGNAL( SIGXFSZ ) | |
369 #endif /* SIGXFSZ */ | |
370 #ifdef SIGHUP | |
371 RAW_SIGNAL( SIGHUP ) | |
372 #endif /* SIGHUP */ | |
373 #ifdef SIGCHLD | |
374 RAW_SIGNAL( SIGCHLD ) | |
375 #endif /* SIGCHLD */ | |
376 #ifdef SIGSYS | |
377 RAW_SIGNAL( SIGSYS ) | |
378 #endif /* SIGSYS */ | |
379 #ifdef SIGSTOP | |
380 RAW_SIGNAL( SIGSTOP ) | |
381 #endif /* SIGSTOP */ | |
382 #ifdef SIGUSR2 | |
383 RAW_SIGNAL( SIGUSR2 ) | |
384 #endif /* SIGUSR2 */ | |
385 #ifdef SIGTSTP | |
386 RAW_SIGNAL( SIGTSTP ) | |
387 #endif /* SIGTSTP */ | |
388 #ifdef SIGKILL | |
389 RAW_SIGNAL( SIGKILL ) | |
390 #endif /* SIGKILL */ | |
391 #ifdef SIGXCPU | |
392 RAW_SIGNAL( SIGXCPU ) | |
393 #endif /* SIGXCPU */ | |
394 #ifdef SIGUNUSED | |
395 RAW_SIGNAL( SIGUNUSED ) | |
396 #endif /* SIGUNUSED */ | |
397 #ifdef SIGPWR | |
398 RAW_SIGNAL( SIGPWR ) | |
399 #endif /* SIGPWR */ | |
400 #ifdef SIGILL | |
401 RAW_SIGNAL( SIGILL ) | |
402 #endif /* SIGILL */ | |
403 #ifdef SIGINT | |
404 RAW_SIGNAL( SIGINT ) | |
405 #endif /* SIGINT */ | |
406 #ifdef SIGIOT | |
407 RAW_SIGNAL( SIGIOT ) | |
408 #endif /* SIGIOT */ | |
409 #ifdef SIGTERM | |
410 RAW_SIGNAL( SIGTERM ) | |
411 #endif /* SIGTERM */ | |
412 }; | |
413 | |
414 TRACE_ENTRY(""); | |
415 | |
416 /* First pass: find the highest signal number */ | |
417 for (i=0; i < sizeof(abbrevs_raw)/sizeof(abbrevs_raw[0]); i++) { | |
418 if (abbrevs_raw[i].sig > SIGNAL_MAX_LIMIT) { | |
419 TRACE_DEBUG(ANNOYING, "Ignoring signal %s (%d), increase SIGNAL_MAX_LIMIT if you want it included", abbrevs_raw[i].name, abbrevs_raw[i].sig); | |
420 continue; | |
421 } | |
422 if (abbrevs_raw[i].sig > abbrevs_nr) | |
423 abbrevs_nr = abbrevs_raw[i].sig; | |
424 } | |
425 | |
426 /* Now, alloc the array */ | |
427 abbrevs_nr++; /* 0-based */ | |
428 CHECK_MALLOC( abbrevs = calloc( abbrevs_nr, sizeof(char *) ) ); | |
429 | |
430 /* Second pass: add all the signals in the array */ | |
431 for (i=0; i < sizeof(abbrevs_raw)/sizeof(abbrevs_raw[0]); i++) { | |
432 if (abbrevs_raw[i].sig > SIGNAL_MAX_LIMIT) | |
433 continue; | |
434 | |
435 if (abbrevs[abbrevs_raw[i].sig] == NULL) | |
436 abbrevs[abbrevs_raw[i].sig] = abbrevs_raw[i].name; | |
437 } | |
438 | |
439 /* Third pass: Set all missing signals to the undef value */ | |
440 for (i=0; i < abbrevs_nr; i++) { | |
441 if (abbrevs[i] == NULL) | |
442 abbrevs[i] = abbrevs_raw[0].name; | |
443 } | |
444 | |
445 /* Done! */ | |
446 return 0; | |
447 } | |
448 | |
449 /* Names of signals */ | |
450 const char * fd_sig_abbrev(int signal) | |
451 { | |
452 if (signal < abbrevs_nr) | |
453 return abbrevs[signal]; | |
454 return abbrevs[0]; | |
455 } | |
456 |