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