* hurd/hurdsig.c (_hurd_internal_post_signal): When normal rules would
[platform/upstream/glibc.git] / hurd / hurdsig.c
1 /* Copyright (C) 1991,92,93,94,95,96,97,98,99,2000,2001,2002,2005,2008
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       if (detail->exc)
747         /* Blocking or ignoring a machine exception is fatal.
748            Otherwise we could just spin on the faulting instruction.  */
749         goto fatal;
750
751       /* Nobody cares about this signal.  If there was a call to resume
752          above in SIGCONT processing and we've left a thread suspended,
753          now's the time to set it going. */
754       if (ss_suspended)
755         {
756           err = __thread_resume (ss->thread);
757           assert_perror (err);
758           ss_suspended = 0;
759         }
760       break;
761
762     sigbomb:
763       /* We got a fault setting up the stack frame for the handler.
764          Nothing to do but die; BSD gets SIGILL in this case.  */
765       detail->code = signo;     /* XXX ? */
766       signo = SIGILL;
767
768     fatal:
769       act = core;
770       /* FALLTHROUGH */
771
772     case term:                  /* Time to die.  */
773     case core:                  /* And leave a rotting corpse.  */
774       /* Have the proc server stop all other threads in our task.  */
775       err = __USEPORT (PROC, __proc_dostop (port, _hurd_msgport_thread));
776       assert_perror (err);
777       /* No more user instructions will be executed.
778          The signal can now be considered delivered.  */
779       reply ();
780       /* Abort all server operations now in progress.  */
781       abort_all_rpcs (signo, &thread_state, 0);
782
783       {
784         int status = W_EXITCODE (0, signo);
785         /* Do a core dump if desired.  Only set the wait status bit saying we
786            in fact dumped core if the operation was actually successful.  */
787         if (act == core && write_corefile (signo, detail))
788           status |= WCOREFLAG;
789         /* Tell proc how we died and then stick the saber in the gut.  */
790         _hurd_exit (status);
791         /* NOTREACHED */
792       }
793
794     case handle:
795       /* Call a handler for this signal.  */
796       {
797         struct sigcontext *scp, ocontext;
798         int wait_for_reply, state_changed;
799
800         /* Stop the thread and abort its pending RPC operations.  */
801         if (! ss_suspended)
802           {
803             err = __thread_suspend (ss->thread);
804             assert_perror (err);
805           }
806
807         /* Abort the thread's kernel context, so any pending message send
808            or receive completes immediately or aborts.  If an interruptible
809            RPC is in progress, abort_rpcs will do this.  But we must always
810            do it before fetching the thread's state, because
811            thread_get_state is never kosher before thread_abort.  */
812         abort_thread (ss, &thread_state, NULL);
813
814         if (ss->context)
815           {
816             /* We have a previous sigcontext that sigreturn was about
817                to restore when another signal arrived.  */
818
819             mach_port_t *loc;
820
821             if (_hurdsig_catch_memory_fault (ss->context))
822               {
823                 /* We faulted reading the thread's stack.  Forget that
824                    context and pretend it wasn't there.  It almost
825                    certainly crash if this handler returns, but that's it's
826                    problem.  */
827                 ss->context = NULL;
828               }
829             else
830               {
831                 /* Copy the context from the thread's stack before
832                    we start diddling the stack to set up the handler.  */
833                 ocontext = *ss->context;
834                 ss->context = &ocontext;
835               }
836             _hurdsig_end_catch_fault ();
837
838             if (! machine_get_basic_state (ss->thread, &thread_state))
839               goto sigbomb;
840             loc = interrupted_reply_port_location (&thread_state, 1);
841             if (loc && *loc != MACH_PORT_NULL)
842               /* This is the reply port for the context which called
843                  sigreturn.  Since we are abandoning that context entirely
844                  and restoring SS->context instead, destroy this port.  */
845               __mach_port_destroy (__mach_task_self (), *loc);
846
847             /* The thread was in sigreturn, not in any interruptible RPC.  */
848             wait_for_reply = 0;
849
850             assert (! __spin_lock_locked (&ss->critical_section_lock));
851           }
852         else
853           {
854             int crit = __spin_lock_locked (&ss->critical_section_lock);
855
856             wait_for_reply
857               = (_hurdsig_abort_rpcs (ss,
858                                       /* In a critical section, any RPC
859                                          should be cancelled instead of
860                                          restarted, regardless of
861                                          SA_RESTART, so the entire
862                                          "atomic" operation can be aborted
863                                          as a unit.  */
864                                       crit ? 0 : signo, 1,
865                                       &thread_state, &state_changed,
866                                       &reply)
867                  != MACH_PORT_NULL);
868
869             if (crit)
870               {
871                 /* The thread is in a critical section.  Mark the signal as
872                    pending.  When it finishes the critical section, it will
873                    check for pending signals.  */
874                 mark_pending ();
875                 if (state_changed)
876                   /* Some cases of interrupting an RPC must change the
877                      thread state to back out the call.  Normally this
878                      change is rolled into the warping to the handler and
879                      sigreturn, but we are not running the handler now
880                      because the thread is in a critical section.  Instead,
881                      mutate the thread right away for the RPC interruption
882                      and resume it; the RPC will return early so the
883                      critical section can end soon.  */
884                   __thread_set_state (ss->thread, MACHINE_THREAD_STATE_FLAVOR,
885                                       (natural_t *) &thread_state.basic,
886                                       MACHINE_THREAD_STATE_COUNT);
887                 /* */
888                 ss->intr_port = MACH_PORT_NULL;
889                 __thread_resume (ss->thread);
890                 break;
891               }
892           }
893
894         /* Call the machine-dependent function to set the thread up
895            to run the signal handler, and preserve its old context.  */
896         scp = _hurd_setup_sighandler (ss, handler, signo, detail,
897                                       wait_for_reply, &thread_state);
898         if (scp == NULL)
899           goto sigbomb;
900
901         /* Set the machine-independent parts of the signal context.  */
902
903         {
904           /* Fetch the thread variable for the MiG reply port,
905              and set it to MACH_PORT_NULL.  */
906           mach_port_t *loc = interrupted_reply_port_location (&thread_state,
907                                                               1);
908           if (loc)
909             {
910               scp->sc_reply_port = *loc;
911               *loc = MACH_PORT_NULL;
912             }
913           else
914             scp->sc_reply_port = MACH_PORT_NULL;
915
916           /* Save the intr_port in use by the interrupted code,
917              and clear the cell before running the trampoline.  */
918           scp->sc_intr_port = ss->intr_port;
919           ss->intr_port = MACH_PORT_NULL;
920
921           if (ss->context)
922             {
923               /* After the handler runs we will restore to the state in
924                  SS->context, not the state of the thread now.  So restore
925                  that context's reply port and intr port.  */
926
927               scp->sc_reply_port = ss->context->sc_reply_port;
928               scp->sc_intr_port = ss->context->sc_intr_port;
929
930               ss->context = NULL;
931             }
932         }
933
934         /* Backdoor extra argument to signal handler.  */
935         scp->sc_error = detail->error;
936
937         /* Block requested signals while running the handler.  */
938         scp->sc_mask = ss->blocked;
939         __sigorset (&ss->blocked, &ss->blocked, &ss->actions[signo].sa_mask);
940
941         /* Also block SIGNO unless we're asked not to.  */
942         if (! (ss->actions[signo].sa_flags & (SA_RESETHAND | SA_NODEFER)))
943           __sigaddset (&ss->blocked, signo);
944
945         /* Reset to SIG_DFL if requested.  SIGILL and SIGTRAP cannot
946            be automatically reset when delivered; the system silently
947            enforces this restriction.  */
948         if (ss->actions[signo].sa_flags & SA_RESETHAND
949             && signo != SIGILL && signo != SIGTRAP)
950           ss->actions[signo].sa_handler = SIG_DFL;
951
952         /* Start the thread running the handler (or possibly waiting for an
953            RPC reply before running the handler).  */
954         err = __thread_set_state (ss->thread, MACHINE_THREAD_STATE_FLAVOR,
955                                   (natural_t *) &thread_state.basic,
956                                   MACHINE_THREAD_STATE_COUNT);
957         assert_perror (err);
958         err = __thread_resume (ss->thread);
959         assert_perror (err);
960         thread_state.set = 0;   /* Everything we know is now wrong.  */
961         break;
962       }
963     }
964
965   /* The signal has either been ignored or is now being handled.  We can
966      consider it delivered and reply to the killer.  */
967   reply ();
968
969   /* We get here unless the signal was fatal.  We still hold SS->lock.
970      Check for pending signals, and loop to post them.  */
971   {
972     /* Return nonzero if SS has any signals pending we should worry about.
973        We don't worry about any pending signals if we are stopped, nor if
974        SS is in a critical section.  We are guaranteed to get a sig_post
975        message before any of them become deliverable: either the SIGCONT
976        signal, or a sig_post with SIGNO==0 as an explicit poll when the
977        thread finishes its critical section.  */
978     inline int signals_pending (void)
979       {
980         if (_hurd_stopped || __spin_lock_locked (&ss->critical_section_lock))
981           return 0;
982         return pending = ss->pending & ~ss->blocked;
983       }
984
985   check_pending_signals:
986     untraced = 0;
987
988     if (signals_pending ())
989       {
990         for (signo = 1; signo < NSIG; ++signo)
991           if (__sigismember (&pending, signo))
992             {
993             deliver_pending:
994               __sigdelset (&ss->pending, signo);
995               *detail = ss->pending_data[signo];
996               __spin_unlock (&ss->lock);
997               goto post_signal;
998             }
999       }
1000
1001     /* No pending signals left undelivered for this thread.
1002        If we were sent signal 0, we need to check for pending
1003        signals for all threads.  */
1004     if (signo == 0)
1005       {
1006         __spin_unlock (&ss->lock);
1007         __mutex_lock (&_hurd_siglock);
1008         for (ss = _hurd_sigstates; ss != NULL; ss = ss->next)
1009           {
1010             __spin_lock (&ss->lock);
1011             for (signo = 1; signo < NSIG; ++signo)
1012               if (__sigismember (&ss->pending, signo)
1013                   && (!__sigismember (&ss->blocked, signo)
1014                       /* We "deliver" immediately pending blocked signals whose
1015                          action might be to ignore, so that if ignored they are
1016                          dropped right away.  */
1017                       || ss->actions[signo].sa_handler == SIG_IGN
1018                       || ss->actions[signo].sa_handler == SIG_DFL))
1019                 {
1020                   mutex_unlock (&_hurd_siglock);
1021                   goto deliver_pending;
1022                 }
1023             __spin_unlock (&ss->lock);
1024           }
1025         __mutex_unlock (&_hurd_siglock);
1026       }
1027     else
1028       {
1029         /* No more signals pending; SS->lock is still locked.
1030            Wake up any sigsuspend call that is blocking SS->thread.  */
1031         if (ss->suspended != MACH_PORT_NULL)
1032           {
1033             /* There is a sigsuspend waiting.  Tell it to wake up.  */
1034             error_t err;
1035             mach_msg_header_t msg;
1036             msg.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_MAKE_SEND, 0);
1037             msg.msgh_remote_port = ss->suspended;
1038             msg.msgh_local_port = MACH_PORT_NULL;
1039             /* These values do not matter.  */
1040             msg.msgh_id = 8675309; /* Jenny, Jenny.  */
1041             ss->suspended = MACH_PORT_NULL;
1042             err = __mach_msg (&msg, MACH_SEND_MSG, sizeof msg, 0,
1043                               MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE,
1044                               MACH_PORT_NULL);
1045             assert_perror (err);
1046           }
1047         __spin_unlock (&ss->lock);
1048       }
1049   }
1050
1051   /* All pending signals delivered to all threads.
1052      Now we can send the reply message even for signal 0.  */
1053   reply ();
1054 }
1055 \f
1056 /* Decide whether REFPORT enables the sender to send us a SIGNO signal.
1057    Returns zero if so, otherwise the error code to return to the sender.  */
1058
1059 static error_t
1060 signal_allowed (int signo, mach_port_t refport)
1061 {
1062   if (signo < 0 || signo >= NSIG)
1063     return EINVAL;
1064
1065   if (refport == __mach_task_self ())
1066     /* Can send any signal.  */
1067     goto win;
1068
1069   /* Avoid needing to check for this below.  */
1070   if (refport == MACH_PORT_NULL)
1071     return EPERM;
1072
1073   switch (signo)
1074     {
1075     case SIGINT:
1076     case SIGQUIT:
1077     case SIGTSTP:
1078     case SIGHUP:
1079     case SIGINFO:
1080     case SIGTTIN:
1081     case SIGTTOU:
1082     case SIGWINCH:
1083       /* Job control signals can be sent by the controlling terminal.  */
1084       if (__USEPORT (CTTYID, port == refport))
1085         goto win;
1086       break;
1087
1088     case SIGCONT:
1089       {
1090         /* A continue signal can be sent by anyone in the session.  */
1091         mach_port_t sessport;
1092         if (! __USEPORT (PROC, __proc_getsidport (port, &sessport)))
1093           {
1094             __mach_port_deallocate (__mach_task_self (), sessport);
1095             if (refport == sessport)
1096               goto win;
1097           }
1098       }
1099       break;
1100
1101     case SIGIO:
1102     case SIGURG:
1103       {
1104         /* Any io object a file descriptor refers to might send us
1105            one of these signals using its async ID port for REFPORT.
1106
1107            This is pretty wide open; it is not unlikely that some random
1108            process can at least open for reading something we have open,
1109            get its async ID port, and send us a spurious SIGIO or SIGURG
1110            signal.  But BSD is actually wider open than that!--you can set
1111            the owner of an io object to any process or process group
1112            whatsoever and send them gratuitous signals.
1113
1114            Someday we could implement some reasonable scheme for
1115            authorizing SIGIO and SIGURG signals properly.  */
1116
1117         int d;
1118         int lucky = 0;          /* True if we find a match for REFPORT.  */
1119         __mutex_lock (&_hurd_dtable_lock);
1120         for (d = 0; !lucky && (unsigned) d < (unsigned) _hurd_dtablesize; ++d)
1121           {
1122             struct hurd_userlink ulink;
1123             io_t port;
1124             mach_port_t asyncid;
1125             if (_hurd_dtable[d] == NULL)
1126               continue;
1127             port = _hurd_port_get (&_hurd_dtable[d]->port, &ulink);
1128             if (! __io_get_icky_async_id (port, &asyncid))
1129               {
1130                 if (refport == asyncid)
1131                   /* Break out of the loop on the next iteration.  */
1132                   lucky = 1;
1133                 __mach_port_deallocate (__mach_task_self (), asyncid);
1134               }
1135             _hurd_port_free (&_hurd_dtable[d]->port, &ulink, port);
1136           }
1137         /* If we found a lucky winner, we've set D to -1 in the loop.  */
1138         if (lucky)
1139           goto win;
1140       }
1141     }
1142
1143   /* If this signal is legit, we have done `goto win' by now.
1144      When we return the error, mig deallocates REFPORT.  */
1145   return EPERM;
1146
1147  win:
1148   /* Deallocate the REFPORT send right; we are done with it.  */
1149   __mach_port_deallocate (__mach_task_self (), refport);
1150
1151   return 0;
1152 }
1153
1154 /* Implement the sig_post RPC from <hurd/msg.defs>;
1155    sent when someone wants us to get a signal.  */
1156 kern_return_t
1157 _S_msg_sig_post (mach_port_t me,
1158                  mach_port_t reply_port, mach_msg_type_name_t reply_port_type,
1159                  int signo, natural_t sigcode,
1160                  mach_port_t refport)
1161 {
1162   error_t err;
1163   struct hurd_signal_detail d;
1164
1165   if (err = signal_allowed (signo, refport))
1166     return err;
1167
1168   d.code = sigcode;
1169   d.exc = 0;
1170
1171   /* Post the signal to the designated signal-receiving thread.  This will
1172      reply when the signal can be considered delivered.  */
1173   _hurd_internal_post_signal (_hurd_thread_sigstate (_hurd_sigthread),
1174                               signo, &d, reply_port, reply_port_type,
1175                               0); /* Stop if traced.  */
1176
1177   return MIG_NO_REPLY;          /* Already replied.  */
1178 }
1179
1180 /* Implement the sig_post_untraced RPC from <hurd/msg.defs>;
1181    sent when the debugger wants us to really get a signal
1182    even if we are traced.  */
1183 kern_return_t
1184 _S_msg_sig_post_untraced (mach_port_t me,
1185                           mach_port_t reply_port,
1186                           mach_msg_type_name_t reply_port_type,
1187                           int signo, natural_t sigcode,
1188                           mach_port_t refport)
1189 {
1190   error_t err;
1191   struct hurd_signal_detail d;
1192
1193   if (err = signal_allowed (signo, refport))
1194     return err;
1195
1196   d.code = sigcode;
1197   d.exc = 0;
1198
1199   /* Post the signal to the designated signal-receiving thread.  This will
1200      reply when the signal can be considered delivered.  */
1201   _hurd_internal_post_signal (_hurd_thread_sigstate (_hurd_sigthread),
1202                               signo, &d, reply_port, reply_port_type,
1203                               1); /* Untraced flag. */
1204
1205   return MIG_NO_REPLY;          /* Already replied.  */
1206 }
1207 \f
1208 extern void __mig_init (void *);
1209
1210 #include <mach/task_special_ports.h>
1211
1212 /* Initialize the message port and _hurd_sigthread and start the signal
1213    thread.  */
1214
1215 void
1216 _hurdsig_init (const int *intarray, size_t intarraysize)
1217 {
1218   error_t err;
1219   vm_size_t stacksize;
1220   struct hurd_sigstate *ss;
1221
1222   __mutex_init (&_hurd_siglock);
1223
1224   err = __mach_port_allocate (__mach_task_self (),
1225                               MACH_PORT_RIGHT_RECEIVE,
1226                               &_hurd_msgport);
1227   assert_perror (err);
1228
1229   /* Make a send right to the signal port.  */
1230   err = __mach_port_insert_right (__mach_task_self (),
1231                                   _hurd_msgport,
1232                                   _hurd_msgport,
1233                                   MACH_MSG_TYPE_MAKE_SEND);
1234   assert_perror (err);
1235
1236   /* Initialize the main thread's signal state.  */
1237   ss = _hurd_self_sigstate ();
1238
1239   /* Copy inherited values from our parent (or pre-exec process state)
1240      into the signal settings of the main thread.  */
1241   if (intarraysize > INIT_SIGMASK)
1242     ss->blocked = intarray[INIT_SIGMASK];
1243   if (intarraysize > INIT_SIGPENDING)
1244     ss->pending = intarray[INIT_SIGPENDING];
1245   if (intarraysize > INIT_SIGIGN && intarray[INIT_SIGIGN] != 0)
1246     {
1247       int signo;
1248       for (signo = 1; signo < NSIG; ++signo)
1249         if (intarray[INIT_SIGIGN] & __sigmask(signo))
1250           ss->actions[signo].sa_handler = SIG_IGN;
1251     }
1252
1253   /* Set the default thread to receive task-global signals
1254      to this one, the main (first) user thread.  */
1255   _hurd_sigthread = ss->thread;
1256
1257   /* Start the signal thread listening on the message port.  */
1258
1259   if (__hurd_threadvar_stack_mask == 0)
1260     {
1261       err = __thread_create (__mach_task_self (), &_hurd_msgport_thread);
1262       assert_perror (err);
1263
1264       stacksize = __vm_page_size * 8; /* Small stack for signal thread.  */
1265       err = __mach_setup_thread (__mach_task_self (), _hurd_msgport_thread,
1266                                  _hurd_msgport_receive,
1267                                  (vm_address_t *) &__hurd_sigthread_stack_base,
1268                                  &stacksize);
1269       assert_perror (err);
1270
1271       __hurd_sigthread_stack_end = __hurd_sigthread_stack_base + stacksize;
1272       __hurd_sigthread_variables =
1273         malloc (__hurd_threadvar_max * sizeof (unsigned long int));
1274       if (__hurd_sigthread_variables == NULL)
1275         __libc_fatal ("hurd: Can't allocate threadvars for signal thread\n");
1276       memset (__hurd_sigthread_variables, 0,
1277               __hurd_threadvar_max * sizeof (unsigned long int));
1278       __hurd_sigthread_variables[_HURD_THREADVAR_LOCALE]
1279         = (unsigned long int) &_nl_global_locale;
1280
1281       /* Reinitialize the MiG support routines so they will use a per-thread
1282          variable for the cached reply port.  */
1283       __mig_init ((void *) __hurd_sigthread_stack_base);
1284
1285       err = __thread_resume (_hurd_msgport_thread);
1286       assert_perror (err);
1287     }
1288   else
1289     {
1290       /* When cthreads is being used, we need to make the signal thread a
1291          proper cthread.  Otherwise it cannot use mutex_lock et al, which
1292          will be the cthreads versions.  Various of the message port RPC
1293          handlers need to take locks, so we need to be able to call into
1294          cthreads code and meet its assumptions about how our thread and
1295          its stack are arranged.  Since cthreads puts it there anyway,
1296          we'll let the signal thread's per-thread variables be found as for
1297          any normal cthread, and just leave the magic __hurd_sigthread_*
1298          values all zero so they'll be ignored.  */
1299 #pragma weak cthread_fork
1300 #pragma weak cthread_detach
1301       cthread_detach (cthread_fork ((cthread_fn_t) &_hurd_msgport_receive, 0));
1302
1303       /* XXX We need the thread port for the signal thread further on
1304          in this thread (see hurdfault.c:_hurdsigfault_init).
1305          Therefore we block until _hurd_msgport_thread is initialized
1306          by the newly created thread.  This really shouldn't be
1307          necessary; we should be able to fetch the thread port for a
1308          cthread from here.  */
1309       while (_hurd_msgport_thread == 0)
1310         __swtch_pri (0);
1311     }
1312
1313   /* Receive exceptions on the signal port.  */
1314 #ifdef TASK_EXCEPTION_PORT
1315   __task_set_special_port (__mach_task_self (),
1316                            TASK_EXCEPTION_PORT, _hurd_msgport);
1317 #elif defined (EXC_MASK_ALL)
1318   __task_set_exception_ports (__mach_task_self (),
1319                               EXC_MASK_ALL & ~(EXC_MASK_SYSCALL
1320                                                | EXC_MASK_MACH_SYSCALL
1321                                                | EXC_MASK_RPC_ALERT),
1322                               _hurd_msgport,
1323                               EXCEPTION_DEFAULT, MACHINE_THREAD_STATE);
1324 #else
1325 # error task_set_exception_port?
1326 #endif
1327
1328   /* Sanity check.  Any pending, unblocked signals should have been
1329      taken by our predecessor incarnation (i.e. parent or pre-exec state)
1330      before packing up our init ints.  This assert is last (not above)
1331      so that signal handling is all set up to handle the abort.  */
1332   assert ((ss->pending &~ ss->blocked) == 0);
1333 }
1334 \f                               /* XXXX */
1335 /* Reauthenticate with the proc server.  */
1336
1337 static void
1338 reauth_proc (mach_port_t new)
1339 {
1340   mach_port_t ref, ignore;
1341
1342   ref = __mach_reply_port ();
1343   if (! HURD_PORT_USE (&_hurd_ports[INIT_PORT_PROC],
1344                        __proc_reauthenticate (port, ref,
1345                                               MACH_MSG_TYPE_MAKE_SEND) ||
1346                        __auth_user_authenticate (new, ref,
1347                                                  MACH_MSG_TYPE_MAKE_SEND,
1348                                                  &ignore))
1349       && ignore != MACH_PORT_NULL)
1350     __mach_port_deallocate (__mach_task_self (), ignore);
1351   __mach_port_destroy (__mach_task_self (), ref);
1352
1353   /* Set the owner of the process here too. */
1354   mutex_lock (&_hurd_id.lock);
1355   if (!_hurd_check_ids ())
1356     HURD_PORT_USE (&_hurd_ports[INIT_PORT_PROC],
1357                    __proc_setowner (port,
1358                                     (_hurd_id.gen.nuids
1359                                      ? _hurd_id.gen.uids[0] : 0),
1360                                     !_hurd_id.gen.nuids));
1361   mutex_unlock (&_hurd_id.lock);
1362
1363   (void) &reauth_proc;          /* Silence compiler warning.  */
1364 }
1365 text_set_element (_hurd_reauth_hook, reauth_proc);
1366 \f
1367 /* Like `getenv', but safe for the signal thread to run.
1368    If the environment is trashed, this will just return NULL.  */
1369
1370 const char *
1371 _hurdsig_getenv (const char *variable)
1372 {
1373   if (__libc_enable_secure)
1374     return NULL;
1375
1376   if (_hurdsig_catch_memory_fault (__environ))
1377     /* We bombed in getenv.  */
1378     return NULL;
1379   else
1380     {
1381       const size_t len = strlen (variable);
1382       char *value = NULL;
1383       char *volatile *ep = __environ;
1384       while (*ep)
1385         {
1386           const char *p = *ep;
1387           _hurdsig_fault_preemptor.first = (long int) p;
1388           _hurdsig_fault_preemptor.last = VM_MAX_ADDRESS;
1389           if (! strncmp (p, variable, len) && p[len] == '=')
1390             {
1391               size_t valuelen;
1392               p += len + 1;
1393               valuelen = strlen (p);
1394               _hurdsig_fault_preemptor.last = (long int) (p + valuelen);
1395               value = malloc (++valuelen);
1396               if (value)
1397                 memcpy (value, p, valuelen);
1398               break;
1399             }
1400           _hurdsig_fault_preemptor.first = (long int) ++ep;
1401           _hurdsig_fault_preemptor.last = (long int) (ep + 1);
1402         }
1403       _hurdsig_end_catch_fault ();
1404       return value;
1405     }
1406 }