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