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