1de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
2de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn/*--------------------------------------------------------------------*/
3de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn/*--- Signal-related libc stuff.                    m_libcsignal.c ---*/
4de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn/*--------------------------------------------------------------------*/
5de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
6de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn/*
7de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   This file is part of Valgrind, a dynamic binary instrumentation
8de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   framework.
9de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
100f157ddb404bcde7815a1c5bf2d7e41c114f3d73sewardj   Copyright (C) 2000-2013 Julian Seward
11de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn      jseward@acm.org
12de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
13de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   This program is free software; you can redistribute it and/or
14de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   modify it under the terms of the GNU General Public License as
15de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   published by the Free Software Foundation; either version 2 of the
16de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   License, or (at your option) any later version.
17de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
18de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   This program is distributed in the hope that it will be useful, but
19de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   WITHOUT ANY WARRANTY; without even the implied warranty of
20de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   General Public License for more details.
22de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
23de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   You should have received a copy of the GNU General Public License
24de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   along with this program; if not, write to the Free Software
25de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   02111-1307, USA.
27de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
28de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   The GNU General Public License is contained in the file COPYING.
29de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn*/
30de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
31c7561b931e249acf3768ead77638545b0ccaa8f1njn#include "pub_core_basics.h"
321383bdd9919ad3e86eb142c05eae5b156eaa8122sewardj#include "pub_core_debuglog.h"
334cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj#include "pub_core_vki.h"
341383bdd9919ad3e86eb142c05eae5b156eaa8122sewardj#include "pub_core_vkiscnums.h"
35de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn#include "pub_core_libcbase.h"
36de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn#include "pub_core_libcassert.h"
379abd608244d8123868d027f616fa928156615d5anjn#include "pub_core_syscall.h"
381383bdd9919ad3e86eb142c05eae5b156eaa8122sewardj#include "pub_core_libcsignal.h"    /* self */
39de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
40f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/* IMPORTANT: on Darwin it is essential to use the _nocancel versions
41f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   of syscalls rather than the vanilla version, if a _nocancel version
42f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   is available.  See docs/internals/Darwin-notes.txt for the reason
43f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   why. */
44f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
45de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn/* sigemptyset, sigfullset, sigaddset and sigdelset return 0 on
46de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   success and -1 on error.  */
47cda2f0fbda4c4b2644babc830244be8aed95de1dnjn/* In the sigset routines below, be aware that _VKI_NSIG_BPW can be
48cda2f0fbda4c4b2644babc830244be8aed95de1dnjn   either 32 or 64, and hence the sig[] words can either be 32- or
49cda2f0fbda4c4b2644babc830244be8aed95de1dnjn   64-bits.  And which they are it doesn't necessarily follow from the
50cda2f0fbda4c4b2644babc830244be8aed95de1dnjn   host word size. */
51de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
52de62cbf607eb0e2dccb8bd6c7caf34180f528badnjnInt VG_(sigfillset)( vki_sigset_t* set )
53de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn{
54de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   Int i;
55de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   if (set == NULL)
56de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn      return -1;
57de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   for (i = 0; i < _VKI_NSIG_WORDS; i++)
58cda2f0fbda4c4b2644babc830244be8aed95de1dnjn      set->sig[i] = ~0;
59de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   return 0;
60de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn}
61de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
62de62cbf607eb0e2dccb8bd6c7caf34180f528badnjnInt VG_(sigemptyset)( vki_sigset_t* set )
63de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn{
64de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   Int i;
65de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   if (set == NULL)
66de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn      return -1;
67de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   for (i = 0; i < _VKI_NSIG_WORDS; i++)
68cda2f0fbda4c4b2644babc830244be8aed95de1dnjn      set->sig[i] = 0;
69de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   return 0;
70de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn}
71de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
72de62cbf607eb0e2dccb8bd6c7caf34180f528badnjnBool VG_(isemptysigset)( const vki_sigset_t* set )
73de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn{
74de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   Int i;
75de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   vg_assert(set != NULL);
76de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   for (i = 0; i < _VKI_NSIG_WORDS; i++)
77cda2f0fbda4c4b2644babc830244be8aed95de1dnjn      if (set->sig[i] != 0) return False;
78de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   return True;
79de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn}
80de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
81de62cbf607eb0e2dccb8bd6c7caf34180f528badnjnBool VG_(isfullsigset)( const vki_sigset_t* set )
82de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn{
83de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   Int i;
84de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   vg_assert(set != NULL);
85de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   for (i = 0; i < _VKI_NSIG_WORDS; i++)
86cda2f0fbda4c4b2644babc830244be8aed95de1dnjn      if (set->sig[i] != ~0) return False;
87de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   return True;
88de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn}
89de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
90de62cbf607eb0e2dccb8bd6c7caf34180f528badnjnBool VG_(iseqsigset)( const vki_sigset_t* set1, const vki_sigset_t* set2 )
91de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn{
92de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   Int i;
93de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   vg_assert(set1 != NULL && set2 != NULL);
94de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   for (i = 0; i < _VKI_NSIG_WORDS; i++)
95de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn      if (set1->sig[i] != set2->sig[i]) return False;
96de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   return True;
97de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn}
98de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
99de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
100de62cbf607eb0e2dccb8bd6c7caf34180f528badnjnInt VG_(sigaddset)( vki_sigset_t* set, Int signum )
101de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn{
102de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   if (set == NULL)
103de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn      return -1;
104de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   if (signum < 1 || signum > _VKI_NSIG)
105de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn      return -1;
106de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   signum--;
107cda2f0fbda4c4b2644babc830244be8aed95de1dnjn   set->sig[signum / _VKI_NSIG_BPW] |= (1ULL << (signum % _VKI_NSIG_BPW));
108de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   return 0;
109de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn}
110de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
111de62cbf607eb0e2dccb8bd6c7caf34180f528badnjnInt VG_(sigdelset)( vki_sigset_t* set, Int signum )
112de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn{
113de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   if (set == NULL)
114de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn      return -1;
115de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   if (signum < 1 || signum > _VKI_NSIG)
116de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn      return -1;
117de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   signum--;
118cda2f0fbda4c4b2644babc830244be8aed95de1dnjn   set->sig[signum / _VKI_NSIG_BPW] &= ~(1ULL << (signum % _VKI_NSIG_BPW));
119de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   return 0;
120de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn}
121de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
122de62cbf607eb0e2dccb8bd6c7caf34180f528badnjnInt VG_(sigismember) ( const vki_sigset_t* set, Int signum )
123de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn{
124de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   if (set == NULL)
125de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn      return 0;
126de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   if (signum < 1 || signum > _VKI_NSIG)
127de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn      return 0;
128de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   signum--;
129de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   if (1 & ((set->sig[signum / _VKI_NSIG_BPW]) >> (signum % _VKI_NSIG_BPW)))
130de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn      return 1;
131de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   else
132de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn      return 0;
133de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn}
134de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
135de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn/* Add all signals in src to dst. */
1363297124fa2116737066ac3cd709f18fdd5405163florianvoid VG_(sigaddset_from_set)( vki_sigset_t* dst, const vki_sigset_t* src )
137de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn{
138de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   Int i;
139de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   vg_assert(dst != NULL && src != NULL);
140de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   for (i = 0; i < _VKI_NSIG_WORDS; i++)
141de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn      dst->sig[i] |= src->sig[i];
142de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn}
143de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
144de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn/* Remove all signals in src from dst. */
1453297124fa2116737066ac3cd709f18fdd5405163florianvoid VG_(sigdelset_from_set)( vki_sigset_t* dst, const vki_sigset_t* src )
146de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn{
147de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   Int i;
148de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   vg_assert(dst != NULL && src != NULL);
149de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   for (i = 0; i < _VKI_NSIG_WORDS; i++)
150de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn      dst->sig[i] &= ~(src->sig[i]);
151de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn}
152de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
153cda2f0fbda4c4b2644babc830244be8aed95de1dnjn/* dst = dst `intersect` src. */
1543297124fa2116737066ac3cd709f18fdd5405163florianvoid VG_(sigintersectset)( vki_sigset_t* dst, const vki_sigset_t* src )
155cda2f0fbda4c4b2644babc830244be8aed95de1dnjn{
156cda2f0fbda4c4b2644babc830244be8aed95de1dnjn   Int i;
157cda2f0fbda4c4b2644babc830244be8aed95de1dnjn   vg_assert(dst != NULL && src != NULL);
158cda2f0fbda4c4b2644babc830244be8aed95de1dnjn   for (i = 0; i < _VKI_NSIG_WORDS; i++)
159cda2f0fbda4c4b2644babc830244be8aed95de1dnjn      dst->sig[i] &= src->sig[i];
160cda2f0fbda4c4b2644babc830244be8aed95de1dnjn}
161cda2f0fbda4c4b2644babc830244be8aed95de1dnjn
162cda2f0fbda4c4b2644babc830244be8aed95de1dnjn/* dst = ~src */
1633297124fa2116737066ac3cd709f18fdd5405163florianvoid VG_(sigcomplementset)( vki_sigset_t* dst, const vki_sigset_t* src )
164cda2f0fbda4c4b2644babc830244be8aed95de1dnjn{
165cda2f0fbda4c4b2644babc830244be8aed95de1dnjn   Int i;
166cda2f0fbda4c4b2644babc830244be8aed95de1dnjn   vg_assert(dst != NULL && src != NULL);
167cda2f0fbda4c4b2644babc830244be8aed95de1dnjn   for (i = 0; i < _VKI_NSIG_WORDS; i++)
168cda2f0fbda4c4b2644babc830244be8aed95de1dnjn      dst->sig[i] = ~ src->sig[i];
169cda2f0fbda4c4b2644babc830244be8aed95de1dnjn}
170cda2f0fbda4c4b2644babc830244be8aed95de1dnjn
171de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
172de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn/* The functions sigaction, sigprocmask, sigpending and sigsuspend
173de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   return 0 on success and -1 on error.
174de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn*/
175de62cbf607eb0e2dccb8bd6c7caf34180f528badnjnInt VG_(sigprocmask)( Int how, const vki_sigset_t* set, vki_sigset_t* oldset)
176de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn{
1776e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj#  if defined(VGO_linux)
178cda2f0fbda4c4b2644babc830244be8aed95de1dnjn#  if defined(__NR_rt_sigprocmask)
179de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   SysRes res = VG_(do_syscall4)(__NR_rt_sigprocmask,
180de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn                                 how, (UWord)set, (UWord)oldset,
181de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn                                 _VKI_NSIG_WORDS * sizeof(UWord));
182cda2f0fbda4c4b2644babc830244be8aed95de1dnjn#  else
183cda2f0fbda4c4b2644babc830244be8aed95de1dnjn   SysRes res = VG_(do_syscall3)(__NR_sigprocmask,
184cda2f0fbda4c4b2644babc830244be8aed95de1dnjn                                 how, (UWord)set, (UWord)oldset);
185cda2f0fbda4c4b2644babc830244be8aed95de1dnjn#  endif
186cda2f0fbda4c4b2644babc830244be8aed95de1dnjn
187f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#  elif defined(VGO_darwin)
188f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   /* On Darwin, __NR_sigprocmask appears to affect the entire
189f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      process, not just this thread.  Hence need to use
190f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      __NR___pthread_sigmask instead. */
191f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   SysRes res =  VG_(do_syscall3)(__NR___pthread_sigmask,
192f76d27a697a7b0bf3b84490baf60623fc96a23afnjn                                  how, (UWord)set, (UWord)oldset);
193cda2f0fbda4c4b2644babc830244be8aed95de1dnjn#  else
194cda2f0fbda4c4b2644babc830244be8aed95de1dnjn#    error "Unknown OS"
195cda2f0fbda4c4b2644babc830244be8aed95de1dnjn#  endif
196cda2f0fbda4c4b2644babc830244be8aed95de1dnjn   return sr_isError(res) ? -1 : 0;
197de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn}
198de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
199de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
200f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VGO_darwin)
201f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/* A helper function for sigaction on Darwin. */
202f76d27a697a7b0bf3b84490baf60623fc96a23afnjnstatic
203f76d27a697a7b0bf3b84490baf60623fc96a23afnjnvoid darwin_signal_demux(void* a1, UWord a2, UWord a3, void* a4, void* a5) {
204f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   VG_(debugLog)(2, "libcsignal",
205f76d27a697a7b0bf3b84490baf60623fc96a23afnjn                    "PRE  demux sig, a2 = %lu, signo = %lu\n", a2, a3);
206f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   if (a2 == 1)
207f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      ((void(*)(int))a1) (a3);
208f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   else
209f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      ((void(*)(int,void*,void*))a1) (a3,a4,a5);
210f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   VG_(debugLog)(2, "libcsignal",
211f76d27a697a7b0bf3b84490baf60623fc96a23afnjn                    "POST demux sig, a2 = %lu, signo = %lu\n", a2, a3);
212f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   VG_(do_syscall2)(__NR_sigreturn, (UWord)a5, 0x1E);
213f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   /* NOTREACHED */
214f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   __asm__ __volatile__("ud2");
215f76d27a697a7b0bf3b84490baf60623fc96a23afnjn}
216f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif
217f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
218cda2f0fbda4c4b2644babc830244be8aed95de1dnjnInt VG_(sigaction) ( Int signum,
219cda2f0fbda4c4b2644babc830244be8aed95de1dnjn                     const vki_sigaction_toK_t* act,
220cda2f0fbda4c4b2644babc830244be8aed95de1dnjn                     vki_sigaction_fromK_t* oldact)
221de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn{
2226e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj#  if defined(VGO_linux)
223cda2f0fbda4c4b2644babc830244be8aed95de1dnjn   /* Normal case: vki_sigaction_toK_t and vki_sigaction_fromK_t are
224cda2f0fbda4c4b2644babc830244be8aed95de1dnjn      identical types. */
225de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   SysRes res = VG_(do_syscall4)(__NR_rt_sigaction,
226de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn                                 signum, (UWord)act, (UWord)oldact,
227de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn                                 _VKI_NSIG_WORDS * sizeof(UWord));
228cda2f0fbda4c4b2644babc830244be8aed95de1dnjn   return sr_isError(res) ? -1 : 0;
229cda2f0fbda4c4b2644babc830244be8aed95de1dnjn
230f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#  elif defined(VGO_darwin)
231f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   /* If we're passing a new action to the kernel, make a copy of the
232f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      new action, install our own sa_tramp field in it, and ignore
233f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      whatever we were provided with.  This is OK because all the
234f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      sigaction requests come from m_signals, and are not directly
235f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      what the client program requested, so there is no chance that we
236f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      will inadvertantly ignore the sa_tramp field requested by the
237f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      client.  (In fact m_signals does ignore it when building signal
238f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      frames for the client, but that's a completely different
239f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      matter).
240f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
241f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      If we're receiving an old action from the kernel, be very
242f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      paranoid and make sure the kernel doesn't trash bits of memory
243f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      that we don't expect it to. */
244f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   SysRes res;
245f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
246f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   vki_sigaction_toK_t actCopy;
247f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   struct {
248f76d27a697a7b0bf3b84490baf60623fc96a23afnjn     ULong before[2];
249f76d27a697a7b0bf3b84490baf60623fc96a23afnjn     vki_sigaction_fromK_t oa;
250f76d27a697a7b0bf3b84490baf60623fc96a23afnjn     ULong after[2];
251f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   }
252f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   oldactCopy;
253f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
254f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   vki_sigaction_toK_t*   real_act;
255f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   vki_sigaction_fromK_t* real_oldact;
256f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
257f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   real_act    = act    ? &actCopy       : NULL;
258f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   real_oldact = oldact ? &oldactCopy.oa : NULL;
259f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   VG_(memset)(&oldactCopy, 0x55, sizeof(oldactCopy));
260f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   if (real_act) {
261f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      *real_act = *act;
262f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      real_act->sa_tramp = (void*)&darwin_signal_demux;
263f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   }
264f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   res = VG_(do_syscall3)(__NR_sigaction,
265f76d27a697a7b0bf3b84490baf60623fc96a23afnjn                          signum, (UWord)real_act, (UWord)real_oldact);
266f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   if (real_oldact) {
267f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      vg_assert(oldactCopy.before[0] == 0x5555555555555555ULL);
268f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      vg_assert(oldactCopy.before[1] == 0x5555555555555555ULL);
269f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      vg_assert(oldactCopy.after[0]  == 0x5555555555555555ULL);
270f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      vg_assert(oldactCopy.after[1]  == 0x5555555555555555ULL);
271f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      *oldact = *real_oldact;
272f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   }
273f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   return sr_isError(res) ? -1 : 0;
274f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
275cda2f0fbda4c4b2644babc830244be8aed95de1dnjn#  else
276cda2f0fbda4c4b2644babc830244be8aed95de1dnjn#    error "Unsupported OS"
277cda2f0fbda4c4b2644babc830244be8aed95de1dnjn#  endif
278cda2f0fbda4c4b2644babc830244be8aed95de1dnjn}
279cda2f0fbda4c4b2644babc830244be8aed95de1dnjn
280cda2f0fbda4c4b2644babc830244be8aed95de1dnjn
281cda2f0fbda4c4b2644babc830244be8aed95de1dnjn/* See explanation in pub_core_libcsignal.h. */
282cda2f0fbda4c4b2644babc830244be8aed95de1dnjnvoid
2833297124fa2116737066ac3cd709f18fdd5405163florianVG_(convert_sigaction_fromK_to_toK)( const vki_sigaction_fromK_t* fromK,
284cda2f0fbda4c4b2644babc830244be8aed95de1dnjn                                     /*OUT*/vki_sigaction_toK_t* toK )
285cda2f0fbda4c4b2644babc830244be8aed95de1dnjn{
2866e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj#  if defined(VGO_linux)
287cda2f0fbda4c4b2644babc830244be8aed95de1dnjn   *toK = *fromK;
288f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#  elif defined(VGO_darwin)
289f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   toK->ksa_handler = fromK->ksa_handler;
290f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   toK->sa_tramp    = NULL; /* the cause of all the difficulty */
291f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   toK->sa_mask     = fromK->sa_mask;
292f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   toK->sa_flags    = fromK->sa_flags;
293cda2f0fbda4c4b2644babc830244be8aed95de1dnjn#  else
294cda2f0fbda4c4b2644babc830244be8aed95de1dnjn#    error "Unsupported OS"
295cda2f0fbda4c4b2644babc830244be8aed95de1dnjn#  endif
296de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn}
297de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
298de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
299de62cbf607eb0e2dccb8bd6c7caf34180f528badnjnInt VG_(kill)( Int pid, Int signo )
300de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn{
3016e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj#  if defined(VGO_linux)
302de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   SysRes res = VG_(do_syscall2)(__NR_kill, pid, signo);
303f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#  elif defined(VGO_darwin)
304f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   SysRes res = VG_(do_syscall3)(__NR_kill,
305f76d27a697a7b0bf3b84490baf60623fc96a23afnjn                                 pid, signo, 1/*posix-compliant*/);
306f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#  else
307f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#    error "Unsupported OS"
308f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#  endif
309cda2f0fbda4c4b2644babc830244be8aed95de1dnjn   return sr_isError(res) ? -1 : 0;
310de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn}
311de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
31299109fe5205aecbcad0a8428e8ee9e6d2d531ec3njnInt VG_(tkill)( Int lwpid, Int signo )
313de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn{
314cda2f0fbda4c4b2644babc830244be8aed95de1dnjn#  if defined(__NR_tkill)
315de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn   SysRes res = VG_(mk_SysRes_Error)(VKI_ENOSYS);
31699109fe5205aecbcad0a8428e8ee9e6d2d531ec3njn   res = VG_(do_syscall2)(__NR_tkill, lwpid, signo);
317cda2f0fbda4c4b2644babc830244be8aed95de1dnjn   if (sr_isError(res) && sr_Err(res) == VKI_ENOSYS)
31899109fe5205aecbcad0a8428e8ee9e6d2d531ec3njn      res = VG_(do_syscall2)(__NR_kill, lwpid, signo);
319cda2f0fbda4c4b2644babc830244be8aed95de1dnjn   return sr_isError(res) ? -1 : 0;
320cda2f0fbda4c4b2644babc830244be8aed95de1dnjn
321f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#  elif defined(VGO_darwin)
322f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   // Note that the __pthread_kill syscall takes a Mach thread, not a pthread.
323f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   SysRes res;
324f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   res = VG_(do_syscall2)(__NR___pthread_kill, lwpid, signo);
325f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   return sr_isError(res) ? -1 : 0;
326f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
327cda2f0fbda4c4b2644babc830244be8aed95de1dnjn#  else
328cda2f0fbda4c4b2644babc830244be8aed95de1dnjn#    error "Unsupported plat"
329cda2f0fbda4c4b2644babc830244be8aed95de1dnjn#  endif
3301383bdd9919ad3e86eb142c05eae5b156eaa8122sewardj}
331de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
332cda2f0fbda4c4b2644babc830244be8aed95de1dnjn/* ---------------------- sigtimedwait_zero ----------------------- */
333de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
3341383bdd9919ad3e86eb142c05eae5b156eaa8122sewardj/* A cut-down version of POSIX sigtimedwait: poll for pending signals
3351383bdd9919ad3e86eb142c05eae5b156eaa8122sewardj   mentioned in the sigset_t, and if any are present, select one
3361383bdd9919ad3e86eb142c05eae5b156eaa8122sewardj   arbitrarily, return its number (which must be > 0), and put
3371383bdd9919ad3e86eb142c05eae5b156eaa8122sewardj   auxiliary info about it in the siginfo_t, and make it
3381383bdd9919ad3e86eb142c05eae5b156eaa8122sewardj   not-pending-any-more.  If none are pending, return zero.  The _zero
3391383bdd9919ad3e86eb142c05eae5b156eaa8122sewardj   refers to the fact that there is zero timeout, so if no signals are
3401383bdd9919ad3e86eb142c05eae5b156eaa8122sewardj   pending it returns immediately.  Perhaps a better name would be
3411383bdd9919ad3e86eb142c05eae5b156eaa8122sewardj   'sigpoll'.  Returns -1 on error, 0 if no signals pending, and n > 0
3421383bdd9919ad3e86eb142c05eae5b156eaa8122sewardj   if signal n was selected.
343de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
3441383bdd9919ad3e86eb142c05eae5b156eaa8122sewardj   The Linux implementation is trivial: do the corresponding syscall.
345de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
3466e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj   The Darwin implementation is horrible and probably broken in a dozen
3471383bdd9919ad3e86eb142c05eae5b156eaa8122sewardj   obscure ways.  I suspect it's only thread-safe because V forces
3481383bdd9919ad3e86eb142c05eae5b156eaa8122sewardj   single-threadedness. */
3491383bdd9919ad3e86eb142c05eae5b156eaa8122sewardj
350cda2f0fbda4c4b2644babc830244be8aed95de1dnjn/* ---------- sigtimedwait_zero: Linux ----------- */
351cda2f0fbda4c4b2644babc830244be8aed95de1dnjn
3521383bdd9919ad3e86eb142c05eae5b156eaa8122sewardj#if defined(VGO_linux)
3531383bdd9919ad3e86eb142c05eae5b156eaa8122sewardjInt VG_(sigtimedwait_zero)( const vki_sigset_t *set,
3541383bdd9919ad3e86eb142c05eae5b156eaa8122sewardj                            vki_siginfo_t *info )
3551383bdd9919ad3e86eb142c05eae5b156eaa8122sewardj{
3561383bdd9919ad3e86eb142c05eae5b156eaa8122sewardj   static const struct vki_timespec zero = { 0, 0 };
3571383bdd9919ad3e86eb142c05eae5b156eaa8122sewardj   SysRes res = VG_(do_syscall4)(__NR_rt_sigtimedwait, (UWord)set, (UWord)info,
3581383bdd9919ad3e86eb142c05eae5b156eaa8122sewardj                                 (UWord)&zero, sizeof(*set));
359cda2f0fbda4c4b2644babc830244be8aed95de1dnjn   return sr_isError(res) ? -1 : sr_Res(res);
360de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn}
361de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn
362f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/* ---------- sigtimedwait_zero: Darwin ----------- */
363f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
364f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#elif defined(VGO_darwin)
365f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
366f76d27a697a7b0bf3b84490baf60623fc96a23afnjn//static void show_set ( HChar* str, const vki_sigset_t* set ) {
367f76d27a697a7b0bf3b84490baf60623fc96a23afnjn//   Int i;
368f76d27a697a7b0bf3b84490baf60623fc96a23afnjn//   VG_(printf)("%s { ", str);
369f76d27a697a7b0bf3b84490baf60623fc96a23afnjn//   for (i = 1; i <= _VKI_NSIG; i++) {
370f76d27a697a7b0bf3b84490baf60623fc96a23afnjn//     if (VG_(sigismember)(set, i))
371f76d27a697a7b0bf3b84490baf60623fc96a23afnjn//         VG_(printf)("%u ", i);
372f76d27a697a7b0bf3b84490baf60623fc96a23afnjn//   }
373f76d27a697a7b0bf3b84490baf60623fc96a23afnjn//   VG_(printf)("}\n");
374f76d27a697a7b0bf3b84490baf60623fc96a23afnjn//}
375f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
3766e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj/* The general idea is:
3776e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj   - use sigpending to find out which signals are pending
3786e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj   - choose one
3796e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj   - temporarily set its handler to sigtimedwait_zero_handler
3806e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj   - use sigsuspend atomically unblock it and wait for the signal.
3816e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj     Upon return, sigsuspend restores the signal mask to what it
3826e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj     was to start with.
3836e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj   - Restore the handler for the signal to whatever it was before.
3846e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj*/
3856e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj
3866e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj/* A signal handler which does nothing (it doesn't need to).  It does
3876e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj   however check that it's not handing a sync signal for which
3886e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj   returning is meaningless. */
389f76d27a697a7b0bf3b84490baf60623fc96a23afnjnstatic void sigtimedwait_zero_handler ( Int sig )
390f76d27a697a7b0bf3b84490baf60623fc96a23afnjn{
391f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   /* XXX this is wrong -- get rid of these.  We could
392f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      get _any_ signal here */
393f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   vg_assert(sig != VKI_SIGILL);
394f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   vg_assert(sig != VKI_SIGSEGV);
395f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   vg_assert(sig != VKI_SIGBUS);
396f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   vg_assert(sig != VKI_SIGTRAP);
397f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   /* do nothing */
398f76d27a697a7b0bf3b84490baf60623fc96a23afnjn}
399f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
400f76d27a697a7b0bf3b84490baf60623fc96a23afnjnInt VG_(sigtimedwait_zero)( const vki_sigset_t *set,
401f76d27a697a7b0bf3b84490baf60623fc96a23afnjn                            vki_siginfo_t *info )
402f76d27a697a7b0bf3b84490baf60623fc96a23afnjn{
403f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  const Bool debug = False;
404f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  Int    i, ir;
405f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  SysRes sr;
406f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  vki_sigset_t pending, blocked, allbutone;
407f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  vki_sigaction_toK_t   sa, saved_sa2;
408f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  vki_sigaction_fromK_t saved_sa;
409f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
410f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  //show_set("STWZ: looking for", set);
411f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
412f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  /* Find out what's pending: Darwin sigpending */
413f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  sr = VG_(do_syscall1)(__NR_sigpending, (UWord)&pending);
414f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  vg_assert(!sr_isError(sr));
415f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
416f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  /* don't try for signals not in 'set' */
417f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  /* pending = pending `intersect` set */
418f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  VG_(sigintersectset)(&pending, (vki_sigset_t*)set);
419f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
420f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  /* don't try for signals not blocked at the moment */
421f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  ir = VG_(sigprocmask)(VKI_SIG_SETMASK, NULL, &blocked);
422f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  vg_assert(ir == 0);
423f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
424f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  /* pending = pending `intersect` blocked */
425f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  VG_(sigintersectset)(&pending, &blocked);
426f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
427f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  /* decide which signal we're going to snarf */
428f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  for (i = 1; i < _VKI_NSIG; i++)
429f76d27a697a7b0bf3b84490baf60623fc96a23afnjn     if (VG_(sigismember)(&pending,i))
430f76d27a697a7b0bf3b84490baf60623fc96a23afnjn        break;
431f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
432f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  if (i == _VKI_NSIG)
433f76d27a697a7b0bf3b84490baf60623fc96a23afnjn     return 0;
434f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
435f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  if (debug)
436f76d27a697a7b0bf3b84490baf60623fc96a23afnjn     VG_(debugLog)(0, "libcsignal",
437f76d27a697a7b0bf3b84490baf60623fc96a23afnjn                      "sigtimedwait_zero: snarfing signal %d\n", i );
438f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
439f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  /* fetch signal i.
440f76d27a697a7b0bf3b84490baf60623fc96a23afnjn     pre: i is blocked and pending
441f76d27a697a7b0bf3b84490baf60623fc96a23afnjn     pre: we are the only thread running
442f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  */
443f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  /* Set up alternative signal handler */
444f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  VG_(sigfillset)(&sa.sa_mask);
445f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  sa.ksa_handler = &sigtimedwait_zero_handler;
446f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  sa.sa_flags    = 0;
447f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  ir = VG_(sigaction)(i, &sa, &saved_sa);
448f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  vg_assert(ir == 0);
449f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
450f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  /* Switch signal masks and wait for the signal.  This should happen
451f76d27a697a7b0bf3b84490baf60623fc96a23afnjn     immediately, since we've already established it is pending and
452f76d27a697a7b0bf3b84490baf60623fc96a23afnjn     blocked. */
453f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  VG_(sigfillset)(&allbutone);
454f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  VG_(sigdelset)(&allbutone, i);
455f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  /* Note: pass the sig mask by value here, not reference (!) */
456f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  vg_assert(_VKI_NSIG_WORDS == 1);
457f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  sr = VG_(do_syscall3)(__NR_sigsuspend_nocancel,
458f76d27a697a7b0bf3b84490baf60623fc96a23afnjn                        (UWord)allbutone.sig[0], 0,0);
459f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  if (debug)
460f76d27a697a7b0bf3b84490baf60623fc96a23afnjn     VG_(debugLog)(0, "libcsignal",
461f76d27a697a7b0bf3b84490baf60623fc96a23afnjn                      "sigtimedwait_zero: sigsuspend got "
462f76d27a697a7b0bf3b84490baf60623fc96a23afnjn                      "res: %s %#lx\n",
463f76d27a697a7b0bf3b84490baf60623fc96a23afnjn                      sr_isError(sr) ? "FAIL" : "SUCCESS",
464f76d27a697a7b0bf3b84490baf60623fc96a23afnjn                      sr_isError(sr) ? sr_Err(sr) : sr_Res(sr));
465f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  vg_assert(sr_isError(sr));
466f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  vg_assert(sr_Err(sr) == VKI_EINTR);
467f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
468f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  /* Restore signal's handler to whatever it was before */
469f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  VG_(convert_sigaction_fromK_to_toK)( &saved_sa, &saved_sa2 );
470f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  ir = VG_(sigaction)(i, &saved_sa2, NULL);
471f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  vg_assert(ir == 0);
472f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
473f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  /* This is bogus - we could get more info from the sighandler. */
474f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  VG_(memset)( info, 0, sizeof(*info) );
475f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  info->si_signo = i;
476f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
477f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  return i;
478f76d27a697a7b0bf3b84490baf60623fc96a23afnjn}
479f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
4801383bdd9919ad3e86eb142c05eae5b156eaa8122sewardj#else
481f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#  error "Unknown OS"
4821383bdd9919ad3e86eb142c05eae5b156eaa8122sewardj#endif
4831383bdd9919ad3e86eb142c05eae5b156eaa8122sewardj
484de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn/*--------------------------------------------------------------------*/
485de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn/*--- end                                                          ---*/
486de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn/*--------------------------------------------------------------------*/
487