(_hurd_self_sigstate): C-t.
[kopensolaris-gnu/glibc.git] / hurd / hurd / signal.h
1 /* Implementing POSIX.1 signals under the Hurd.
2 Copyright (C) 1993, 1994 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
9
10 The GNU C Library 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 GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB.  If
17 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
18 Cambridge, MA 02139, USA.  */
19
20 #ifndef _HURD_SIGNAL_H
21
22 #define _HURD_SIGNAL_H  1
23 #include <features.h>
24 /* Make sure <signal.h> is going to define NSIG.  */
25 #ifndef __USE_GNU
26 #error "Must have `_GNU_SOURCE' feature test macro to use this file"
27 #endif
28
29 #define __need_NULL
30 #include <stddef.h>
31
32 #include <mach/mach_types.h>
33 #include <mach/port.h>
34 #include <mach/message.h>
35 #include <hurd/hurd_types.h>
36 #include <signal.h>
37 #include <errno.h>
38
39 #include <cthreads.h>           /* For `struct mutex'.  */
40 #include <lock-intern.h>
41 #include <hurd/threadvar.h>     /* We cache sigstate in a threadvar.  */
42
43
44 /* Per-thread signal state.  */
45
46 struct hurd_sigstate
47   {
48     /* This mutex locks most of the rest of this structure.  It also acts
49        as a critical section lock for the thread (see below).  */
50     struct mutex lock;
51     int critical_section;
52
53     /* XXX This should perhaps instead be something that identifies
54        cthreads multiplexed on a single kernel thread.  */
55     thread_t thread;
56     struct hurd_sigstate *next; /* Linked-list of thread sigstates.  */
57
58     sigset_t blocked;
59     sigset_t pending;
60     struct sigaction actions[NSIG];
61     struct sigaltstack sigaltstack;
62     int sigcodes[NSIG];         /* Codes for pending signals.  */
63
64     /* If `suspended' is set when this thread gets a signal,
65        the signal thread clears it and then signals `arrived'.  */
66     int suspended;
67 #ifdef noteven
68     struct condition arrived;
69 #endif
70
71     /* Not locked.  Used only by this thread, or by the signal thread with
72        this thread suspended.  */
73     volatile mach_port_t intr_port; /* Port interruptible RPC was sent on.  */
74   };
75
76 /* Linked list of states of all threads whose state has been asked for.  */
77
78 extern struct hurd_sigstate *_hurd_sigstates;
79
80 extern struct mutex _hurd_siglock; /* Locks _hurd_sigstates.  */
81
82 /* Get the sigstate of a given thread, taking its lock.  */
83
84 extern struct hurd_sigstate *_hurd_thread_sigstate (thread_t);
85
86 /* Get the sigstate of the current thread, taking its lock.
87    This uses a per-thread variable to optimize the lookup.  */
88
89 _EXTERN_INLINE struct hurd_sigstate *
90 _hurd_self_sigstate_unlocked (void)
91 {
92   struct hurd_sigstate **location =
93     (void *) __hurd_threadvar_location (_HURD_THREADVAR_SIGSTATE);
94   if (! *location)
95     {
96       *location = _hurd_thread_sigstate (__mach_thread_self ());
97       __mutex_unlock (&(*location)->lock);
98     }
99   return *location;
100 }
101
102 _EXTERN_INLINE struct hurd_sigstate *
103 _hurd_self_sigstate (void)
104 {
105   struct hurd_sigstate **location =
106     (void *) __hurd_threadvar_location (_HURD_THREADVAR_SIGSTATE);
107   if (*location)
108     __mutex_lock (&(*location)->lock);
109   else
110     *location = _hurd_thread_sigstate (__mach_thread_self ());
111   return *location;
112 }
113 \f
114 /* Critical sections.
115
116    A critical section is a section of code which cannot safely be interrupted
117    to run a signal handler; for example, code that holds any lock cannot be
118    interrupted lest the signal handler try to take the same lock and
119    deadlock result.  Before entering a critical section, a thread must make
120    sure it holds its own sigstate lock.  The thread sets the
121    `critical_section' flag (which is not itself locked) to indicate the
122    lock is already held by the same thread.  Subroutines which contain
123    critical sections of their own then test this flag; if it is set, they
124    don't try to acquire the sigstate lock again, to avoid deadlock.  */
125
126 _EXTERN_INLINE void *
127 _hurd_critical_section_lock (void)
128 {
129   struct hurd_sigstate **location =
130     (void *) __hurd_threadvar_location (_HURD_THREADVAR_SIGSTATE);
131   struct hurd_sigstate *ss = *location;
132   if (ss == NULL)
133     /* The thread variable is unset; this must be the first time we've
134        asked for it.  In this case, the critical section flag cannot
135        possible already be set.  Look up our sigstate structure the slow
136        way; this locks the sigstate lock.  */
137     ss = *location = _hurd_thread_sigstate (__mach_thread_self ());
138   else
139     {
140       if (ss->critical_section)
141         /* Some caller higher up has already acquired the critical section
142            lock.  We need do nothing.  The null pointer we return will
143            make _hurd_critical_section_unlock (below) be a no-op.  */
144         return NULL;
145       /* Acquire the sigstate lock to prevent any signal from arriving.  */
146       __mutex_lock (&ss->lock);
147     }
148   /* Set the critical section flag so no later call will try to
149      take the sigstate lock while we already have it locked.  */
150   ss->critical_section = 1;
151   /* Return our sigstate pointer; this will be passed to
152      _hurd_critical_section_unlock to clear the critical section flag. */
153   return ss;
154 }
155
156 _EXTERN_INLINE void
157 _hurd_critical_section_unlock (void *our_lock)
158 {
159   if (our_lock == NULL)
160     /* The critical section lock was held when we began.  Do nothing.  */
161     return;
162   else
163     {
164       /* It was us who acquired the critical section lock.  Clear the
165          critical section flag and unlock the sigstate lock.  */
166       struct hurd_sigstate *ss = our_lock;
167       ss->critical_section = 0;
168       __mutex_unlock (&ss->lock);
169     }
170 }
171
172 /* Convenient macros for simple uses of critical sections.
173    These two must be used as a pair at the same C scoping level.  */
174
175 #define HURD_CRITICAL_BEGIN \
176   { void *__hurd_critical__ = _hurd_critical_section_lock ()
177 #define HURD_CRITICAL_END \
178       _hurd_critical_section_unlock (__hurd_critical__); } while (0)
179 \f
180 /* Thread listening on our message port; also called the "signal thread".  */
181
182 extern thread_t _hurd_msgport_thread;
183
184 /* Our message port.  We hold the receive right and _hurd_msgport_thread
185    listens for messages on it.  We also hold a send right, for convenience.  */
186
187 extern mach_port_t _hurd_msgport;
188
189
190 /* Thread to receive process-global signals.  */
191
192 extern thread_t _hurd_sigthread;
193
194
195 /* Resource limit on core file size.  Enforced by hurdsig.c.  */
196 extern int _hurd_core_limit;
197 \f
198 /* Initialize the signal code, and start the signal thread.  */
199
200 extern void _hurdsig_init (void);
201
202 /* Initialize proc server-assisted fault recovery for the signal thread.  */
203
204 extern void _hurdsig_fault_init (void);
205
206 /* Raise a signal as described by SIGNO and SIGCODE, on the thread whose
207    sigstate SS points to.  If SS is a null pointer, this instead affects
208    the calling thread.  */
209
210 extern void _hurd_raise_signal (struct hurd_sigstate *ss,
211                                 int signo, int sigcode);
212
213 /* Translate a Mach exception into a signal (machine-dependent).  */
214
215 extern void _hurd_exception2signal (int exception, int code, int subcode,
216                                     int *signo, int *sigcode);
217
218
219 /* Make the thread described by SS take the signal described by SIGNO and
220    SIGCODE.  When the signal can be considered delivered, sends a sig_post
221    reply message on REPLY_PORT indicating success.  SS->lock is held on
222    entry, and released before return.  */
223
224 extern void _hurd_internal_post_signal (struct hurd_sigstate *ss,
225                                         int signo, int sigcode,
226                                         mach_port_t reply_port,
227                                         mach_msg_type_name_t reply_port_type);
228
229 /* Set up STATE to handle signal SIGNO by running HANDLER.  FLAGS is the
230    `sa_flags' member from `struct sigaction'.  If the SA_ONSTACK bit is
231    set, *ALTSTACK describes the alternate signal stack to use.  The handler
232    is passed SIGNO, SIGCODE, and the returned `struct sigcontext' (which
233    resides on the stack the handler will use, and which describes the state
234    of the thread encoded in STATE before running the handler).  */
235
236 extern struct sigcontext *_hurd_setup_sighandler (int flags,
237                                                   __sighandler_t handler,
238                                                   struct sigaltstack *altstack,
239                                                   int signo, int sigcode,
240                                                   void *state);
241
242 /* Function run by the signal thread to receive from the signal port.  */
243
244 extern void _hurd_msgport_receive (void);
245
246 /* Return nonzero if STATE indicates a thread that is blocked in a mach_msg
247    system call (machine-dependent).  If returning nonzero, set *PORT to
248    the receive right that the thread is blocked on.  */
249
250 extern int _hurd_thread_state_msging_p (void *state, mach_port_t *port);
251
252 /* Set up STATE with a thread state that, when resumed, is
253    like `longjmp (_hurd_sigthread_fault_env, 1)'.  */
254
255 extern void _hurd_initialize_fault_recovery_state (void *state);
256
257
258 /* Function run for SIGINFO when its action is SIG_DFL and the current
259    process is the session leader.  */
260
261 extern void _hurd_siginfo_handler (int);
262
263
264 /* Perform interruptible RPC CALL on PORT.
265    The call should use 
266    The args in CALL should be constant or local variable refs.
267    They may be evaluated many times, and must not change.
268    PORT must not be deallocated before this RPC is finished.  */
269 #define HURD_EINTR_RPC(port, call)                                            \
270   ({                                                                          \
271     __label__ __do_call;        /* Give this label block scope.  */           \
272     error_t __err;                                                            \
273     struct hurd_sigstate *__ss = _hurd_self_sigstate_unlocked ();             \
274     __do_call:                                                                \
275     /* Tell the signal thread that we are doing an interruptible RPC on       \
276        this port.  If we get a signal and should return EINTR, the signal     \
277        thread will set this variable to MACH_PORT_NULL.  The RPC might        \
278        return EINTR when some other thread gets a signal, in which case we    \
279        want to restart our call.  */                                          \
280     __ss->intr_port = (port);                                                 \
281     /* A signal may arrive here, after intr_port is set, but before the       \
282        mach_msg system call.  The signal handler might do an interruptible    \
283        RPC, and clobber intr_port; then it would not be set properly when     \
284        we actually did send the RPC, and a later signal wouldn't interrupt    \
285        that RPC.  So, _hurd_run_sighandler saves intr_port in the             \
286        sigcontext, and sigreturn restores it.  */                             \
287     switch (__err = (call))                                                   \
288       {                                                                       \
289       case EINTR:               /* RPC went out and was interrupted.  */      \
290       case MACH_SEND_INTERRUPTED: /* RPC didn't get out.  */                  \
291         if (__ss->intr_port == MACH_PORT_NULL)                                \
292           /* Restart the interrupted call.  */                                \
293           goto __do_call;                                                     \
294         /* FALLTHROUGH */                                                     \
295       case MACH_RCV_PORT_DIED:                                                \
296         /* Server didn't respond to interrupt_operation,                      \
297            so the signal thread destroyed the reply port.  */                 \
298         __err = EINTR;                                                        \
299         break;                                                                \
300       default:                  /* Quiet -Wswitch-enum.  */                   \
301       }                                                                       \
302     __ss->intr_port = MACH_PORT_NULL;                                         \
303     __err;                                                                    \
304   })                                                                          \
305
306
307 /* Mask of signals that cannot be caught, blocked, or ignored.  */
308 #define _SIG_CANT_MASK  (__sigmask (SIGSTOP) | __sigmask (SIGKILL))
309
310 /* Do an RPC to a process's message port.
311
312    Each argument is an expression which returns an error code; each
313    expression may be evaluated several times.  FETCH_MSGPORT_EXPR should
314    fetch the appropriate message port and store it in the local variable
315    `msgport'.  FETCH_REFPORT_EXPR should fetch the appropriate message port
316    and store it in the local variable `refport' (if no reference port is
317    needed in the call, then FETCH_REFPORT_EXPR should be simply
318    KERN_SUCCESS or 0).  Both of these are assumed to create user
319    references, which this macro deallocates.  RPC_EXPR should perform the
320    desired RPC operation using `msgport' and `refport'.
321
322    The reason for the complexity is that a process's message port and
323    reference port may change between fetching those ports and completing an
324    RPC using them (usually they change only when a process execs).  The RPC
325    will fail with MACH_SEND_INVALID_DEST if the msgport dies before we can
326    send the RPC request; or with MIG_SERVER_DIED if the msgport was
327    destroyed after we sent the RPC request but before it was serviced.  In
328    either of these cases, we retry the entire operation, discarding the old
329    message and reference ports and fetch them anew.  */
330
331 #define HURD_MSGPORT_RPC(fetch_msgport_expr, fetch_refport_expr, rpc_expr)   \
332 ({                                                                            \
333     error_t __err;                                                            \
334     mach_port_t msgport, refport = MACH_PORT_NULL;                            \
335     do                                                                        \
336       {                                                                       \
337         /* Get the message port.  */                                          \
338         if (__err = (fetch_msgport_expr))                                     \
339           break;                                                              \
340         /* Get the reference port.  */                                        \
341         if (__err = (fetch_refport_expr))                                     \
342           {                                                                   \
343             /* Couldn't get it; deallocate MSGPORT and fail.  */              \
344             __mach_port_deallocate (__mach_task_self (), msgport);            \
345             break;                                                            \
346           }                                                                   \
347         __err = (rpc_expr);                                                   \
348         __mach_port_deallocate (__mach_task_self (), msgport);                \
349         if (refport != MACH_PORT_NULL)                                        \
350           __mach_port_deallocate (__mach_task_self (), refport);              \
351       } while (__err == MACH_SEND_INVALID_DEST ||                             \
352                __err == MIG_SERVER_DIED);                                     \
353     __err;                                                                    \
354 })
355 \f
356 /* Some other parts of the library need to preempt signals, to detect
357    errors that should not result in a POSIX signal.  For example, when
358    some mapped region of memory is used, an extraneous SIGSEGV might be
359    generated when the mapping server returns an error for a page fault.  */
360
361 struct hurd_signal_preempt
362   {
363     /* Function to examine a thread receiving a given signal.  The handler
364        is called even for blocked signals.  This function is run in the
365        signal thread, with THREAD's sigstate locked; it should be as simple
366        and robust as possible.  THREAD is the thread which is about to
367        receive the signal.  SIGNO and SIGCODE would be passed to the normal
368        handler.
369
370        If the return value is SIG_DFL, normal signal processing continues.
371        If it is SIG_IGN, the signal is ignored.
372        Any other value is used in place of the normal handler.  */
373     sighandler_t (*handler) (thread_t thread, int signo, int sigcode);
374     int first, last;            /* Range of sigcodes this handler wants.  */
375     struct hurd_signal_preempt *next; /* Next handler on the chain. */
376   };
377
378 extern struct hurd_signal_preempt *_hurd_signal_preempt[NSIG];
379 extern struct mutex _hurd_signal_preempt_lock;
380
381
382 #endif  /* hurd/signal.h */