Update copyright notices with scripts/update-copyrights
[glibc.git] / sysdeps / posix / sigvec.c
blob83ba75546f8ff6c8fadf91ca7730935c0e57fa31
1 /* Copyright (C) 1991-2014 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <http://www.gnu.org/licenses/>. */
18 #include <signal.h>
19 #include <errno.h>
20 #include <stddef.h>
22 /* Include macros to convert between `sigset_t' and old-style mask. */
23 #include <sigset-cvt-mask.h>
25 #ifndef SA_RESETHAND
26 /* When sigaction lacks the extension bit for it,
27 we use a wrapper handler to support SV_RESETHAND. */
28 struct sigvec_wrapper_data
30 __sighandler_t sw_handler;
31 unsigned int sw_mask;
34 static void sigvec_wrapper_handler (int sig) __THROW;
36 static struct sigvec_wrapper_data sigvec_wrapper_data[NSIG];
37 #endif
40 /* If VEC is non-NULL, set the handler for SIG to the `sv_handler' member
41 of VEC. The signals in `sv_mask' will be blocked while the handler runs.
42 If the SV_RESETHAND bit is set in `sv_flags', the handler for SIG will be
43 reset to SIG_DFL before `sv_handler' is entered. If OVEC is non-NULL,
44 it is filled in with the old information for SIG. */
45 int
46 __sigvec (sig, vec, ovec)
47 int sig;
48 const struct sigvec *vec;
49 struct sigvec *ovec;
51 struct sigaction old;
53 #ifndef SA_RESETHAND
54 if (vec == NULL || !(vec->sv_flags & SV_RESETHAND))
55 #endif
57 struct sigaction new, *n;
59 if (vec == NULL)
60 n = NULL;
61 else
63 __sighandler_t handler;
64 unsigned int mask;
65 unsigned int sv_flags;
66 unsigned int sa_flags;
68 handler = vec->sv_handler;
69 mask = vec->sv_mask;
70 sv_flags = vec->sv_flags;
71 sa_flags = 0;
72 if (sv_flags & SV_ONSTACK)
74 #ifdef SA_ONSTACK
75 sa_flags |= SA_ONSTACK;
76 #else
77 __set_errno (ENOSYS);
78 return -1;
79 #endif
81 #ifdef SA_RESTART
82 if (!(sv_flags & SV_INTERRUPT))
83 sa_flags |= SA_RESTART;
84 #endif
85 #ifdef SA_RESETHAND
86 if (sv_flags & SV_RESETHAND)
87 sa_flags |= SA_RESETHAND;
88 #endif
89 n = &new;
90 new.sa_handler = handler;
91 if (sigset_set_old_mask (&new.sa_mask, mask) < 0)
92 return -1;
93 new.sa_flags = sa_flags;
96 if (__sigaction (sig, n, &old) < 0)
97 return -1;
99 #ifndef SA_RESETHAND
100 else
102 __sighandler_t handler;
103 unsigned int mask;
104 struct sigvec_wrapper_data *data;
105 struct sigaction wrapper;
107 handler = vec->sv_handler;
108 mask = (unsigned int)vec->sv_mask;
109 data = &sigvec_wrapper_data[sig];
110 wrapper.sa_handler = sigvec_wrapper_handler;
111 /* FIXME: should we set wrapper.sa_mask, wrapper.sa_flags?? */
112 data->sw_handler = handler;
113 data->sw_mask = mask;
115 if (__sigaction (sig, &wrapper, &old) < 0)
116 return -1;
118 #endif
120 if (ovec != NULL)
122 __sighandler_t handler;
123 unsigned int sv_flags;
124 unsigned int sa_flags;
125 unsigned int mask;
127 handler = old.sa_handler;
128 sv_flags = 0;
129 sa_flags = old.sa_flags;
130 #ifndef SA_RESETHAND
131 if (handler == sigvec_wrapper_handler)
133 handler = sigvec_wrapper_data[sig].sw_handler;
134 /* should we use data->sw_mask?? */
135 sv_flags |= SV_RESETHAND;
137 #else
138 if (sa_flags & SA_RESETHAND)
139 sv_flags |= SV_RESETHAND;
140 #endif
141 mask = sigset_get_old_mask (&old.sa_mask);
142 #ifdef SA_ONSTACK
143 if (sa_flags & SA_ONSTACK)
144 sv_flags |= SV_ONSTACK;
145 #endif
146 #ifdef SA_RESTART
147 if (!(sa_flags & SA_RESTART))
148 #endif
149 sv_flags |= SV_INTERRUPT;
150 ovec->sv_handler = handler;
151 ovec->sv_mask = (int)mask;
152 ovec->sv_flags = (int)sv_flags;
155 return 0;
158 weak_alias (__sigvec, sigvec)
160 #ifndef SA_RESETHAND
161 static void
162 sigvec_wrapper_handler (sig)
163 int sig;
165 struct sigvec_wrapper_data *data;
166 struct sigaction act;
167 int save;
168 __sighandler_t handler;
170 data = &sigvec_wrapper_data[sig];
171 act.sa_handler = SIG_DFL;
172 act.sa_flags = 0;
173 sigset_set_old_mask (&act.sa_mask, data->sw_mask);
174 handler = data->sw_handler;
175 save = errno;
176 (void) __sigaction (sig, &act, (struct sigaction *) NULL);
177 __set_errno (save);
179 (*handler) (sig);
181 #endif