1999-11-18 Roland McGrath <roland@baalperazim.frob.com>
[platform/upstream/glibc.git] / hurd / hurdsig.c
1 /* Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Library General Public License as
6    published by the Free Software Foundation; either version 2 of the
7    License, or (at your option) any later version.
8
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    Library General Public License for more details.
13
14    You should have received a copy of the GNU Library General Public
15    License along with the GNU C Library; see the file COPYING.LIB.  If not,
16    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17    Boston, MA 02111-1307, USA.  */
18
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <hurd.h>
22 #include <hurd/signal.h>
23 #include <cthreads.h>           /* For `struct mutex'.  */
24 #include <string.h>
25 #include <hurd/id.h>
26 #include "hurdfault.h"
27 #include "hurdmalloc.h"         /* XXX */
28
29 const char *_hurdsig_getenv (const char *);
30
31 struct mutex _hurd_siglock;
32 int _hurd_stopped;
33
34 /* Port that receives signals and other miscellaneous messages.  */
35 mach_port_t _hurd_msgport;
36
37 /* Thread listening on it.  */
38 thread_t _hurd_msgport_thread;
39
40 /* Thread which receives task-global signals.  */
41 thread_t _hurd_sigthread;
42
43 /* These are set up by _hurdsig_init.  */
44 unsigned long int __hurd_sigthread_stack_base;
45 unsigned long int __hurd_sigthread_stack_end;
46 unsigned long int *__hurd_sigthread_variables;
47
48 /* Linked-list of per-thread signal state.  */
49 struct hurd_sigstate *_hurd_sigstates;
50
51 /* Timeout for RPC's after interrupt_operation. */
52 mach_msg_timeout_t _hurd_interrupted_rpc_timeout = 3000;
53 \f
54 static void
55 default_sigaction (struct sigaction actions[NSIG])
56 {
57   int signo;
58
59   __sigemptyset (&actions[0].sa_mask);
60   actions[0].sa_flags = SA_RESTART;
61   actions[0].sa_handler = SIG_DFL;
62
63   for (signo = 1; signo < NSIG; ++signo)
64     actions[signo] = actions[0];
65 }
66
67 struct hurd_sigstate *
68 _hurd_thread_sigstate (thread_t thread)
69 {
70   struct hurd_sigstate *ss;
71   __mutex_lock (&_hurd_siglock);
72   for (ss = _hurd_sigstates; ss != NULL; ss = ss->next)
73     if (ss->thread == thread)
74        break;
75   if (ss == NULL)
76     {
77       ss = malloc (sizeof (*ss));
78       if (ss == NULL)
79         __libc_fatal ("hurd: Can't allocate thread sigstate\n");
80       ss->thread = thread;
81       __spin_lock_init (&ss->lock);
82
83       /* Initialize default state.  */
84       __sigemptyset (&ss->blocked);
85       __sigemptyset (&ss->pending);
86       memset (&ss->sigaltstack, 0, sizeof (ss->sigaltstack));
87       ss->preemptors = NULL;
88       ss->suspended = 0;
89       ss->intr_port = MACH_PORT_NULL;
90       ss->context = NULL;
91
92       /* Initialize the sigaction vector from the default signal receiving
93          thread's state, and its from the system defaults.  */
94       if (thread == _hurd_sigthread)
95         default_sigaction (ss->actions);
96       else
97         {
98           struct hurd_sigstate *s;
99           for (s = _hurd_sigstates; s != NULL; s = s->next)
100             if (s->thread == _hurd_sigthread)
101               break;
102           if (s)
103             {
104               __spin_lock (&s->lock);
105               memcpy (ss->actions, s->actions, sizeof (s->actions));
106               __spin_unlock (&s->lock);
107             }
108           else
109             default_sigaction (ss->actions);
110         }
111
112       ss->next = _hurd_sigstates;
113       _hurd_sigstates = ss;
114     }
115   __mutex_unlock (&_hurd_siglock);
116   return ss;
117 }
118 \f
119 /* Signal delivery itself is on this page.  */
120
121 #include <hurd/fd.h>
122 #include <hurd/crash.h>
123 #include <hurd/paths.h>
124 #include <setjmp.h>
125 #include <fcntl.h>
126 #include <sys/wait.h>
127 #include "thread_state.h"
128 #include <hurd/msg_server.h>
129 #include <hurd/msg_reply.h>     /* For __msg_sig_post_reply.  */
130 #include <hurd/interrupt.h>
131 #include <assert.h>
132 #include <unistd.h>
133
134 int _hurd_core_limit;   /* XXX */
135
136 /* Call the crash dump server to mummify us before we die.
137    Returns nonzero if a core file was written.  */
138 static int
139 write_corefile (int signo, const struct hurd_signal_detail *detail)
140 {
141   error_t err;
142   mach_port_t coreserver;
143   file_t file, coredir;
144   const char *name;
145
146   /* XXX RLIMIT_CORE:
147      When we have a protocol to make the server return an error
148      for RLIMIT_FSIZE, then tell the corefile fs server the RLIMIT_CORE
149      value in place of the RLIMIT_FSIZE value.  */
150
151   /* First get a port to the core dumping server.  */
152   coreserver = MACH_PORT_NULL;
153   name = _hurdsig_getenv ("CRASHSERVER");
154   if (name != NULL)
155     coreserver = __file_name_lookup (name, 0, 0);
156   if (coreserver == MACH_PORT_NULL)
157     coreserver = __file_name_lookup (_SERVERS_CRASH, 0, 0);
158   if (coreserver == MACH_PORT_NULL)
159     return 0;
160
161   /* Get a port to the directory where the new core file will reside.  */
162   file = MACH_PORT_NULL;
163   name = _hurdsig_getenv ("COREFILE");
164   if (name == NULL)
165     name = "core";
166   coredir = __file_name_split (name, (char **) &name);
167   if (coredir != MACH_PORT_NULL)
168     /* Create the new file, but don't link it into the directory yet.  */
169     __dir_mkfile (coredir, O_WRONLY|O_CREAT,
170                   0600 & ~_hurd_umask, /* XXX ? */
171                   &file);
172
173   /* Call the core dumping server to write the core file.  */
174   err = __crash_dump_task (coreserver,
175                            __mach_task_self (),
176                            file,
177                            signo, detail->code, detail->error,
178                            detail->exc, detail->exc_code, detail->exc_subcode,
179                            _hurd_ports[INIT_PORT_CTTYID].port,
180                            MACH_MSG_TYPE_COPY_SEND);
181   __mach_port_deallocate (__mach_task_self (), coreserver);
182
183   if (! err && file != MACH_PORT_NULL)
184     /* The core dump into FILE succeeded, so now link it into the
185        directory.  */
186     err = __dir_link (file, coredir, name, 1);
187   __mach_port_deallocate (__mach_task_self (), file);
188   __mach_port_deallocate (__mach_task_self (), coredir);
189   return !err && file != MACH_PORT_NULL;
190 }
191
192
193 /* The lowest-numbered thread state flavor value is 1,
194    so we use bit 0 in machine_thread_all_state.set to
195    record whether we have done thread_abort.  */
196 #define THREAD_ABORTED 1
197
198 /* SS->thread is suspended.  Abort the thread and get its basic state.  */
199 static void
200 abort_thread (struct hurd_sigstate *ss, struct machine_thread_all_state *state,
201               void (*reply) (void))
202 {
203   if (!(state->set & THREAD_ABORTED))
204     {
205       error_t err = __thread_abort (ss->thread);
206       assert_perror (err);
207       /* Clear all thread state flavor set bits, because thread_abort may
208          have changed the state.  */
209       state->set = THREAD_ABORTED;
210     }
211
212   if (reply)
213     (*reply) ();
214
215   machine_get_basic_state (ss->thread, state);
216 }
217
218 /* Find the location of the MiG reply port cell in use by the thread whose
219    state is described by THREAD_STATE.  If SIGTHREAD is nonzero, make sure
220    that this location can be set without faulting, or else return NULL.  */
221
222 static mach_port_t *
223 interrupted_reply_port_location (struct machine_thread_all_state *thread_state,
224                                  int sigthread)
225 {
226   mach_port_t *portloc = (mach_port_t *) __hurd_threadvar_location_from_sp
227     (_HURD_THREADVAR_MIG_REPLY, (void *) thread_state->basic.SP);
228
229   if (sigthread && _hurdsig_catch_memory_fault (portloc))
230     /* Faulted trying to read the stack.  */
231     return NULL;
232
233   /* Fault now if this pointer is bogus.  */
234   *(volatile mach_port_t *) portloc = *portloc;
235
236   if (sigthread)
237     _hurdsig_end_catch_fault ();
238
239   return portloc;
240 }
241 \f
242 #include <hurd/sigpreempt.h>
243 #include "intr-msg.h"
244
245 /* Timeout on interrupt_operation calls.  */
246 mach_msg_timeout_t _hurdsig_interrupt_timeout = 1000;
247
248 /* SS->thread is suspended.
249
250    Abort any interruptible RPC operation the thread is doing.
251
252    This uses only the constant member SS->thread and the unlocked, atomically
253    set member SS->intr_port, so no locking is needed.
254
255    If successfully sent an interrupt_operation and therefore the thread should
256    wait for its pending RPC to return (possibly EINTR) before taking the
257    incoming signal, returns the reply port to be received on.  Otherwise
258    returns MACH_PORT_NULL.
259
260    SIGNO is used to find the applicable SA_RESTART bit.  If SIGNO is zero,
261    the RPC fails with EINTR instead of restarting (thread_cancel).
262
263    *STATE_CHANGE is set nonzero if STATE->basic was modified and should
264    be applied back to the thread if it might ever run again, else zero.  */
265
266 mach_port_t
267 _hurdsig_abort_rpcs (struct hurd_sigstate *ss, int signo, int sigthread,
268                      struct machine_thread_all_state *state, int *state_change,
269                      void (*reply) (void))
270 {
271   extern const void _hurd_intr_rpc_msg_in_trap;
272   mach_port_t rcv_port = MACH_PORT_NULL;
273   mach_port_t intr_port;
274
275   *state_change = 0;
276
277   intr_port = ss->intr_port;
278   if (intr_port == MACH_PORT_NULL)
279     /* No interruption needs done.  */
280     return MACH_PORT_NULL;
281
282   /* Abort the thread's kernel context, so any pending message send or
283      receive completes immediately or aborts.  */
284   abort_thread (ss, state, reply);
285
286   if (state->basic.PC < (natural_t) &_hurd_intr_rpc_msg_in_trap)
287     {
288       /* The thread is about to do the RPC, but hasn't yet entered
289          mach_msg.  Mutate the thread's state so it knows not to try
290          the RPC.  */
291       INTR_MSG_BACK_OUT (&state->basic);
292       MACHINE_THREAD_STATE_SET_PC (&state->basic,
293                                    &_hurd_intr_rpc_msg_in_trap);
294       state->basic.SYSRETURN = MACH_SEND_INTERRUPTED;
295       *state_change = 1;
296     }
297   else if (state->basic.PC == (natural_t) &_hurd_intr_rpc_msg_in_trap &&
298            /* The thread was blocked in the system call.  After thread_abort,
299               the return value register indicates what state the RPC was in
300               when interrupted.  */
301            state->basic.SYSRETURN == MACH_RCV_INTERRUPTED)
302       {
303         /* The RPC request message was sent and the thread was waiting for
304            the reply message; now the message receive has been aborted, so
305            the mach_msg call will return MACH_RCV_INTERRUPTED.  We must tell
306            the server to interrupt the pending operation.  The thread must
307            wait for the reply message before running the signal handler (to
308            guarantee that the operation has finished being interrupted), so
309            our nonzero return tells the trampoline code to finish the message
310            receive operation before running the handler.  */
311
312         mach_port_t *reply = interrupted_reply_port_location (state,
313                                                               sigthread);
314         error_t err = __interrupt_operation (intr_port, _hurdsig_interrupt_timeout);
315
316         if (err)
317           {
318             if (reply)
319               {
320                 /* The interrupt didn't work.
321                    Destroy the receive right the thread is blocked on.  */
322                 __mach_port_destroy (__mach_task_self (), *reply);
323                 *reply = MACH_PORT_NULL;
324               }
325
326             /* The system call return value register now contains
327                MACH_RCV_INTERRUPTED; when mach_msg resumes, it will retry the
328                call.  Since we have just destroyed the receive right, the
329                retry will fail with MACH_RCV_INVALID_NAME.  Instead, just
330                change the return value here to EINTR so mach_msg will not
331                retry and the EINTR error code will propagate up.  */
332             state->basic.SYSRETURN = EINTR;
333             *state_change = 1;
334           }
335         else if (reply)
336           rcv_port = *reply;
337
338         /* All threads whose RPCs were interrupted by the interrupt_operation
339            call above will retry their RPCs unless we clear SS->intr_port.
340            So we clear it for the thread taking a signal when SA_RESTART is
341            clear, so that its call returns EINTR.  */
342         if (! signo || !(ss->actions[signo].sa_flags & SA_RESTART))
343           ss->intr_port = MACH_PORT_NULL;
344       }
345
346   return rcv_port;
347 }
348
349
350 /* Abort the RPCs being run by all threads but this one;
351    all other threads should be suspended.  If LIVE is nonzero, those
352    threads may run again, so they should be adjusted as necessary to be
353    happy when resumed.  STATE is clobbered as a scratch area; its initial
354    contents are ignored, and its contents on return are not useful.  */
355
356 static void
357 abort_all_rpcs (int signo, struct machine_thread_all_state *state, int live)
358 {
359   /* We can just loop over the sigstates.  Any thread doing something
360      interruptible must have one.  We needn't bother locking because all
361      other threads are stopped.  */
362
363   struct hurd_sigstate *ss;
364   size_t nthreads;
365   mach_port_t *reply_ports;
366
367   /* First loop over the sigstates to count them.
368      We need to know how big a vector we will need for REPLY_PORTS.  */
369   nthreads = 0;
370   for (ss = _hurd_sigstates; ss != NULL; ss = ss->next)
371     ++nthreads;
372
373   reply_ports = alloca (nthreads * sizeof *reply_ports);
374
375   nthreads = 0;
376   for (ss = _hurd_sigstates; ss != NULL; ss = ss->next, ++nthreads)
377     if (ss->thread == _hurd_msgport_thread)
378       reply_ports[nthreads] = MACH_PORT_NULL;
379     else
380       {
381         int state_changed;
382         state->set = 0;         /* Reset scratch area.  */
383
384         /* Abort any operation in progress with interrupt_operation.
385            Record the reply port the thread is waiting on.
386            We will wait for all the replies below.  */
387         reply_ports[nthreads] = _hurdsig_abort_rpcs (ss, signo, 1,
388                                                      state, &state_changed,
389                                                      NULL);
390         if (live)
391           {
392             if (reply_ports[nthreads] != MACH_PORT_NULL)
393               {
394                 /* We will wait for the reply to this RPC below, so the
395                    thread must issue a new RPC rather than waiting for the
396                    reply to the one it sent.  */
397                 state->basic.SYSRETURN = EINTR;
398                 state_changed = 1;
399               }
400             if (state_changed)
401               /* Aborting the RPC needed to change this thread's state,
402                  and it might ever run again.  So write back its state.  */
403               __thread_set_state (ss->thread, MACHINE_THREAD_STATE_FLAVOR,
404                                   (natural_t *) &state->basic,
405                                   MACHINE_THREAD_STATE_COUNT);
406           }
407       }
408
409   /* Wait for replies from all the successfully interrupted RPCs.  */
410   while (nthreads-- > 0)
411     if (reply_ports[nthreads] != MACH_PORT_NULL)
412       {
413         error_t err;
414         mach_msg_header_t head;
415         err = __mach_msg (&head, MACH_RCV_MSG|MACH_RCV_TIMEOUT, 0, sizeof head,
416                           reply_ports[nthreads],
417                           _hurd_interrupted_rpc_timeout, MACH_PORT_NULL);
418         switch (err)
419           {
420           case MACH_RCV_TIMED_OUT:
421           case MACH_RCV_TOO_LARGE:
422             break;
423
424           default:
425             assert_perror (err);
426           }
427       }
428 }
429
430 struct hurd_signal_preemptor *_hurdsig_preemptors = 0;
431 sigset_t _hurdsig_preempted_set;
432
433 /* XXX temporary to deal with spelling fix */
434 weak_alias (_hurdsig_preemptors, _hurdsig_preempters)
435
436 /* Mask of stop signals.  */
437 #define STOPSIGS (sigmask (SIGTTIN) | sigmask (SIGTTOU) | \
438                   sigmask (SIGSTOP) | sigmask (SIGTSTP))
439
440 /* Deliver a signal.  SS is not locked.  */
441 void
442 _hurd_internal_post_signal (struct hurd_sigstate *ss,
443                             int signo, struct hurd_signal_detail *detail,
444                             mach_port_t reply_port,
445                             mach_msg_type_name_t reply_port_type,
446                             int untraced)
447 {
448   error_t err;
449   struct machine_thread_all_state thread_state;
450   enum { stop, ignore, core, term, handle } act;
451   sighandler_t handler;
452   sigset_t pending;
453   int ss_suspended;
454
455   /* Reply to this sig_post message.  */
456   __typeof (__msg_sig_post_reply) *reply_rpc
457     = (untraced ? __msg_sig_post_untraced_reply : __msg_sig_post_reply);
458   void reply (void)
459     {
460       error_t err;
461       if (reply_port == MACH_PORT_NULL)
462         return;
463       err = (*reply_rpc) (reply_port, reply_port_type, 0);
464       reply_port = MACH_PORT_NULL;
465       if (err != MACH_SEND_INVALID_DEST) /* Ignore dead reply port.  */
466         assert_perror (err);
467     }
468
469   /* Mark the signal as pending.  */
470   void mark_pending (void)
471     {
472       __sigaddset (&ss->pending, signo);
473       /* Save the details to be given to the handler when SIGNO is
474          unblocked.  */
475       ss->pending_data[signo] = *detail;
476     }
477
478   /* Suspend the process with SIGNO.  */
479   void suspend (void)
480     {
481       /* Stop all other threads and mark ourselves stopped.  */
482       __USEPORT (PROC,
483                  ({
484                    /* Hold the siglock while stopping other threads to be
485                       sure it is not held by another thread afterwards.  */
486                    __mutex_lock (&_hurd_siglock);
487                    __proc_dostop (port, _hurd_msgport_thread);
488                    __mutex_unlock (&_hurd_siglock);
489                    abort_all_rpcs (signo, &thread_state, 1);
490                    reply ();
491                    __proc_mark_stop (port, signo, detail->code);
492                  }));
493       _hurd_stopped = 1;
494     }
495   /* Resume the process after a suspension.  */
496   void resume (void)
497     {
498       /* Resume the process from being stopped.  */
499       thread_t *threads;
500       mach_msg_type_number_t nthreads, i;
501       error_t err;
502
503       if (! _hurd_stopped)
504         return;
505
506       /* Tell the proc server we are continuing.  */
507       __USEPORT (PROC, __proc_mark_cont (port));
508       /* Fetch ports to all our threads and resume them.  */
509       err = __task_threads (__mach_task_self (), &threads, &nthreads);
510       assert_perror (err);
511       for (i = 0; i < nthreads; ++i)
512         {
513           if (threads[i] != _hurd_msgport_thread &&
514               (act != handle || threads[i] != ss->thread))
515             {
516               err = __thread_resume (threads[i]);
517               assert_perror (err);
518             }
519           err = __mach_port_deallocate (__mach_task_self (),
520                                         threads[i]);
521           assert_perror (err);
522         }
523       __vm_deallocate (__mach_task_self (),
524                        (vm_address_t) threads,
525                        nthreads * sizeof *threads);
526       _hurd_stopped = 0;
527       if (act == handle)
528         /* The thread that will run the handler is already suspended.  */
529         ss_suspended = 1;
530     }
531
532   if (signo == 0)
533     {
534       if (untraced)
535         /* This is PTRACE_CONTINUE.  */
536         resume ();
537
538       /* This call is just to check for pending signals.  */
539       __spin_lock (&ss->lock);
540       goto check_pending_signals;
541     }
542
543  post_signal:
544
545   thread_state.set = 0;         /* We know nothing.  */
546
547   __spin_lock (&ss->lock);
548
549   /* Check for a preempted signal.  Preempted signals can arrive during
550      critical sections.  */
551   {
552     inline sighandler_t try_preemptor (struct hurd_signal_preemptor *pe)
553       {                         /* PE cannot be null.  */
554         do
555           {
556             if (HURD_PREEMPT_SIGNAL_P (pe, signo, detail->code))
557               {
558                 if (pe->preemptor)
559                   {
560                     sighandler_t handler = (*pe->preemptor) (pe, ss,
561                                                              &signo, detail);
562                     if (handler != SIG_ERR)
563                       return handler;
564                   }
565                 else
566                   return pe->handler;
567               }
568             pe = pe->next;
569           } while (pe != 0);
570         return SIG_ERR;
571       }
572
573     handler = ss->preemptors ? try_preemptor (ss->preemptors) : SIG_ERR;
574
575     /* If no thread-specific preemptor, check for a global one.  */
576     if (handler == SIG_ERR && (__sigmask (signo) & _hurdsig_preempted_set))
577       {
578         __mutex_lock (&_hurd_siglock);
579         handler = try_preemptor (_hurdsig_preemptors);
580         __mutex_unlock (&_hurd_siglock);
581       }
582   }
583
584   ss_suspended = 0;
585
586   if (handler == SIG_IGN)
587     /* Ignore the signal altogether.  */
588     act = ignore;
589   else if (handler != SIG_ERR)
590     /* Run the preemption-provided handler.  */
591     act = handle;
592   else
593     {
594       /* No preemption.  Do normal handling.  */
595
596       if (!untraced && __sigismember (&_hurdsig_traced, signo))
597         {
598           /* We are being traced.  Stop to tell the debugger of the signal.  */
599           if (_hurd_stopped)
600             /* Already stopped.  Mark the signal as pending;
601                when resumed, we will notice it and stop again.  */
602             mark_pending ();
603           else
604             suspend ();
605           __spin_unlock (&ss->lock);
606           reply ();
607           return;
608         }
609
610       handler = ss->actions[signo].sa_handler;
611
612       if (handler == SIG_DFL)
613         /* Figure out the default action for this signal.  */
614         switch (signo)
615           {
616           case 0:
617             /* A sig_post msg with SIGNO==0 is sent to
618                tell us to check for pending signals.  */
619             act = ignore;
620             break;
621
622           case SIGTTIN:
623           case SIGTTOU:
624           case SIGSTOP:
625           case SIGTSTP:
626             act = stop;
627             break;
628
629           case SIGCONT:
630           case SIGIO:
631           case SIGURG:
632           case SIGCHLD:
633           case SIGWINCH:
634             act = ignore;
635             break;
636
637           case SIGQUIT:
638           case SIGILL:
639           case SIGTRAP:
640           case SIGIOT:
641           case SIGEMT:
642           case SIGFPE:
643           case SIGBUS:
644           case SIGSEGV:
645           case SIGSYS:
646             act = core;
647             break;
648
649           case SIGINFO:
650             if (_hurd_pgrp == _hurd_pid)
651               {
652                 /* We are the process group leader.  Since there is no
653                    user-specified handler for SIGINFO, we use a default one
654                    which prints something interesting.  We use the normal
655                    handler mechanism instead of just doing it here to avoid
656                    the signal thread faulting or blocking in this
657                    potentially hairy operation.  */
658                 act = handle;
659                 handler = _hurd_siginfo_handler;
660               }
661             else
662               act = ignore;
663             break;
664
665           default:
666             act = term;
667             break;
668           }
669       else if (handler == SIG_IGN)
670         act = ignore;
671       else
672         act = handle;
673
674       if (__sigmask (signo) & STOPSIGS)
675         /* Stop signals clear a pending SIGCONT even if they
676            are handled or ignored (but not if preempted).  */
677         ss->pending &= ~sigmask (SIGCONT);
678       else
679         {
680           if (signo == SIGCONT)
681             /* Even if handled or ignored (but not preempted), SIGCONT clears
682                stop signals and resumes the process.  */
683             ss->pending &= ~STOPSIGS;
684
685           if (_hurd_stopped && act != stop && (untraced || signo == SIGCONT))
686             resume ();
687         }
688     }
689
690   if (_hurd_orphaned && act == stop &&
691       (__sigmask (signo) & (__sigmask (SIGTTIN) | __sigmask (SIGTTOU) |
692                             __sigmask (SIGTSTP))))
693     {
694       /* If we would ordinarily stop for a job control signal, but we are
695          orphaned so noone would ever notice and continue us again, we just
696          quietly die, alone and in the dark.  */
697       detail->code = signo;
698       signo = SIGKILL;
699       act = term;
700     }
701
702   /* Handle receipt of a blocked signal, or any signal while stopped.  */
703   if (act != ignore &&          /* Signals ignored now are forgotten now.  */
704       __sigismember (&ss->blocked, signo) ||
705       (signo != SIGKILL && _hurd_stopped))
706     {
707       mark_pending ();
708       act = ignore;
709     }
710
711   /* Perform the chosen action for the signal.  */
712   switch (act)
713     {
714     case stop:
715       if (_hurd_stopped)
716         {
717           /* We are already stopped, but receiving an untraced stop
718              signal.  Instead of resuming and suspending again, just
719              notify the proc server of the new stop signal.  */
720           error_t err = __USEPORT (PROC, __proc_mark_stop
721                                    (port, signo, detail->code));
722           assert_perror (err);
723         }
724       else
725         /* Suspend the process.  */
726         suspend ();
727       break;
728
729     case ignore:
730       /* Nobody cares about this signal.  If there was a call to resume
731          above in SIGCONT processing and we've left a thread suspended,
732          now's the time to set it going. */
733       if (ss_suspended)
734         {
735           err = __thread_resume (ss->thread);
736           assert_perror (err);
737           ss_suspended = 0;
738         }
739       break;
740
741     sigbomb:
742       /* We got a fault setting up the stack frame for the handler.
743          Nothing to do but die; BSD gets SIGILL in this case.  */
744       detail->code = signo;     /* XXX ? */
745       signo = SIGILL;
746       act = core;
747       /* FALLTHROUGH */
748
749     case term:                  /* Time to die.  */
750     case core:                  /* And leave a rotting corpse.  */
751       /* Have the proc server stop all other threads in our task.  */
752       err = __USEPORT (PROC, __proc_dostop (port, _hurd_msgport_thread));
753       assert_perror (err);
754       /* No more user instructions will be executed.
755          The signal can now be considered delivered.  */
756       reply ();
757       /* Abort all server operations now in progress.  */
758       abort_all_rpcs (signo, &thread_state, 0);
759
760       {
761         int status = W_EXITCODE (0, signo);
762         /* Do a core dump if desired.  Only set the wait status bit saying we
763            in fact dumped core if the operation was actually successful.  */
764         if (act == core && write_corefile (signo, detail))
765           status |= WCOREFLAG;
766         /* Tell proc how we died and then stick the saber in the gut.  */
767         _hurd_exit (status);
768         /* NOTREACHED */
769       }
770
771     case handle:
772       /* Call a handler for this signal.  */
773       {
774         struct sigcontext *scp, ocontext;
775         int wait_for_reply, state_changed;
776
777         /* Stop the thread and abort its pending RPC operations.  */
778         if (! ss_suspended)
779           {
780             err = __thread_suspend (ss->thread);
781             assert_perror (err);
782           }
783
784         /* Abort the thread's kernel context, so any pending message send
785            or receive completes immediately or aborts.  If an interruptible
786            RPC is in progress, abort_rpcs will do this.  But we must always
787            do it before fetching the thread's state, because
788            thread_get_state is never kosher before thread_abort.  */
789         abort_thread (ss, &thread_state, NULL);
790
791         if (ss->context)
792           {
793             /* We have a previous sigcontext that sigreturn was about
794                to restore when another signal arrived.  */
795
796             mach_port_t *loc;
797
798             if (_hurdsig_catch_memory_fault (ss->context))
799               {
800                 /* We faulted reading the thread's stack.  Forget that
801                    context and pretend it wasn't there.  It almost
802                    certainly crash if this handler returns, but that's it's
803                    problem.  */
804                 ss->context = NULL;
805               }
806             else
807               {
808                 /* Copy the context from the thread's stack before
809                    we start diddling the stack to set up the handler.  */
810                 ocontext = *ss->context;
811                 ss->context = &ocontext;
812               }
813             _hurdsig_end_catch_fault ();
814
815             if (! machine_get_basic_state (ss->thread, &thread_state))
816               goto sigbomb;
817             loc = interrupted_reply_port_location (&thread_state, 1);
818             if (loc && *loc != MACH_PORT_NULL)
819               /* This is the reply port for the context which called
820                  sigreturn.  Since we are abandoning that context entirely
821                  and restoring SS->context instead, destroy this port.  */
822               __mach_port_destroy (__mach_task_self (), *loc);
823
824             /* The thread was in sigreturn, not in any interruptible RPC.  */
825             wait_for_reply = 0;
826
827             assert (! __spin_lock_locked (&ss->critical_section_lock));
828           }
829         else
830           {
831             int crit = __spin_lock_locked (&ss->critical_section_lock);
832
833             wait_for_reply
834               = (_hurdsig_abort_rpcs (ss,
835                                       /* In a critical section, any RPC
836                                          should be cancelled instead of
837                                          restarted, regardless of
838                                          SA_RESTART, so the entire
839                                          "atomic" operation can be aborted
840                                          as a unit.  */
841                                       crit ? 0 : signo, 1,
842                                       &thread_state, &state_changed,
843                                       &reply)
844                  != MACH_PORT_NULL);
845
846             if (crit)
847               {
848                 /* The thread is in a critical section.  Mark the signal as
849                    pending.  When it finishes the critical section, it will
850                    check for pending signals.  */
851                 mark_pending ();
852                 if (state_changed)
853                   /* Some cases of interrupting an RPC must change the
854                      thread state to back out the call.  Normally this
855                      change is rolled into the warping to the handler and
856                      sigreturn, but we are not running the handler now
857                      because the thread is in a critical section.  Instead,
858                      mutate the thread right away for the RPC interruption
859                      and resume it; the RPC will return early so the
860                      critical section can end soon.  */
861                   __thread_set_state (ss->thread, MACHINE_THREAD_STATE_FLAVOR,
862                                       (natural_t *) &thread_state.basic,
863                                       MACHINE_THREAD_STATE_COUNT);
864                 /* */
865                 ss->intr_port = MACH_PORT_NULL;
866                 __thread_resume (ss->thread);
867                 break;
868               }
869           }
870
871         /* Call the machine-dependent function to set the thread up
872            to run the signal handler, and preserve its old context.  */
873         scp = _hurd_setup_sighandler (ss, handler, signo, detail,
874                                       wait_for_reply, &thread_state);
875         if (scp == NULL)
876           goto sigbomb;
877
878         /* Set the machine-independent parts of the signal context.  */
879
880         {
881           /* Fetch the thread variable for the MiG reply port,
882              and set it to MACH_PORT_NULL.  */
883           mach_port_t *loc = interrupted_reply_port_location (&thread_state,
884                                                               1);
885           if (loc)
886             {
887               scp->sc_reply_port = *loc;
888               *loc = MACH_PORT_NULL;
889             }
890           else
891             scp->sc_reply_port = MACH_PORT_NULL;
892
893           /* Save the intr_port in use by the interrupted code,
894              and clear the cell before running the trampoline.  */
895           scp->sc_intr_port = ss->intr_port;
896           ss->intr_port = MACH_PORT_NULL;
897
898           if (ss->context)
899             {
900               /* After the handler runs we will restore to the state in
901                  SS->context, not the state of the thread now.  So restore
902                  that context's reply port and intr port.  */
903
904               scp->sc_reply_port = ss->context->sc_reply_port;
905               scp->sc_intr_port = ss->context->sc_intr_port;
906
907               ss->context = NULL;
908             }
909         }
910
911         /* Backdoor extra argument to signal handler.  */
912         scp->sc_error = detail->error;
913
914         /* Block SIGNO and requested signals while running the handler.  */
915         scp->sc_mask = ss->blocked;
916         ss->blocked |= __sigmask (signo) | ss->actions[signo].sa_mask;
917
918         /* Start the thread running the handler (or possibly waiting for an
919            RPC reply before running the handler).  */
920         err = __thread_set_state (ss->thread, MACHINE_THREAD_STATE_FLAVOR,
921                                   (natural_t *) &thread_state.basic,
922                                   MACHINE_THREAD_STATE_COUNT);
923         assert_perror (err);
924         err = __thread_resume (ss->thread);
925         assert_perror (err);
926         thread_state.set = 0;   /* Everything we know is now wrong.  */
927         break;
928       }
929     }
930
931   /* The signal has either been ignored or is now being handled.  We can
932      consider it delivered and reply to the killer.  */
933   reply ();
934
935   /* We get here unless the signal was fatal.  We still hold SS->lock.
936      Check for pending signals, and loop to post them.  */
937   {
938     /* Return nonzero if SS has any signals pending we should worry about.
939        We don't worry about any pending signals if we are stopped, nor if
940        SS is in a critical section.  We are guaranteed to get a sig_post
941        message before any of them become deliverable: either the SIGCONT
942        signal, or a sig_post with SIGNO==0 as an explicit poll when the
943        thread finishes its critical section.  */
944     inline int signals_pending (void)
945       {
946         if (_hurd_stopped || __spin_lock_locked (&ss->critical_section_lock))
947           return 0;
948         return pending = ss->pending & ~ss->blocked;
949       }
950
951   check_pending_signals:
952     untraced = 0;
953
954     if (signals_pending ())
955       {
956         for (signo = 1; signo < NSIG; ++signo)
957           if (__sigismember (&pending, signo))
958             {
959             deliver_pending:
960               __sigdelset (&ss->pending, signo);
961               *detail = ss->pending_data[signo];
962               __spin_unlock (&ss->lock);
963               goto post_signal;
964             }
965       }
966
967     /* No pending signals left undelivered for this thread.
968        If we were sent signal 0, we need to check for pending
969        signals for all threads.  */
970     if (signo == 0)
971       {
972         __spin_unlock (&ss->lock);
973         __mutex_lock (&_hurd_siglock);
974         for (ss = _hurd_sigstates; ss != NULL; ss = ss->next)
975           {
976             __spin_lock (&ss->lock);
977             for (signo = 1; signo < NSIG; ++signo)
978               if (__sigismember (&ss->pending, signo)
979                   && (!__sigismember (&ss->blocked, signo)
980                       /* We "deliver" immediately pending blocked signals whose
981                          action might be to ignore, so that if ignored they are
982                          dropped right away.  */
983                       || ss->actions[signo].sa_handler == SIG_IGN
984                       || ss->actions[signo].sa_handler == SIG_DFL))
985                 {
986                   mutex_unlock (&_hurd_siglock);
987                   goto deliver_pending;
988                 }
989             __spin_unlock (&ss->lock);
990           }
991         __mutex_unlock (&_hurd_siglock);
992       }
993     else
994       {
995         /* No more signals pending; SS->lock is still locked.
996            Wake up any sigsuspend call that is blocking SS->thread.  */
997         if (ss->suspended != MACH_PORT_NULL)
998           {
999             /* There is a sigsuspend waiting.  Tell it to wake up.  */
1000             error_t err;
1001             mach_msg_header_t msg;
1002             err = __mach_port_insert_right (__mach_task_self (),
1003                                             ss->suspended, ss->suspended,
1004                                             MACH_MSG_TYPE_MAKE_SEND);
1005             assert_perror (err);
1006             msg.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_MOVE_SEND, 0);
1007             msg.msgh_remote_port = ss->suspended;
1008             msg.msgh_local_port = MACH_PORT_NULL;
1009             /* These values do not matter.  */
1010             msg.msgh_id = 8675309; /* Jenny, Jenny.  */
1011             msg.msgh_seqno = 17; /* Random.  */
1012             ss->suspended = MACH_PORT_NULL;
1013             err = __mach_msg (&msg, MACH_SEND_MSG, sizeof msg, 0,
1014                               MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE,
1015                               MACH_PORT_NULL);
1016             assert_perror (err);
1017           }
1018         __spin_unlock (&ss->lock);
1019       }
1020   }
1021
1022   /* All pending signals delivered to all threads.
1023      Now we can send the reply message even for signal 0.  */
1024   reply ();
1025 }
1026 \f
1027 /* Decide whether REFPORT enables the sender to send us a SIGNO signal.
1028    Returns zero if so, otherwise the error code to return to the sender.  */
1029
1030 static error_t
1031 signal_allowed (int signo, mach_port_t refport)
1032 {
1033   if (signo < 0 || signo >= NSIG)
1034     return EINVAL;
1035
1036   if (refport == __mach_task_self ())
1037     /* Can send any signal.  */
1038     goto win;
1039
1040   /* Avoid needing to check for this below.  */
1041   if (refport == MACH_PORT_NULL)
1042     return EPERM;
1043
1044   switch (signo)
1045     {
1046     case SIGINT:
1047     case SIGQUIT:
1048     case SIGTSTP:
1049     case SIGHUP:
1050     case SIGINFO:
1051     case SIGTTIN:
1052     case SIGTTOU:
1053     case SIGWINCH:
1054       /* Job control signals can be sent by the controlling terminal.  */
1055       if (__USEPORT (CTTYID, port == refport))
1056         goto win;
1057       break;
1058
1059     case SIGCONT:
1060       {
1061         /* A continue signal can be sent by anyone in the session.  */
1062         mach_port_t sessport;
1063         if (! __USEPORT (PROC, __proc_getsidport (port, &sessport)))
1064           {
1065             __mach_port_deallocate (__mach_task_self (), sessport);
1066             if (refport == sessport)
1067               goto win;
1068           }
1069       }
1070       break;
1071
1072     case SIGIO:
1073     case SIGURG:
1074       {
1075         /* Any io object a file descriptor refers to might send us
1076            one of these signals using its async ID port for REFPORT.
1077
1078            This is pretty wide open; it is not unlikely that some random
1079            process can at least open for reading something we have open,
1080            get its async ID port, and send us a spurious SIGIO or SIGURG
1081            signal.  But BSD is actually wider open than that!--you can set
1082            the owner of an io object to any process or process group
1083            whatsoever and send them gratuitous signals.
1084
1085            Someday we could implement some reasonable scheme for
1086            authorizing SIGIO and SIGURG signals properly.  */
1087
1088         int d;
1089         int lucky = 0;          /* True if we find a match for REFPORT.  */
1090         __mutex_lock (&_hurd_dtable_lock);
1091         for (d = 0; !lucky && (unsigned) d < (unsigned) _hurd_dtablesize; ++d)
1092           {
1093             struct hurd_userlink ulink;
1094             io_t port;
1095             mach_port_t asyncid;
1096             if (_hurd_dtable[d] == NULL)
1097               continue;
1098             port = _hurd_port_get (&_hurd_dtable[d]->port, &ulink);
1099             if (! __io_get_icky_async_id (port, &asyncid))
1100               {
1101                 if (refport == asyncid)
1102                   /* Break out of the loop on the next iteration.  */
1103                   lucky = 1;
1104                 __mach_port_deallocate (__mach_task_self (), asyncid);
1105               }
1106             _hurd_port_free (&_hurd_dtable[d]->port, &ulink, port);
1107           }
1108         /* If we found a lucky winner, we've set D to -1 in the loop.  */
1109         if (lucky)
1110           goto win;
1111       }
1112     }
1113
1114   /* If this signal is legit, we have done `goto win' by now.
1115      When we return the error, mig deallocates REFPORT.  */
1116   return EPERM;
1117
1118  win:
1119   /* Deallocate the REFPORT send right; we are done with it.  */
1120   __mach_port_deallocate (__mach_task_self (), refport);
1121
1122   return 0;
1123 }
1124
1125 /* Implement the sig_post RPC from <hurd/msg.defs>;
1126    sent when someone wants us to get a signal.  */
1127 kern_return_t
1128 _S_msg_sig_post (mach_port_t me,
1129                  mach_port_t reply_port, mach_msg_type_name_t reply_port_type,
1130                  int signo, natural_t sigcode,
1131                  mach_port_t refport)
1132 {
1133   error_t err;
1134   struct hurd_signal_detail d;
1135
1136   if (err = signal_allowed (signo, refport))
1137     return err;
1138
1139   d.code = sigcode;
1140   d.exc = 0;
1141
1142   /* Post the signal to the designated signal-receiving thread.  This will
1143      reply when the signal can be considered delivered.  */
1144   _hurd_internal_post_signal (_hurd_thread_sigstate (_hurd_sigthread),
1145                               signo, &d, reply_port, reply_port_type,
1146                               0); /* Stop if traced.  */
1147
1148   return MIG_NO_REPLY;          /* Already replied.  */
1149 }
1150
1151 /* Implement the sig_post_untraced RPC from <hurd/msg.defs>;
1152    sent when the debugger wants us to really get a signal
1153    even if we are traced.  */
1154 kern_return_t
1155 _S_msg_sig_post_untraced (mach_port_t me,
1156                           mach_port_t reply_port,
1157                           mach_msg_type_name_t reply_port_type,
1158                           int signo, natural_t sigcode,
1159                           mach_port_t refport)
1160 {
1161   error_t err;
1162   struct hurd_signal_detail d;
1163
1164   if (err = signal_allowed (signo, refport))
1165     return err;
1166
1167   d.code = sigcode;
1168   d.exc = 0;
1169
1170   /* Post the signal to the designated signal-receiving thread.  This will
1171      reply when the signal can be considered delivered.  */
1172   _hurd_internal_post_signal (_hurd_thread_sigstate (_hurd_sigthread),
1173                               signo, &d, reply_port, reply_port_type,
1174                               1); /* Untraced flag. */
1175
1176   return MIG_NO_REPLY;          /* Already replied.  */
1177 }
1178 \f
1179 extern void __mig_init (void *);
1180
1181 #include <mach/task_special_ports.h>
1182
1183 /* Initialize the message port and _hurd_sigthread and start the signal
1184    thread.  */
1185
1186 void
1187 _hurdsig_init (const int *intarray, size_t intarraysize)
1188 {
1189   error_t err;
1190   vm_size_t stacksize;
1191   struct hurd_sigstate *ss;
1192
1193   __mutex_init (&_hurd_siglock);
1194
1195   err = __mach_port_allocate (__mach_task_self (),
1196                               MACH_PORT_RIGHT_RECEIVE,
1197                               &_hurd_msgport);
1198   assert_perror (err);
1199
1200   /* Make a send right to the signal port.  */
1201   err = __mach_port_insert_right (__mach_task_self (),
1202                                   _hurd_msgport,
1203                                   _hurd_msgport,
1204                                   MACH_MSG_TYPE_MAKE_SEND);
1205   assert_perror (err);
1206
1207   /* Initialize the main thread's signal state.  */
1208   ss = _hurd_self_sigstate ();
1209
1210   /* Copy inherited values from our parent (or pre-exec process state)
1211      into the signal settings of the main thread.  */
1212   if (intarraysize > INIT_SIGMASK)
1213     ss->blocked = intarray[INIT_SIGMASK];
1214   if (intarraysize > INIT_SIGPENDING)
1215     ss->blocked = intarray[INIT_SIGPENDING];
1216   if (intarraysize > INIT_SIGIGN && intarray[INIT_SIGIGN] != 0)
1217     {
1218       int signo;
1219       for (signo = 1; signo < NSIG; ++signo)
1220         if (intarray[INIT_SIGIGN] & __sigmask(signo))
1221           ss->actions[signo].sa_handler = SIG_IGN;
1222     }
1223
1224   /* Set the default thread to receive task-global signals
1225      to this one, the main (first) user thread.  */
1226   _hurd_sigthread = ss->thread;
1227
1228   /* Start the signal thread listening on the message port.  */
1229
1230   if (__hurd_threadvar_stack_mask == 0)
1231     {
1232       err = __thread_create (__mach_task_self (), &_hurd_msgport_thread);
1233       assert_perror (err);
1234
1235       stacksize = ~__hurd_threadvar_stack_mask + 1;
1236       stacksize = __vm_page_size * 8; /* Small stack for signal thread.  */
1237       err = __mach_setup_thread (__mach_task_self (), _hurd_msgport_thread,
1238                                  _hurd_msgport_receive,
1239                                  (vm_address_t *) &__hurd_sigthread_stack_base,
1240                                  &stacksize);
1241       assert_perror (err);
1242
1243       __hurd_sigthread_stack_end = __hurd_sigthread_stack_base + stacksize;
1244       __hurd_sigthread_variables =
1245         malloc (__hurd_threadvar_max * sizeof (unsigned long int));
1246       if (__hurd_sigthread_variables == NULL)
1247         __libc_fatal ("hurd: Can't allocate threadvars for signal thread\n");
1248
1249       /* Reinitialize the MiG support routines so they will use a per-thread
1250          variable for the cached reply port.  */
1251       __mig_init ((void *) __hurd_sigthread_stack_base);
1252
1253       err = __thread_resume (_hurd_msgport_thread);
1254       assert_perror (err);
1255     }
1256   else
1257     {
1258       /* When cthreads is being used, we need to make the signal thread a
1259          proper cthread.  Otherwise it cannot use mutex_lock et al, which
1260          will be the cthreads versions.  Various of the message port RPC
1261          handlers need to take locks, so we need to be able to call into
1262          cthreads code and meet its assumptions about how our thread and
1263          its stack are arranged.  Since cthreads puts it there anyway,
1264          we'll let the signal thread's per-thread variables be found as for
1265          any normal cthread, and just leave the magic __hurd_sigthread_*
1266          values all zero so they'll be ignored.  */
1267 #pragma weak cthread_fork
1268 #pragma weak cthread_detach
1269       cthread_detach (cthread_fork ((cthread_fn_t) &_hurd_msgport_receive, 0));
1270     }
1271
1272   /* Receive exceptions on the signal port.  */
1273   __task_set_special_port (__mach_task_self (),
1274                            TASK_EXCEPTION_PORT, _hurd_msgport);
1275
1276   /* Sanity check.  Any pending, unblocked signals should have been
1277      taken by our predecessor incarnation (i.e. parent or pre-exec state)
1278      before packing up our init ints.  This assert is last (not above)
1279      so that signal handling is all set up to handle the abort.  */
1280   assert ((ss->pending &~ ss->blocked) == 0);
1281 }
1282 \f                               /* XXXX */
1283 /* Reauthenticate with the proc server.  */
1284
1285 static void
1286 reauth_proc (mach_port_t new)
1287 {
1288   mach_port_t ref, ignore;
1289
1290   ref = __mach_reply_port ();
1291   if (! HURD_PORT_USE (&_hurd_ports[INIT_PORT_PROC],
1292                        __proc_reauthenticate (port, ref,
1293                                               MACH_MSG_TYPE_MAKE_SEND) ||
1294                        __auth_user_authenticate (new, ref,
1295                                                  MACH_MSG_TYPE_MAKE_SEND,
1296                                                  &ignore))
1297       && ignore != MACH_PORT_NULL)
1298     __mach_port_deallocate (__mach_task_self (), ignore);
1299   __mach_port_destroy (__mach_task_self (), ref);
1300
1301   /* Set the owner of the process here too. */
1302   mutex_lock (&_hurd_id.lock);
1303   if (!_hurd_check_ids ())
1304     HURD_PORT_USE (&_hurd_ports[INIT_PORT_PROC],
1305                    __proc_setowner (port,
1306                                     (_hurd_id.gen.nuids
1307                                      ? _hurd_id.gen.uids[0] : 0),
1308                                     !_hurd_id.gen.nuids));
1309   mutex_unlock (&_hurd_id.lock);
1310
1311   (void) &reauth_proc;          /* Silence compiler warning.  */
1312 }
1313 text_set_element (_hurd_reauth_hook, reauth_proc);
1314 \f
1315 /* Like `getenv', but safe for the signal thread to run.
1316    If the environment is trashed, this will just return NULL.  */
1317
1318 const char *
1319 _hurdsig_getenv (const char *variable)
1320 {
1321   if (_hurdsig_catch_memory_fault (__environ))
1322     /* We bombed in getenv.  */
1323     return NULL;
1324   else
1325     {
1326       const size_t len = strlen (variable);
1327       char *value = NULL;
1328       char *volatile *ep = __environ;
1329       while (*ep)
1330         {
1331           const char *p = *ep;
1332           _hurdsig_fault_preemptor.first = (long int) p;
1333           _hurdsig_fault_preemptor.last = VM_MAX_ADDRESS;
1334           if (! strncmp (p, variable, len) && p[len] == '=')
1335             {
1336               char *value;
1337               size_t valuelen;
1338               p += len + 1;
1339               valuelen = strlen (p);
1340               _hurdsig_fault_preemptor.last = (long int) (p + valuelen);
1341               value = malloc (++valuelen);
1342               if (value)
1343                 memcpy (value, p, valuelen);
1344               break;
1345             }
1346           _hurdsig_fault_preemptor.first = (long int) ++ep;
1347           _hurdsig_fault_preemptor.last = (long int) (ep + 1);
1348         }
1349       _hurdsig_end_catch_fault ();
1350       return value;
1351     }
1352 }