blob: 9d881da50acad7ccbadd5c6fb5a225f2ee49348c [file] [log] [blame]
njnde62cbf2005-06-10 22:08:14 +00001
2/*--------------------------------------------------------------------*/
3/*--- Signal-related libc stuff. m_libcsignal.c ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
sewardj9eecbbb2010-05-03 21:37:12 +000010 Copyright (C) 2000-2010 Julian Seward
njnde62cbf2005-06-10 22:08:14 +000011 jseward@acm.org
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
njnc7561b92005-06-19 01:24:32 +000031#include "pub_core_basics.h"
sewardj1383bdd2006-10-17 01:30:47 +000032#include "pub_core_debuglog.h"
sewardj4cfea4f2006-10-14 19:26:10 +000033#include "pub_core_vki.h"
sewardj1383bdd2006-10-17 01:30:47 +000034#include "pub_core_vkiscnums.h"
njnde62cbf2005-06-10 22:08:14 +000035#include "pub_core_libcbase.h"
36#include "pub_core_libcassert.h"
njn9abd6082005-06-17 21:31:45 +000037#include "pub_core_syscall.h"
sewardj1383bdd2006-10-17 01:30:47 +000038#include "pub_core_libcsignal.h" /* self */
njnde62cbf2005-06-10 22:08:14 +000039
njnf76d27a2009-05-28 01:53:07 +000040/* IMPORTANT: on Darwin it is essential to use the _nocancel versions
41 of syscalls rather than the vanilla version, if a _nocancel version
42 is available. See docs/internals/Darwin-notes.txt for the reason
43 why. */
44
njnde62cbf2005-06-10 22:08:14 +000045/* sigemptyset, sigfullset, sigaddset and sigdelset return 0 on
46 success and -1 on error. */
sewardj1383bdd2006-10-17 01:30:47 +000047/* I believe the indexing scheme in ->sig[] is also correct for
48 32- and 64-bit AIX (verified 27 July 06). */
njncda2f0f2009-05-18 02:12:08 +000049/* In the sigset routines below, be aware that _VKI_NSIG_BPW can be
50 either 32 or 64, and hence the sig[] words can either be 32- or
51 64-bits. And which they are it doesn't necessarily follow from the
52 host word size. */
njnde62cbf2005-06-10 22:08:14 +000053
54Int VG_(sigfillset)( vki_sigset_t* set )
55{
56 Int i;
57 if (set == NULL)
58 return -1;
59 for (i = 0; i < _VKI_NSIG_WORDS; i++)
njncda2f0f2009-05-18 02:12:08 +000060 set->sig[i] = ~0;
njnde62cbf2005-06-10 22:08:14 +000061 return 0;
62}
63
64Int VG_(sigemptyset)( vki_sigset_t* set )
65{
66 Int i;
67 if (set == NULL)
68 return -1;
69 for (i = 0; i < _VKI_NSIG_WORDS; i++)
njncda2f0f2009-05-18 02:12:08 +000070 set->sig[i] = 0;
njnde62cbf2005-06-10 22:08:14 +000071 return 0;
72}
73
74Bool VG_(isemptysigset)( const vki_sigset_t* set )
75{
76 Int i;
77 vg_assert(set != NULL);
78 for (i = 0; i < _VKI_NSIG_WORDS; i++)
njncda2f0f2009-05-18 02:12:08 +000079 if (set->sig[i] != 0) return False;
njnde62cbf2005-06-10 22:08:14 +000080 return True;
81}
82
83Bool VG_(isfullsigset)( const vki_sigset_t* set )
84{
85 Int i;
86 vg_assert(set != NULL);
87 for (i = 0; i < _VKI_NSIG_WORDS; i++)
njncda2f0f2009-05-18 02:12:08 +000088 if (set->sig[i] != ~0) return False;
njnde62cbf2005-06-10 22:08:14 +000089 return True;
90}
91
92Bool VG_(iseqsigset)( const vki_sigset_t* set1, const vki_sigset_t* set2 )
93{
94 Int i;
95 vg_assert(set1 != NULL && set2 != NULL);
96 for (i = 0; i < _VKI_NSIG_WORDS; i++)
97 if (set1->sig[i] != set2->sig[i]) return False;
98 return True;
99}
100
101
102Int VG_(sigaddset)( vki_sigset_t* set, Int signum )
103{
104 if (set == NULL)
105 return -1;
106 if (signum < 1 || signum > _VKI_NSIG)
107 return -1;
108 signum--;
njncda2f0f2009-05-18 02:12:08 +0000109 set->sig[signum / _VKI_NSIG_BPW] |= (1ULL << (signum % _VKI_NSIG_BPW));
njnde62cbf2005-06-10 22:08:14 +0000110 return 0;
111}
112
113Int VG_(sigdelset)( vki_sigset_t* set, Int signum )
114{
115 if (set == NULL)
116 return -1;
117 if (signum < 1 || signum > _VKI_NSIG)
118 return -1;
119 signum--;
njncda2f0f2009-05-18 02:12:08 +0000120 set->sig[signum / _VKI_NSIG_BPW] &= ~(1ULL << (signum % _VKI_NSIG_BPW));
njnde62cbf2005-06-10 22:08:14 +0000121 return 0;
122}
123
124Int VG_(sigismember) ( const vki_sigset_t* set, Int signum )
125{
126 if (set == NULL)
127 return 0;
128 if (signum < 1 || signum > _VKI_NSIG)
129 return 0;
130 signum--;
131 if (1 & ((set->sig[signum / _VKI_NSIG_BPW]) >> (signum % _VKI_NSIG_BPW)))
132 return 1;
133 else
134 return 0;
135}
136
njnde62cbf2005-06-10 22:08:14 +0000137/* Add all signals in src to dst. */
138void VG_(sigaddset_from_set)( vki_sigset_t* dst, vki_sigset_t* src )
139{
140 Int i;
141 vg_assert(dst != NULL && src != NULL);
142 for (i = 0; i < _VKI_NSIG_WORDS; i++)
143 dst->sig[i] |= src->sig[i];
144}
145
146/* Remove all signals in src from dst. */
147void VG_(sigdelset_from_set)( vki_sigset_t* dst, vki_sigset_t* src )
148{
149 Int i;
150 vg_assert(dst != NULL && src != NULL);
151 for (i = 0; i < _VKI_NSIG_WORDS; i++)
152 dst->sig[i] &= ~(src->sig[i]);
153}
154
njncda2f0f2009-05-18 02:12:08 +0000155/* dst = dst `intersect` src. */
156void VG_(sigintersectset)( vki_sigset_t* dst, vki_sigset_t* src )
157{
158 Int i;
159 vg_assert(dst != NULL && src != NULL);
160 for (i = 0; i < _VKI_NSIG_WORDS; i++)
161 dst->sig[i] &= src->sig[i];
162}
163
164/* dst = ~src */
165void VG_(sigcomplementset)( vki_sigset_t* dst, vki_sigset_t* src )
166{
167 Int i;
168 vg_assert(dst != NULL && src != NULL);
169 for (i = 0; i < _VKI_NSIG_WORDS; i++)
170 dst->sig[i] = ~ src->sig[i];
171}
172
njnde62cbf2005-06-10 22:08:14 +0000173
174/* The functions sigaction, sigprocmask, sigpending and sigsuspend
175 return 0 on success and -1 on error.
176*/
177Int VG_(sigprocmask)( Int how, const vki_sigset_t* set, vki_sigset_t* oldset)
178{
njncda2f0f2009-05-18 02:12:08 +0000179# if defined(VGO_linux) || defined(VGO_aix5)
180# if defined(__NR_rt_sigprocmask)
njnde62cbf2005-06-10 22:08:14 +0000181 SysRes res = VG_(do_syscall4)(__NR_rt_sigprocmask,
182 how, (UWord)set, (UWord)oldset,
183 _VKI_NSIG_WORDS * sizeof(UWord));
njncda2f0f2009-05-18 02:12:08 +0000184# else
185 SysRes res = VG_(do_syscall3)(__NR_sigprocmask,
186 how, (UWord)set, (UWord)oldset);
187# endif
188
njnf76d27a2009-05-28 01:53:07 +0000189# elif defined(VGO_darwin)
190 /* On Darwin, __NR_sigprocmask appears to affect the entire
191 process, not just this thread. Hence need to use
192 __NR___pthread_sigmask instead. */
193 SysRes res = VG_(do_syscall3)(__NR___pthread_sigmask,
194 how, (UWord)set, (UWord)oldset);
njncda2f0f2009-05-18 02:12:08 +0000195# else
196# error "Unknown OS"
197# endif
198 return sr_isError(res) ? -1 : 0;
njnde62cbf2005-06-10 22:08:14 +0000199}
200
201
njnf76d27a2009-05-28 01:53:07 +0000202#if defined(VGO_darwin)
203/* A helper function for sigaction on Darwin. */
204static
205void darwin_signal_demux(void* a1, UWord a2, UWord a3, void* a4, void* a5) {
206 VG_(debugLog)(2, "libcsignal",
207 "PRE demux sig, a2 = %lu, signo = %lu\n", a2, a3);
208 if (a2 == 1)
209 ((void(*)(int))a1) (a3);
210 else
211 ((void(*)(int,void*,void*))a1) (a3,a4,a5);
212 VG_(debugLog)(2, "libcsignal",
213 "POST demux sig, a2 = %lu, signo = %lu\n", a2, a3);
214 VG_(do_syscall2)(__NR_sigreturn, (UWord)a5, 0x1E);
215 /* NOTREACHED */
216 __asm__ __volatile__("ud2");
217}
218#endif
219
njncda2f0f2009-05-18 02:12:08 +0000220Int VG_(sigaction) ( Int signum,
221 const vki_sigaction_toK_t* act,
222 vki_sigaction_fromK_t* oldact)
njnde62cbf2005-06-10 22:08:14 +0000223{
njncda2f0f2009-05-18 02:12:08 +0000224# if defined(VGO_linux) || defined(VGO_aix5)
225 /* Normal case: vki_sigaction_toK_t and vki_sigaction_fromK_t are
226 identical types. */
njnde62cbf2005-06-10 22:08:14 +0000227 SysRes res = VG_(do_syscall4)(__NR_rt_sigaction,
228 signum, (UWord)act, (UWord)oldact,
229 _VKI_NSIG_WORDS * sizeof(UWord));
njncda2f0f2009-05-18 02:12:08 +0000230 return sr_isError(res) ? -1 : 0;
231
njnf76d27a2009-05-28 01:53:07 +0000232# elif defined(VGO_darwin)
233 /* If we're passing a new action to the kernel, make a copy of the
234 new action, install our own sa_tramp field in it, and ignore
235 whatever we were provided with. This is OK because all the
236 sigaction requests come from m_signals, and are not directly
237 what the client program requested, so there is no chance that we
238 will inadvertantly ignore the sa_tramp field requested by the
239 client. (In fact m_signals does ignore it when building signal
240 frames for the client, but that's a completely different
241 matter).
242
243 If we're receiving an old action from the kernel, be very
244 paranoid and make sure the kernel doesn't trash bits of memory
245 that we don't expect it to. */
246 SysRes res;
247
248 vki_sigaction_toK_t actCopy;
249 struct {
250 ULong before[2];
251 vki_sigaction_fromK_t oa;
252 ULong after[2];
253 }
254 oldactCopy;
255
256 vki_sigaction_toK_t* real_act;
257 vki_sigaction_fromK_t* real_oldact;
258
259 real_act = act ? &actCopy : NULL;
260 real_oldact = oldact ? &oldactCopy.oa : NULL;
261 VG_(memset)(&oldactCopy, 0x55, sizeof(oldactCopy));
262 if (real_act) {
263 *real_act = *act;
264 real_act->sa_tramp = (void*)&darwin_signal_demux;
265 }
266 res = VG_(do_syscall3)(__NR_sigaction,
267 signum, (UWord)real_act, (UWord)real_oldact);
268 if (real_oldact) {
269 vg_assert(oldactCopy.before[0] == 0x5555555555555555ULL);
270 vg_assert(oldactCopy.before[1] == 0x5555555555555555ULL);
271 vg_assert(oldactCopy.after[0] == 0x5555555555555555ULL);
272 vg_assert(oldactCopy.after[1] == 0x5555555555555555ULL);
273 *oldact = *real_oldact;
274 }
275 return sr_isError(res) ? -1 : 0;
276
njncda2f0f2009-05-18 02:12:08 +0000277# else
278# error "Unsupported OS"
279# endif
280}
281
282
283/* See explanation in pub_core_libcsignal.h. */
284void
285VG_(convert_sigaction_fromK_to_toK)( vki_sigaction_fromK_t* fromK,
286 /*OUT*/vki_sigaction_toK_t* toK )
287{
288# if defined(VGO_linux) || defined(VGO_aix5)
289 *toK = *fromK;
njnf76d27a2009-05-28 01:53:07 +0000290# elif defined(VGO_darwin)
291 toK->ksa_handler = fromK->ksa_handler;
292 toK->sa_tramp = NULL; /* the cause of all the difficulty */
293 toK->sa_mask = fromK->sa_mask;
294 toK->sa_flags = fromK->sa_flags;
njncda2f0f2009-05-18 02:12:08 +0000295# else
296# error "Unsupported OS"
297# endif
njnde62cbf2005-06-10 22:08:14 +0000298}
299
300
njnde62cbf2005-06-10 22:08:14 +0000301Int VG_(kill)( Int pid, Int signo )
302{
njnf76d27a2009-05-28 01:53:07 +0000303# if defined(VGO_linux) || defined(VGO_aix5)
njnde62cbf2005-06-10 22:08:14 +0000304 SysRes res = VG_(do_syscall2)(__NR_kill, pid, signo);
njnf76d27a2009-05-28 01:53:07 +0000305# elif defined(VGO_darwin)
306 SysRes res = VG_(do_syscall3)(__NR_kill,
307 pid, signo, 1/*posix-compliant*/);
308# else
309# error "Unsupported OS"
310# endif
njncda2f0f2009-05-18 02:12:08 +0000311 return sr_isError(res) ? -1 : 0;
njnde62cbf2005-06-10 22:08:14 +0000312}
313
njn99109fe2009-05-20 07:10:48 +0000314Int VG_(tkill)( Int lwpid, Int signo )
njnde62cbf2005-06-10 22:08:14 +0000315{
njncda2f0f2009-05-18 02:12:08 +0000316# if defined(__NR_tkill)
njnde62cbf2005-06-10 22:08:14 +0000317 SysRes res = VG_(mk_SysRes_Error)(VKI_ENOSYS);
njn99109fe2009-05-20 07:10:48 +0000318 res = VG_(do_syscall2)(__NR_tkill, lwpid, signo);
njncda2f0f2009-05-18 02:12:08 +0000319 if (sr_isError(res) && sr_Err(res) == VKI_ENOSYS)
njn99109fe2009-05-20 07:10:48 +0000320 res = VG_(do_syscall2)(__NR_kill, lwpid, signo);
njncda2f0f2009-05-18 02:12:08 +0000321 return sr_isError(res) ? -1 : 0;
322
njnf76d27a2009-05-28 01:53:07 +0000323# elif defined(VGO_darwin)
324 // Note that the __pthread_kill syscall takes a Mach thread, not a pthread.
325 SysRes res;
326 res = VG_(do_syscall2)(__NR___pthread_kill, lwpid, signo);
327 return sr_isError(res) ? -1 : 0;
328
njncda2f0f2009-05-18 02:12:08 +0000329# else
330# error "Unsupported plat"
331# endif
njnde62cbf2005-06-10 22:08:14 +0000332}
333
njncda2f0f2009-05-18 02:12:08 +0000334/* ---------------------- sigtimedwait_zero ----------------------- */
sewardj1383bdd2006-10-17 01:30:47 +0000335
336/* A cut-down version of POSIX sigtimedwait: poll for pending signals
337 mentioned in the sigset_t, and if any are present, select one
338 arbitrarily, return its number (which must be > 0), and put
339 auxiliary info about it in the siginfo_t, and make it
340 not-pending-any-more. If none are pending, return zero. The _zero
341 refers to the fact that there is zero timeout, so if no signals are
342 pending it returns immediately. Perhaps a better name would be
343 'sigpoll'. Returns -1 on error, 0 if no signals pending, and n > 0
344 if signal n was selected.
345
346 The Linux implementation is trivial: do the corresponding syscall.
347
348 The AIX implementation is horrible and probably broken in a dozen
349 obscure ways. I suspect it's only thread-safe because V forces
350 single-threadedness. */
351
njncda2f0f2009-05-18 02:12:08 +0000352/* ---------- sigtimedwait_zero: Linux ----------- */
353
sewardj1383bdd2006-10-17 01:30:47 +0000354#if defined(VGO_linux)
355Int VG_(sigtimedwait_zero)( const vki_sigset_t *set,
356 vki_siginfo_t *info )
357{
358 static const struct vki_timespec zero = { 0, 0 };
359 SysRes res = VG_(do_syscall4)(__NR_rt_sigtimedwait, (UWord)set, (UWord)info,
360 (UWord)&zero, sizeof(*set));
njncda2f0f2009-05-18 02:12:08 +0000361 return sr_isError(res) ? -1 : sr_Res(res);
sewardj1383bdd2006-10-17 01:30:47 +0000362}
363
njncda2f0f2009-05-18 02:12:08 +0000364/* ---------- sigtimedwait_zero: AIX5 ----------- */
365
sewardj1383bdd2006-10-17 01:30:47 +0000366#elif defined(VGO_aix5)
367/* The general idea is:
368 - use sigpending to find out which signals are pending
369 - choose one
370 - temporarily set its handler to sigtimedwait_zero_handler
371 - use sigsuspend atomically unblock it and wait for the signal.
372 Upon return, sigsuspend restores the signal mask to what it
373 was to start with.
374 - Restore the handler for the signal to whatever it was before.
375*/
376
377/* A signal handler which does nothing (it doesn't need to). It does
378 however check that it's not handing a sync signal for which
379 returning is meaningless. */
380static void sigtimedwait_zero_handler ( Int sig )
381{
382 vg_assert(sig != VKI_SIGILL);
383 vg_assert(sig != VKI_SIGSEGV);
384 vg_assert(sig != VKI_SIGBUS);
385 vg_assert(sig != VKI_SIGTRAP);
386 /* do nothing */
387}
388
389Int VG_(sigtimedwait_zero)( const vki_sigset_t *set,
390 vki_siginfo_t *info )
391{
392 Int i, ir;
393 SysRes sr;
394 vki_sigset_t pending, blocked, allbutone;
395 struct vki_sigaction sa, saved_sa;
396
397 /* Find out what's pending: AIX _sigpending */
398 sr = VG_(do_syscall1)(__NR__sigpending, (UWord)&pending);
399 vg_assert(!sr.isError);
400
401 /* don't try for signals not in 'set' */
402 /* pending = pending `intersect` set */
njn397080c2009-05-21 03:38:58 +0000403 VG_(sigintersectset)(&pending, set);
sewardj1383bdd2006-10-17 01:30:47 +0000404
405 /* don't try for signals not blocked at the moment */
406 ir = VG_(sigprocmask)(VKI_SIG_SETMASK, NULL, &blocked);
407 vg_assert(ir == 0);
408
409 /* pending = pending `intersect` blocked */
njncda2f0f2009-05-18 02:12:08 +0000410 VG_(sigintersectset)(&pending, blocked);
sewardj1383bdd2006-10-17 01:30:47 +0000411
412 /* decide which signal we're going to snarf */
413 for (i = 1; i < _VKI_NSIG; i++)
414 if (VG_(sigismember)(&pending,i))
415 break;
416
417 if (i == _VKI_NSIG)
418 return 0;
419
420 /* fetch signal i.
421 pre: i is blocked and pending
422 pre: we are the only thread running
423 */
424 /* Set up alternative signal handler */
425 VG_(sigfillset)(&allbutone);
426 VG_(sigdelset)(&allbutone, i);
427 sa.sa_mask = allbutone;
428 sa.ksa_handler = &sigtimedwait_zero_handler;
429 sa.sa_flags = 0;
430 ir = VG_(sigaction)(i, &sa, &saved_sa);
431 vg_assert(ir == 0);
432
433 /* Switch signal masks and wait for the signal. This should happen
434 immediately, since we've already established it is pending and
435 blocked. */
436 sr = VG_(do_syscall1)(__NR__sigsuspend, (UWord)&allbutone);
437 vg_assert(sr.isError);
438 if (0)
439 VG_(debugLog)(0, "libcsignal",
440 "sigtimedwait_zero: sigsuspend got res %ld err %ld\n",
441 sr.res, sr.err);
442 vg_assert(sr.res == (UWord)-1);
443
444 /* Restore signal's handler to whatever it was before */
445 ir = VG_(sigaction)(i, &saved_sa, NULL);
446 vg_assert(ir == 0);
447
448 /* This is bogus - we could get more info from the sighandler. */
449 VG_(memset)( info, 0, sizeof(*info) );
450 info->si_signo = i;
451
452 return i;
453}
454
njnf76d27a2009-05-28 01:53:07 +0000455/* ---------- sigtimedwait_zero: Darwin ----------- */
456
457#elif defined(VGO_darwin)
458
459//static void show_set ( HChar* str, const vki_sigset_t* set ) {
460// Int i;
461// VG_(printf)("%s { ", str);
462// for (i = 1; i <= _VKI_NSIG; i++) {
463// if (VG_(sigismember)(set, i))
464// VG_(printf)("%u ", i);
465// }
466// VG_(printf)("}\n");
467//}
468
469static void sigtimedwait_zero_handler ( Int sig )
470{
471 /* XXX this is wrong -- get rid of these. We could
472 get _any_ signal here */
473 vg_assert(sig != VKI_SIGILL);
474 vg_assert(sig != VKI_SIGSEGV);
475 vg_assert(sig != VKI_SIGBUS);
476 vg_assert(sig != VKI_SIGTRAP);
477 /* do nothing */
478}
479
480Int VG_(sigtimedwait_zero)( const vki_sigset_t *set,
481 vki_siginfo_t *info )
482{
483 const Bool debug = False;
484 Int i, ir;
485 SysRes sr;
486 vki_sigset_t pending, blocked, allbutone;
487 vki_sigaction_toK_t sa, saved_sa2;
488 vki_sigaction_fromK_t saved_sa;
489
490 //show_set("STWZ: looking for", set);
491
492 /* Find out what's pending: Darwin sigpending */
493 sr = VG_(do_syscall1)(__NR_sigpending, (UWord)&pending);
494 vg_assert(!sr_isError(sr));
495
496 /* don't try for signals not in 'set' */
497 /* pending = pending `intersect` set */
498 VG_(sigintersectset)(&pending, (vki_sigset_t*)set);
499
500 /* don't try for signals not blocked at the moment */
501 ir = VG_(sigprocmask)(VKI_SIG_SETMASK, NULL, &blocked);
502 vg_assert(ir == 0);
503
504 /* pending = pending `intersect` blocked */
505 VG_(sigintersectset)(&pending, &blocked);
506
507 /* decide which signal we're going to snarf */
508 for (i = 1; i < _VKI_NSIG; i++)
509 if (VG_(sigismember)(&pending,i))
510 break;
511
512 if (i == _VKI_NSIG)
513 return 0;
514
515 if (debug)
516 VG_(debugLog)(0, "libcsignal",
517 "sigtimedwait_zero: snarfing signal %d\n", i );
518
519 /* fetch signal i.
520 pre: i is blocked and pending
521 pre: we are the only thread running
522 */
523 /* Set up alternative signal handler */
524 VG_(sigfillset)(&sa.sa_mask);
525 sa.ksa_handler = &sigtimedwait_zero_handler;
526 sa.sa_flags = 0;
527 ir = VG_(sigaction)(i, &sa, &saved_sa);
528 vg_assert(ir == 0);
529
530 /* Switch signal masks and wait for the signal. This should happen
531 immediately, since we've already established it is pending and
532 blocked. */
533 VG_(sigfillset)(&allbutone);
534 VG_(sigdelset)(&allbutone, i);
535 /* Note: pass the sig mask by value here, not reference (!) */
536 vg_assert(_VKI_NSIG_WORDS == 1);
537 sr = VG_(do_syscall3)(__NR_sigsuspend_nocancel,
538 (UWord)allbutone.sig[0], 0,0);
539 if (debug)
540 VG_(debugLog)(0, "libcsignal",
541 "sigtimedwait_zero: sigsuspend got "
542 "res: %s %#lx\n",
543 sr_isError(sr) ? "FAIL" : "SUCCESS",
544 sr_isError(sr) ? sr_Err(sr) : sr_Res(sr));
545 vg_assert(sr_isError(sr));
546 vg_assert(sr_Err(sr) == VKI_EINTR);
547
548 /* Restore signal's handler to whatever it was before */
549 VG_(convert_sigaction_fromK_to_toK)( &saved_sa, &saved_sa2 );
550 ir = VG_(sigaction)(i, &saved_sa2, NULL);
551 vg_assert(ir == 0);
552
553 /* This is bogus - we could get more info from the sighandler. */
554 VG_(memset)( info, 0, sizeof(*info) );
555 info->si_signo = i;
556
557 return i;
558}
559
sewardj1383bdd2006-10-17 01:30:47 +0000560#else
njnf76d27a2009-05-28 01:53:07 +0000561# error "Unknown OS"
sewardj1383bdd2006-10-17 01:30:47 +0000562#endif
563
njnde62cbf2005-06-10 22:08:14 +0000564/*--------------------------------------------------------------------*/
565/*--- end ---*/
566/*--------------------------------------------------------------------*/