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