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