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