chiark / gitweb /
eglibc (2.11.3-4+deb6u3) squeeze-lts; urgency=medium
[eglibc.git] / linuxthreads / sighandler.c
1 /* Linuxthreads - a simple clone()-based implementation of Posix        */
2 /* threads for Linux.                                                   */
3 /* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr)              */
4 /*                                                                      */
5 /* This program is free software; you can redistribute it and/or        */
6 /* modify it under the terms of the GNU Library General Public License  */
7 /* as published by the Free Software Foundation; either version 2       */
8 /* of the License, or (at your option) any later version.               */
9 /*                                                                      */
10 /* This program is distributed in the hope that it will be useful,      */
11 /* but WITHOUT ANY WARRANTY; without even the implied warranty of       */
12 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        */
13 /* GNU Library General Public License for more details.                 */
14
15 /* Signal handlers */
16
17 #include "internals.h"
18
19
20 /* The wrapper around user-provided signal handlers */
21 void __pthread_sighandler(int signo, SIGCONTEXT ctx)
22 {
23   pthread_descr self;
24   char * in_sighandler;
25   self = check_thread_self();
26
27   /* If we're in a sigwait operation, just record the signal received
28      and return without calling the user's handler */
29   if (THREAD_GETMEM(self, p_sigwaiting)) {
30     THREAD_SETMEM(self, p_sigwaiting, 0);
31     THREAD_SETMEM(self, p_signal, signo);
32     return;
33   }
34   /* Record that we're in a signal handler and call the user's
35      handler function */
36   in_sighandler = THREAD_GETMEM(self, p_in_sighandler);
37   if (in_sighandler == NULL)
38     THREAD_SETMEM(self, p_in_sighandler, CURRENT_STACK_FRAME);
39   CALL_SIGHANDLER(__sighandler[signo].old, signo, ctx);
40   if (in_sighandler == NULL)
41     THREAD_SETMEM(self, p_in_sighandler, NULL);
42 }
43
44 /* The same, this time for real-time signals.  */
45 void __pthread_sighandler_rt(int signo, struct siginfo *si,
46                              struct ucontext *uc)
47 {
48   pthread_descr self;
49   char * in_sighandler;
50   self = check_thread_self();
51
52   /* If we're in a sigwait operation, just record the signal received
53      and return without calling the user's handler */
54   if (THREAD_GETMEM(self, p_sigwaiting)) {
55     THREAD_SETMEM(self, p_sigwaiting, 0);
56     THREAD_SETMEM(self, p_signal, signo);
57     return;
58   }
59   /* Record that we're in a signal handler and call the user's
60      handler function */
61   in_sighandler = THREAD_GETMEM(self, p_in_sighandler);
62   if (in_sighandler == NULL)
63     THREAD_SETMEM(self, p_in_sighandler, CURRENT_STACK_FRAME);
64   __sighandler[signo].rt(signo, si, uc);
65   if (in_sighandler == NULL)
66     THREAD_SETMEM(self, p_in_sighandler, NULL);
67 }
68
69
70 /* A signal handler that does nothing */
71 void __pthread_null_sighandler(int sig) { }