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