/* Copyright (C) 1991,92,93,94,95,96,97,98,99,2000,2001,2002,2005,2008
   	Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <cthreads.h>		/* For `struct mutex'.  */
#include <mach.h>
#include <mach/thread_switch.h>

#include <hurd.h>
#include <hurd/id.h>
#include <hurd/signal.h>

#include "hurdfault.h"
#include "hurdmalloc.h"		/* XXX */
#include "../locale/localeinfo.h"

const char *_hurdsig_getenv (const char *);

struct mutex _hurd_siglock;
int _hurd_stopped;

/* Port that receives signals and other miscellaneous messages.  */
mach_port_t _hurd_msgport;

/* Thread listening on it.  */
thread_t _hurd_msgport_thread;

/* Thread which receives task-global signals.  */
thread_t _hurd_sigthread;

/* These are set up by _hurdsig_init.  */
unsigned long int __hurd_sigthread_stack_base;
unsigned long int __hurd_sigthread_stack_end;
unsigned long int *__hurd_sigthread_variables;

/* Linked-list of per-thread signal state.  */
struct hurd_sigstate *_hurd_sigstates;

/* Timeout for RPC's after interrupt_operation. */
mach_msg_timeout_t _hurd_interrupted_rpc_timeout = 3000;

static void
default_sigaction (struct sigaction actions[NSIG])
{
  int signo;

  __sigemptyset (&actions[0].sa_mask);
  actions[0].sa_flags = SA_RESTART;
  actions[0].sa_handler = SIG_DFL;

  for (signo = 1; signo < NSIG; ++signo)
    actions[signo] = actions[0];
}

struct hurd_sigstate *
_hurd_thread_sigstate (thread_t thread)
{
  struct hurd_sigstate *ss;
  __mutex_lock (&_hurd_siglock);
  for (ss = _hurd_sigstates; ss != NULL; ss = ss->next)
    if (ss->thread == thread)
       break;
  if (ss == NULL)
    {
      ss = malloc (sizeof (*ss));
      if (ss == NULL)
	__libc_fatal ("hurd: Can't allocate thread sigstate\n");
      ss->thread = thread;
      __spin_lock_init (&ss->lock);

      /* Initialize default state.  */
      __sigemptyset (&ss->blocked);
      __sigemptyset (&ss->pending);
      memset (&ss->sigaltstack, 0, sizeof (ss->sigaltstack));
      ss->preemptors = NULL;
      ss->suspended = MACH_PORT_NULL;
      ss->intr_port = MACH_PORT_NULL;
      ss->context = NULL;

      /* Initialize the sigaction vector from the default signal receiving
	 thread's state, and its from the system defaults.  */
      if (thread == _hurd_sigthread)
	default_sigaction (ss->actions);
      else
	{
	  struct hurd_sigstate *s;
	  for (s = _hurd_sigstates; s != NULL; s = s->next)
	    if (s->thread == _hurd_sigthread)
	      break;
	  if (s)
	    {
	      __spin_lock (&s->lock);
	      memcpy (ss->actions, s->actions, sizeof (s->actions));
	      __spin_unlock (&s->lock);
	    }
	  else
	    default_sigaction (ss->actions);
	}

      ss->next = _hurd_sigstates;
      _hurd_sigstates = ss;
    }
  __mutex_unlock (&_hurd_siglock);
  return ss;
}

/* Signal delivery itself is on this page.  */

#include <hurd/fd.h>
#include <hurd/crash.h>
#include <hurd/resource.h>
#include <hurd/paths.h>
#include <setjmp.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <thread_state.h>
#include <hurd/msg_server.h>
#include <hurd/msg_reply.h>	/* For __msg_sig_post_reply.  */
#include <hurd/interrupt.h>
#include <assert.h>
#include <unistd.h>


/* Call the crash dump server to mummify us before we die.
   Returns nonzero if a core file was written.  */
static int
write_corefile (int signo, const struct hurd_signal_detail *detail)
{
  error_t err;
  mach_port_t coreserver;
  file_t file, coredir;
  const char *name;

  /* Don't bother locking since we just read the one word.  */
  rlim_t corelimit = _hurd_rlimits[RLIMIT_CORE].rlim_cur;

  if (corelimit == 0)
    /* No core dumping, thank you very much.  Note that this makes
       `ulimit -c 0' prevent crash-suspension too, which is probably
       what the user wanted.  */
    return 0;

  /* XXX RLIMIT_CORE:
     When we have a protocol to make the server return an error
     for RLIMIT_FSIZE, then tell the corefile fs server the RLIMIT_CORE
     value in place of the RLIMIT_FSIZE value.  */

  /* First get a port to the core dumping server.  */
  coreserver = MACH_PORT_NULL;
  name = _hurdsig_getenv ("CRASHSERVER");
  if (name != NULL)
    coreserver = __file_name_lookup (name, 0, 0);
  if (coreserver == MACH_PORT_NULL)
    coreserver = __file_name_lookup (_SERVERS_CRASH, 0, 0);
  if (coreserver == MACH_PORT_NULL)
    return 0;

  /* Get a port to the directory where the new core file will reside.  */
  file = MACH_PORT_NULL;
  name = _hurdsig_getenv ("COREFILE");
  if (name == NULL)
    name = "core";
  coredir = __file_name_split (name, (char **) &name);
  if (coredir != MACH_PORT_NULL)
    /* Create the new file, but don't link it into the directory yet.  */
    __dir_mkfile (coredir, O_WRONLY|O_CREAT,
		  0600 & ~_hurd_umask, /* XXX ? */
		  &file);

  /* Call the core dumping server to write the core file.  */
  err = __crash_dump_task (coreserver,
			   __mach_task_self (),
			   file,
			   signo, detail->code, detail->error,
			   detail->exc, detail->exc_code, detail->exc_subcode,
			   _hurd_ports[INIT_PORT_CTTYID].port,
			   MACH_MSG_TYPE_COPY_SEND);
  __mach_port_deallocate (__mach_task_self (), coreserver);

  if (! err && file != MACH_PORT_NULL)
    /* The core dump into FILE succeeded, so now link it into the
       directory.  */
    err = __dir_link (coredir, file, name, 1);
  __mach_port_deallocate (__mach_task_self (), file);
  __mach_port_deallocate (__mach_task_self (), coredir);
  return !err && file != MACH_PORT_NULL;
}


/* The lowest-numbered thread state flavor value is 1,
   so we use bit 0 in machine_thread_all_state.set to
   record whether we have done thread_abort.  */
#define THREAD_ABORTED 1

/* SS->thread is suspended.  Abort the thread and get its basic state.  */
static void
abort_thread (struct hurd_sigstate *ss, struct machine_thread_all_state *state,
	      void (*reply) (void))
{
  if (!(state->set & THREAD_ABORTED))
    {
      error_t err = __thread_abort (ss->thread);
      assert_perror (err);
      /* Clear all thread state flavor set bits, because thread_abort may
	 have changed the state.  */
      state->set = THREAD_ABORTED;
    }

  if (reply)
    (*reply) ();

  machine_get_basic_state (ss->thread, state);
}

/* Find the location of the MiG reply port cell in use by the thread whose
   state is described by THREAD_STATE.  If SIGTHREAD is nonzero, make sure
   that this location can be set without faulting, or else return NULL.  */

static mach_port_t *
interrupted_reply_port_location (struct machine_thread_all_state *thread_state,
				 int sigthread)
{
  mach_port_t *portloc = (mach_port_t *) __hurd_threadvar_location_from_sp
    (_HURD_THREADVAR_MIG_REPLY, (void *) thread_state->basic.SP);

  if (sigthread && _hurdsig_catch_memory_fault (portloc))
    /* Faulted trying to read the stack.  */
    return NULL;

  /* Fault now if this pointer is bogus.  */
  *(volatile mach_port_t *) portloc = *portloc;

  if (sigthread)
    _hurdsig_end_catch_fault ();

  return portloc;
}

#include <hurd/sigpreempt.h>
#include <intr-msg.h>

/* Timeout on interrupt_operation calls.  */
mach_msg_timeout_t _hurdsig_interrupt_timeout = 1000;

/* SS->thread is suspended.

   Abort any interruptible RPC operation the thread is doing.

   This uses only the constant member SS->thread and the unlocked, atomically
   set member SS->intr_port, so no locking is needed.

   If successfully sent an interrupt_operation and therefore the thread should
   wait for its pending RPC to return (possibly EINTR) before taking the
   incoming signal, returns the reply port to be received on.  Otherwise
   returns MACH_PORT_NULL.

   SIGNO is used to find the applicable SA_RESTART bit.  If SIGNO is zero,
   the RPC fails with EINTR instead of restarting (thread_cancel).

   *STATE_CHANGE is set nonzero if STATE->basic was modified and should
   be applied back to the thread if it might ever run again, else zero.  */

mach_port_t
_hurdsig_abort_rpcs (struct hurd_sigstate *ss, int signo, int sigthread,
		     struct machine_thread_all_state *state, int *state_change,
		     void (*reply) (void))
{
  extern const void _hurd_intr_rpc_msg_in_trap;
  mach_port_t rcv_port = MACH_PORT_NULL;
  mach_port_t intr_port;

  *state_change = 0;

  intr_port = ss->intr_port;
  if (intr_port == MACH_PORT_NULL)
    /* No interruption needs done.  */
    return MACH_PORT_NULL;

  /* Abort the thread's kernel context, so any pending message send or
     receive completes immediately or aborts.  */
  abort_thread (ss, state, reply);

  if (state->basic.PC < (natural_t) &_hurd_intr_rpc_msg_in_trap)
    {
      /* The thread is about to do the RPC, but hasn't yet entered
	 mach_msg.  Mutate the thread's state so it knows not to try
	 the RPC.  */
      INTR_MSG_BACK_OUT (&state->basic);
      MACHINE_THREAD_STATE_SET_PC (&state->basic,
				   &_hurd_intr_rpc_msg_in_trap);
      state->basic.SYSRETURN = MACH_SEND_INTERRUPTED;
      *state_change = 1;
    }
  else if (state->basic.PC == (natural_t) &_hurd_intr_rpc_msg_in_trap &&
	   /* The thread was blocked in the system call.  After thread_abort,
	      the return value register indicates what state the RPC was in
	      when interrupted.  */
	   state->basic.SYSRETURN == MACH_RCV_INTERRUPTED)
      {
	/* The RPC request message was sent and the thread was waiting for
	   the reply message; now the message receive has been aborted, so
	   the mach_msg call will return MACH_RCV_INTERRUPTED.  We must tell
	   the server to interrupt the pending operation.  The thread must
	   wait for the reply message before running the signal handler (to
	   guarantee that the operation has finished being interrupted), so
	   our nonzero return tells the trampoline code to finish the message
	   receive operation before running the handler.  */

	mach_port_t *reply = interrupted_reply_port_location (state,
							      sigthread);
	error_t err = __interrupt_operation (intr_port, _hurdsig_interrupt_timeout);

	if (err)
	  {
	    if (reply)
	      {
		/* The interrupt didn't work.
		   Destroy the receive right the thread is blocked on.  */
		__mach_port_destroy (__mach_task_self (), *reply);
		*reply = MACH_PORT_NULL;
	      }

	    /* The system call return value register now contains
	       MACH_RCV_INTERRUPTED; when mach_msg resumes, it will retry the
	       call.  Since we have just destroyed the receive right, the
	       retry will fail with MACH_RCV_INVALID_NAME.  Instead, just
	       change the return value here to EINTR so mach_msg will not
	       retry and the EINTR error code will propagate up.  */
	    state->basic.SYSRETURN = EINTR;
	    *state_change = 1;
	  }
	else if (reply)
	  rcv_port = *reply;

	/* All threads whose RPCs were interrupted by the interrupt_operation
	   call above will retry their RPCs unless we clear SS->intr_port.
	   So we clear it for the thread taking a signal when SA_RESTART is
	   clear, so that its call returns EINTR.  */
	if (! signo || !(ss->actions[signo].sa_flags & SA_RESTART))
	  ss->intr_port = MACH_PORT_NULL;
      }

  return rcv_port;
}


/* Abort the RPCs being run by all threads but this one;
   all other threads should be suspended.  If LIVE is nonzero, those
   threads may run again, so they should be adjusted as necessary to be
   happy when resumed.  STATE is clobbered as a scratch area; its initial
   contents are ignored, and its contents on return are not useful.  */

static void
abort_all_rpcs (int signo, struct machine_thread_all_state *state, int live)
{
  /* We can just loop over the sigstates.  Any thread doing something
     interruptible must have one.  We needn't bother locking because all
     other threads are stopped.  */

  struct hurd_sigstate *ss;
  size_t nthreads;
  mach_port_t *reply_ports;

  /* First loop over the sigstates to count them.
     We need to know how big a vector we will need for REPLY_PORTS.  */
  nthreads = 0;
  for (ss = _hurd_sigstates; ss != NULL; ss = ss->next)
    ++nthreads;

  reply_ports = alloca (nthreads * sizeof *reply_ports);

  nthreads = 0;
  for (ss = _hurd_sigstates; ss != NULL; ss = ss->next, ++nthreads)
    if (ss->thread == _hurd_msgport_thread)
      reply_ports[nthreads] = MACH_PORT_NULL;
    else
      {
	int state_changed;
	state->set = 0;		/* Reset scratch area.  */

	/* Abort any operation in progress with interrupt_operation.
	   Record the reply port the thread is waiting on.
	   We will wait for all the replies below.  */
	reply_ports[nthreads] = _hurdsig_abort_rpcs (ss, signo, 1,
						     state, &state_changed,
						     NULL);
	if (live)
	  {
	    if (reply_ports[nthreads] != MACH_PORT_NULL)
	      {
		/* We will wait for the reply to this RPC below, so the
		   thread must issue a new RPC rather than waiting for the
		   reply to the one it sent.  */
		state->basic.SYSRETURN = EINTR;
		state_changed = 1;
	      }
	    if (state_changed)
	      /* Aborting the RPC needed to change this thread's state,
		 and it might ever run again.  So write back its state.  */
	      __thread_set_state (ss->thread, MACHINE_THREAD_STATE_FLAVOR,
				  (natural_t *) &state->basic,
				  MACHINE_THREAD_STATE_COUNT);
	  }
      }

  /* Wait for replies from all the successfully interrupted RPCs.  */
  while (nthreads-- > 0)
    if (reply_ports[nthreads] != MACH_PORT_NULL)
      {
	error_t err;
	mach_msg_header_t head;
	err = __mach_msg (&head, MACH_RCV_MSG|MACH_RCV_TIMEOUT, 0, sizeof head,
			  reply_ports[nthreads],
			  _hurd_interrupted_rpc_timeout, MACH_PORT_NULL);
	switch (err)
	  {
	  case MACH_RCV_TIMED_OUT:
	  case MACH_RCV_TOO_LARGE:
	    break;

	  default:
	    assert_perror (err);
	  }
      }
}

struct hurd_signal_preemptor *_hurdsig_preemptors = 0;
sigset_t _hurdsig_preempted_set;

/* XXX temporary to deal with spelling fix */
weak_alias (_hurdsig_preemptors, _hurdsig_preempters)

/* Mask of stop signals.  */
#define STOPSIGS (sigmask (SIGTTIN) | sigmask (SIGTTOU) | \
		  sigmask (SIGSTOP) | sigmask (SIGTSTP))

/* Deliver a signal.  SS is not locked.  */
void
_hurd_internal_post_signal (struct hurd_sigstate *ss,
			    int signo, struct hurd_signal_detail *detail,
			    mach_port_t reply_port,
			    mach_msg_type_name_t reply_port_type,
			    int untraced)
{
  error_t err;
  struct machine_thread_all_state thread_state;
  enum { stop, ignore, core, term, handle } act;
  sighandler_t handler;
  sigset_t pending;
  int ss_suspended;

  /* Reply to this sig_post message.  */
  __typeof (__msg_sig_post_reply) *reply_rpc
    = (untraced ? __msg_sig_post_untraced_reply : __msg_sig_post_reply);
  void reply (void)
    {
      error_t err;
      if (reply_port == MACH_PORT_NULL)
	return;
      err = (*reply_rpc) (reply_port, reply_port_type, 0);
      reply_port = MACH_PORT_NULL;
      if (err != MACH_SEND_INVALID_DEST) /* Ignore dead reply port.  */
	assert_perror (err);
    }

  /* Mark the signal as pending.  */
  void mark_pending (void)
    {
      __sigaddset (&ss->pending, signo);
      /* Save the details to be given to the handler when SIGNO is
	 unblocked.  */
      ss->pending_data[signo] = *detail;
    }

  /* Suspend the process with SIGNO.  */
  void suspend (void)
    {
      /* Stop all other threads and mark ourselves stopped.  */
      __USEPORT (PROC,
		 ({
		   /* Hold the siglock while stopping other threads to be
		      sure it is not held by another thread afterwards.  */
		   __mutex_lock (&_hurd_siglock);
		   __proc_dostop (port, _hurd_msgport_thread);
		   __mutex_unlock (&_hurd_siglock);
		   abort_all_rpcs (signo, &thread_state, 1);
		   reply ();
		   __proc_mark_stop (port, signo, detail->code);
		 }));
      _hurd_stopped = 1;
    }
  /* Resume the process after a suspension.  */
  void resume (void)
    {
      /* Resume the process from being stopped.  */
      thread_t *threads;
      mach_msg_type_number_t nthreads, i;
      error_t err;

      if (! _hurd_stopped)
	return;

      /* Tell the proc server we are continuing.  */
      __USEPORT (PROC, __proc_mark_cont (port));
      /* Fetch ports to all our threads and resume them.  */
      err = __task_threads (__mach_task_self (), &threads, &nthreads);
      assert_perror (err);
      for (i = 0; i < nthreads; ++i)
	{
	  if (threads[i] != _hurd_msgport_thread &&
	      (act != handle || threads[i] != ss->thread))
	    {
	      err = __thread_resume (threads[i]);
	      assert_perror (err);
	    }
	  err = __mach_port_deallocate (__mach_task_self (),
					threads[i]);
	  assert_perror (err);
	}
      __vm_deallocate (__mach_task_self (),
		       (vm_address_t) threads,
		       nthreads * sizeof *threads);
      _hurd_stopped = 0;
      if (act == handle)
	/* The thread that will run the handler is already suspended.  */
	ss_suspended = 1;
    }

  if (signo == 0)
    {
      if (untraced)
	/* This is PTRACE_CONTINUE.  */
	resume ();

      /* This call is just to check for pending signals.  */
      __spin_lock (&ss->lock);
      goto check_pending_signals;
    }

 post_signal:

  thread_state.set = 0;		/* We know nothing.  */

  __spin_lock (&ss->lock);

  /* Check for a preempted signal.  Preempted signals can arrive during
     critical sections.  */
  {
    inline sighandler_t try_preemptor (struct hurd_signal_preemptor *pe)
      {				/* PE cannot be null.  */
	do
	  {
	    if (HURD_PREEMPT_SIGNAL_P (pe, signo, detail->code))
	      {
		if (pe->preemptor)
		  {
		    sighandler_t handler = (*pe->preemptor) (pe, ss,
							     &signo, detail);
		    if (handler != SIG_ERR)
		      return handler;
		  }
		else
		  return pe->handler;
	      }
	    pe = pe->next;
	  } while (pe != 0);
	return SIG_ERR;
      }

    handler = ss->preemptors ? try_preemptor (ss->preemptors) : SIG_ERR;

    /* If no thread-specific preemptor, check for a global one.  */
    if (handler == SIG_ERR && __sigismember (&_hurdsig_preempted_set, signo))
      {
	__mutex_lock (&_hurd_siglock);
	handler = try_preemptor (_hurdsig_preemptors);
	__mutex_unlock (&_hurd_siglock);
      }
  }

  ss_suspended = 0;

  if (handler == SIG_IGN)
    /* Ignore the signal altogether.  */
    act = ignore;
  else if (handler != SIG_ERR)
    /* Run the preemption-provided handler.  */
    act = handle;
  else
    {
      /* No preemption.  Do normal handling.  */

      if (!untraced && __sigismember (&_hurdsig_traced, signo))
	{
	  /* We are being traced.  Stop to tell the debugger of the signal.  */
	  if (_hurd_stopped)
	    /* Already stopped.  Mark the signal as pending;
	       when resumed, we will notice it and stop again.  */
	    mark_pending ();
	  else
	    suspend ();
	  __spin_unlock (&ss->lock);
	  reply ();
	  return;
	}

      handler = ss->actions[signo].sa_handler;

      if (handler == SIG_DFL)
	/* Figure out the default action for this signal.  */
	switch (signo)
	  {
	  case 0:
	    /* A sig_post msg with SIGNO==0 is sent to
	       tell us to check for pending signals.  */
	    act = ignore;
	    break;

	  case SIGTTIN:
	  case SIGTTOU:
	  case SIGSTOP:
	  case SIGTSTP:
	    act = stop;
	    break;

	  case SIGCONT:
	  case SIGIO:
	  case SIGURG:
	  case SIGCHLD:
	  case SIGWINCH:
	    act = ignore;
	    break;

	  case SIGQUIT:
	  case SIGILL:
	  case SIGTRAP:
	  case SIGIOT:
	  case SIGEMT:
	  case SIGFPE:
	  case SIGBUS:
	  case SIGSEGV:
	  case SIGSYS:
	    act = core;
	    break;

	  case SIGINFO:
	    if (_hurd_pgrp == _hurd_pid)
	      {
		/* We are the process group leader.  Since there is no
		   user-specified handler for SIGINFO, we use a default one
		   which prints something interesting.  We use the normal
		   handler mechanism instead of just doing it here to avoid
		   the signal thread faulting or blocking in this
		   potentially hairy operation.  */
		act = handle;
		handler = _hurd_siginfo_handler;
	      }
	    else
	      act = ignore;
	    break;

	  default:
	    act = term;
	    break;
	  }
      else if (handler == SIG_IGN)
	act = ignore;
      else
	act = handle;

      if (__sigmask (signo) & STOPSIGS)
	/* Stop signals clear a pending SIGCONT even if they
	   are handled or ignored (but not if preempted).  */
	__sigdelset (&ss->pending, SIGCONT);
      else
	{
	  if (signo == SIGCONT)
	    /* Even if handled or ignored (but not preempted), SIGCONT clears
	       stop signals and resumes the process.  */
	    ss->pending &= ~STOPSIGS;

	  if (_hurd_stopped && act != stop && (untraced || signo == SIGCONT))
	    resume ();
	}
    }

  if (_hurd_orphaned && act == stop &&
      (__sigmask (signo) & (__sigmask (SIGTTIN) | __sigmask (SIGTTOU) |
			    __sigmask (SIGTSTP))))
    {
      /* If we would ordinarily stop for a job control signal, but we are
	 orphaned so noone would ever notice and continue us again, we just
	 quietly die, alone and in the dark.  */
      detail->code = signo;
      signo = SIGKILL;
      act = term;
    }

  /* Handle receipt of a blocked signal, or any signal while stopped.  */
  if (act != ignore &&		/* Signals ignored now are forgotten now.  */
      __sigismember (&ss->blocked, signo) ||
      (signo != SIGKILL && _hurd_stopped))
    {
      mark_pending ();
      act = ignore;
    }

  /* Perform the chosen action for the signal.  */
  switch (act)
    {
    case stop:
      if (_hurd_stopped)
	{
	  /* We are already stopped, but receiving an untraced stop
	     signal.  Instead of resuming and suspending again, just
	     notify the proc server of the new stop signal.  */
	  error_t err = __USEPORT (PROC, __proc_mark_stop
				   (port, signo, detail->code));
	  assert_perror (err);
	}
      else
	/* Suspend the process.  */
	suspend ();
      break;

    case ignore:
      if (detail->exc)
	/* Blocking or ignoring a machine exception is fatal.
	   Otherwise we could just spin on the faulting instruction.  */
	goto fatal;

      /* Nobody cares about this signal.  If there was a call to resume
	 above in SIGCONT processing and we've left a thread suspended,
	 now's the time to set it going. */
      if (ss_suspended)
	{
	  err = __thread_resume (ss->thread);
	  assert_perror (err);
	  ss_suspended = 0;
	}
      break;

    sigbomb:
      /* We got a fault setting up the stack frame for the handler.
	 Nothing to do but die; BSD gets SIGILL in this case.  */
      detail->code = signo;	/* XXX ? */
      signo = SIGILL;

    fatal:
      act = core;
      /* FALLTHROUGH */

    case term:			/* Time to die.  */
    case core:			/* And leave a rotting corpse.  */
      /* Have the proc server stop all other threads in our task.  */
      err = __USEPORT (PROC, __proc_dostop (port, _hurd_msgport_thread));
      assert_perror (err);
      /* No more user instructions will be executed.
	 The signal can now be considered delivered.  */
      reply ();
      /* Abort all server operations now in progress.  */
      abort_all_rpcs (signo, &thread_state, 0);

      {
	int status = W_EXITCODE (0, signo);
	/* Do a core dump if desired.  Only set the wait status bit saying we
	   in fact dumped core if the operation was actually successful.  */
	if (act == core && write_corefile (signo, detail))
	  status |= WCOREFLAG;
	/* Tell proc how we died and then stick the saber in the gut.  */
	_hurd_exit (status);
	/* NOTREACHED */
      }

    case handle:
      /* Call a handler for this signal.  */
      {
	struct sigcontext *scp, ocontext;
	int wait_for_reply, state_changed;

	/* Stop the thread and abort its pending RPC operations.  */
	if (! ss_suspended)
	  {
	    err = __thread_suspend (ss->thread);
	    assert_perror (err);
	  }

	/* Abort the thread's kernel context, so any pending message send
	   or receive completes immediately or aborts.  If an interruptible
	   RPC is in progress, abort_rpcs will do this.  But we must always
	   do it before fetching the thread's state, because
	   thread_get_state is never kosher before thread_abort.  */
	abort_thread (ss, &thread_state, NULL);

	if (ss->context)
	  {
	    /* We have a previous sigcontext that sigreturn was about
	       to restore when another signal arrived.  */

	    mach_port_t *loc;

	    if (_hurdsig_catch_memory_fault (ss->context))
	      {
		/* We faulted reading the thread's stack.  Forget that
		   context and pretend it wasn't there.  It almost
		   certainly crash if this handler returns, but that's it's
		   problem.  */
		ss->context = NULL;
	      }
	    else
	      {
		/* Copy the context from the thread's stack before
		   we start diddling the stack to set up the handler.  */
		ocontext = *ss->context;
		ss->context = &ocontext;
	      }
	    _hurdsig_end_catch_fault ();

	    if (! machine_get_basic_state (ss->thread, &thread_state))
	      goto sigbomb;
	    loc = interrupted_reply_port_location (&thread_state, 1);
	    if (loc && *loc != MACH_PORT_NULL)
	      /* This is the reply port for the context which called
		 sigreturn.  Since we are abandoning that context entirely
		 and restoring SS->context instead, destroy this port.  */
	      __mach_port_destroy (__mach_task_self (), *loc);

	    /* The thread was in sigreturn, not in any interruptible RPC.  */
	    wait_for_reply = 0;

	    assert (! __spin_lock_locked (&ss->critical_section_lock));
	  }
	else
	  {
	    int crit = __spin_lock_locked (&ss->critical_section_lock);

	    wait_for_reply
	      = (_hurdsig_abort_rpcs (ss,
				      /* In a critical section, any RPC
					 should be cancelled instead of
					 restarted, regardless of
					 SA_RESTART, so the entire
					 "atomic" operation can be aborted
					 as a unit.  */
				      crit ? 0 : signo, 1,
				      &thread_state, &state_changed,
				      &reply)
		 != MACH_PORT_NULL);

	    if (crit)
	      {
		/* The thread is in a critical section.  Mark the signal as
		   pending.  When it finishes the critical section, it will
		   check for pending signals.  */
		mark_pending ();
		if (state_changed)
		  /* Some cases of interrupting an RPC must change the
		     thread state to back out the call.  Normally this
		     change is rolled into the warping to the handler and
		     sigreturn, but we are not running the handler now
		     because the thread is in a critical section.  Instead,
		     mutate the thread right away for the RPC interruption
		     and resume it; the RPC will return early so the
		     critical section can end soon.  */
		  __thread_set_state (ss->thread, MACHINE_THREAD_STATE_FLAVOR,
				      (natural_t *) &thread_state.basic,
				      MACHINE_THREAD_STATE_COUNT);
		/* */
		ss->intr_port = MACH_PORT_NULL;
		__thread_resume (ss->thread);
		break;
	      }
	  }

	/* Call the machine-dependent function to set the thread up
	   to run the signal handler, and preserve its old context.  */
	scp = _hurd_setup_sighandler (ss, handler, signo, detail,
				      wait_for_reply, &thread_state);
	if (scp == NULL)
	  goto sigbomb;

	/* Set the machine-independent parts of the signal context.  */

	{
	  /* Fetch the thread variable for the MiG reply port,
	     and set it to MACH_PORT_NULL.  */
	  mach_port_t *loc = interrupted_reply_port_location (&thread_state,
							      1);
	  if (loc)
	    {
	      scp->sc_reply_port = *loc;
	      *loc = MACH_PORT_NULL;
	    }
	  else
	    scp->sc_reply_port = MACH_PORT_NULL;

	  /* Save the intr_port in use by the interrupted code,
	     and clear the cell before running the trampoline.  */
	  scp->sc_intr_port = ss->intr_port;
	  ss->intr_port = MACH_PORT_NULL;

	  if (ss->context)
	    {
	      /* After the handler runs we will restore to the state in
		 SS->context, not the state of the thread now.  So restore
		 that context's reply port and intr port.  */

	      scp->sc_reply_port = ss->context->sc_reply_port;
	      scp->sc_intr_port = ss->context->sc_intr_port;

	      ss->context = NULL;
	    }
	}

	/* Backdoor extra argument to signal handler.  */
	scp->sc_error = detail->error;

	/* Block requested signals while running the handler.  */
	scp->sc_mask = ss->blocked;
	__sigorset (&ss->blocked, &ss->blocked, &ss->actions[signo].sa_mask);

	/* Also block SIGNO unless we're asked not to.  */
	if (! (ss->actions[signo].sa_flags & (SA_RESETHAND | SA_NODEFER)))
	  __sigaddset (&ss->blocked, signo);

	/* Reset to SIG_DFL if requested.  SIGILL and SIGTRAP cannot
           be automatically reset when delivered; the system silently
           enforces this restriction.  */
	if (ss->actions[signo].sa_flags & SA_RESETHAND
	    && signo != SIGILL && signo != SIGTRAP)
	  ss->actions[signo].sa_handler = SIG_DFL;

	/* Start the thread running the handler (or possibly waiting for an
	   RPC reply before running the handler).  */
	err = __thread_set_state (ss->thread, MACHINE_THREAD_STATE_FLAVOR,
				  (natural_t *) &thread_state.basic,
				  MACHINE_THREAD_STATE_COUNT);
	assert_perror (err);
	err = __thread_resume (ss->thread);
	assert_perror (err);
	thread_state.set = 0;	/* Everything we know is now wrong.  */
	break;
      }
    }

  /* The signal has either been ignored or is now being handled.  We can
     consider it delivered and reply to the killer.  */
  reply ();

  /* We get here unless the signal was fatal.  We still hold SS->lock.
     Check for pending signals, and loop to post them.  */
  {
    /* Return nonzero if SS has any signals pending we should worry about.
       We don't worry about any pending signals if we are stopped, nor if
       SS is in a critical section.  We are guaranteed to get a sig_post
       message before any of them become deliverable: either the SIGCONT
       signal, or a sig_post with SIGNO==0 as an explicit poll when the
       thread finishes its critical section.  */
    inline int signals_pending (void)
      {
	if (_hurd_stopped || __spin_lock_locked (&ss->critical_section_lock))
	  return 0;
	return pending = ss->pending & ~ss->blocked;
      }

  check_pending_signals:
    untraced = 0;

    if (signals_pending ())
      {
	for (signo = 1; signo < NSIG; ++signo)
	  if (__sigismember (&pending, signo))
	    {
	    deliver_pending:
	      __sigdelset (&ss->pending, signo);
	      *detail = ss->pending_data[signo];
	      __spin_unlock (&ss->lock);
	      goto post_signal;
	    }
      }

    /* No pending signals left undelivered for this thread.
       If we were sent signal 0, we need to check for pending
       signals for all threads.  */
    if (signo == 0)
      {
	__spin_unlock (&ss->lock);
	__mutex_lock (&_hurd_siglock);
	for (ss = _hurd_sigstates; ss != NULL; ss = ss->next)
	  {
	    __spin_lock (&ss->lock);
	    for (signo = 1; signo < NSIG; ++signo)
	      if (__sigismember (&ss->pending, signo)
		  && (!__sigismember (&ss->blocked, signo)
		      /* We "deliver" immediately pending blocked signals whose
			 action might be to ignore, so that if ignored they are
			 dropped right away.  */
		      || ss->actions[signo].sa_handler == SIG_IGN
		      || ss->actions[signo].sa_handler == SIG_DFL))
		{
		  mutex_unlock (&_hurd_siglock);
		  goto deliver_pending;
		}
	    __spin_unlock (&ss->lock);
	  }
	__mutex_unlock (&_hurd_siglock);
      }
    else
      {
	/* No more signals pending; SS->lock is still locked.
	   Wake up any sigsuspend call that is blocking SS->thread.  */
	if (ss->suspended != MACH_PORT_NULL)
	  {
	    /* There is a sigsuspend waiting.  Tell it to wake up.  */
	    error_t err;
	    mach_msg_header_t msg;
	    msg.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_MAKE_SEND, 0);
	    msg.msgh_remote_port = ss->suspended;
	    msg.msgh_local_port = MACH_PORT_NULL;
	    /* These values do not matter.  */
	    msg.msgh_id = 8675309; /* Jenny, Jenny.  */
	    ss->suspended = MACH_PORT_NULL;
	    err = __mach_msg (&msg, MACH_SEND_MSG, sizeof msg, 0,
			      MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE,
			      MACH_PORT_NULL);
	    assert_perror (err);
	  }
	__spin_unlock (&ss->lock);
      }
  }

  /* All pending signals delivered to all threads.
     Now we can send the reply message even for signal 0.  */
  reply ();
}

/* Decide whether REFPORT enables the sender to send us a SIGNO signal.
   Returns zero if so, otherwise the error code to return to the sender.  */

static error_t
signal_allowed (int signo, mach_port_t refport)
{
  if (signo < 0 || signo >= NSIG)
    return EINVAL;

  if (refport == __mach_task_self ())
    /* Can send any signal.  */
    goto win;

  /* Avoid needing to check for this below.  */
  if (refport == MACH_PORT_NULL)
    return EPERM;

  switch (signo)
    {
    case SIGINT:
    case SIGQUIT:
    case SIGTSTP:
    case SIGHUP:
    case SIGINFO:
    case SIGTTIN:
    case SIGTTOU:
    case SIGWINCH:
      /* Job control signals can be sent by the controlling terminal.  */
      if (__USEPORT (CTTYID, port == refport))
	goto win;
      break;

    case SIGCONT:
      {
	/* A continue signal can be sent by anyone in the session.  */
	mach_port_t sessport;
	if (! __USEPORT (PROC, __proc_getsidport (port, &sessport)))
	  {
	    __mach_port_deallocate (__mach_task_self (), sessport);
	    if (refport == sessport)
	      goto win;
	  }
      }
      break;

    case SIGIO:
    case SIGURG:
      {
	/* Any io object a file descriptor refers to might send us
	   one of these signals using its async ID port for REFPORT.

	   This is pretty wide open; it is not unlikely that some random
	   process can at least open for reading something we have open,
	   get its async ID port, and send us a spurious SIGIO or SIGURG
	   signal.  But BSD is actually wider open than that!--you can set
	   the owner of an io object to any process or process group
	   whatsoever and send them gratuitous signals.

	   Someday we could implement some reasonable scheme for
	   authorizing SIGIO and SIGURG signals properly.  */

	int d;
	int lucky = 0;		/* True if we find a match for REFPORT.  */
	__mutex_lock (&_hurd_dtable_lock);
	for (d = 0; !lucky && (unsigned) d < (unsigned) _hurd_dtablesize; ++d)
	  {
	    struct hurd_userlink ulink;
	    io_t port;
	    mach_port_t asyncid;
	    if (_hurd_dtable[d] == NULL)
	      continue;
	    port = _hurd_port_get (&_hurd_dtable[d]->port, &ulink);
	    if (! __io_get_icky_async_id (port, &asyncid))
	      {
		if (refport == asyncid)
		  /* Break out of the loop on the next iteration.  */
		  lucky = 1;
		__mach_port_deallocate (__mach_task_self (), asyncid);
	      }
	    _hurd_port_free (&_hurd_dtable[d]->port, &ulink, port);
	  }
	__mutex_unlock (&_hurd_dtable_lock);
	/* If we found a lucky winner, we've set D to -1 in the loop.  */
	if (lucky)
	  goto win;
      }
    }

  /* If this signal is legit, we have done `goto win' by now.
     When we return the error, mig deallocates REFPORT.  */
  return EPERM;

 win:
  /* Deallocate the REFPORT send right; we are done with it.  */
  __mach_port_deallocate (__mach_task_self (), refport);

  return 0;
}

/* Implement the sig_post RPC from <hurd/msg.defs>;
   sent when someone wants us to get a signal.  */
kern_return_t
_S_msg_sig_post (mach_port_t me,
		 mach_port_t reply_port, mach_msg_type_name_t reply_port_type,
		 int signo, natural_t sigcode,
		 mach_port_t refport)
{
  error_t err;
  struct hurd_signal_detail d;

  if (err = signal_allowed (signo, refport))
    return err;

  d.code = sigcode;
  d.exc = 0;

  /* Post the signal to the designated signal-receiving thread.  This will
     reply when the signal can be considered delivered.  */
  _hurd_internal_post_signal (_hurd_thread_sigstate (_hurd_sigthread),
			      signo, &d, reply_port, reply_port_type,
			      0); /* Stop if traced.  */

  return MIG_NO_REPLY;		/* Already replied.  */
}

/* Implement the sig_post_untraced RPC from <hurd/msg.defs>;
   sent when the debugger wants us to really get a signal
   even if we are traced.  */
kern_return_t
_S_msg_sig_post_untraced (mach_port_t me,
			  mach_port_t reply_port,
			  mach_msg_type_name_t reply_port_type,
			  int signo, natural_t sigcode,
			  mach_port_t refport)
{
  error_t err;
  struct hurd_signal_detail d;

  if (err = signal_allowed (signo, refport))
    return err;

  d.code = sigcode;
  d.exc = 0;

  /* Post the signal to the designated signal-receiving thread.  This will
     reply when the signal can be considered delivered.  */
  _hurd_internal_post_signal (_hurd_thread_sigstate (_hurd_sigthread),
			      signo, &d, reply_port, reply_port_type,
			      1); /* Untraced flag. */

  return MIG_NO_REPLY;		/* Already replied.  */
}

extern void __mig_init (void *);

#include <mach/task_special_ports.h>

/* Initialize the message port and _hurd_sigthread and start the signal
   thread.  */

void
_hurdsig_init (const int *intarray, size_t intarraysize)
{
  error_t err;
  vm_size_t stacksize;
  struct hurd_sigstate *ss;

  __mutex_init (&_hurd_siglock);

  err = __mach_port_allocate (__mach_task_self (),
			      MACH_PORT_RIGHT_RECEIVE,
			      &_hurd_msgport);
  assert_perror (err);

  /* Make a send right to the signal port.  */
  err = __mach_port_insert_right (__mach_task_self (),
				  _hurd_msgport,
				  _hurd_msgport,
				  MACH_MSG_TYPE_MAKE_SEND);
  assert_perror (err);

  /* Initialize the main thread's signal state.  */
  ss = _hurd_self_sigstate ();

  /* Copy inherited values from our parent (or pre-exec process state)
     into the signal settings of the main thread.  */
  if (intarraysize > INIT_SIGMASK)
    ss->blocked = intarray[INIT_SIGMASK];
  if (intarraysize > INIT_SIGPENDING)
    ss->pending = intarray[INIT_SIGPENDING];
  if (intarraysize > INIT_SIGIGN && intarray[INIT_SIGIGN] != 0)
    {
      int signo;
      for (signo = 1; signo < NSIG; ++signo)
	if (intarray[INIT_SIGIGN] & __sigmask(signo))
	  ss->actions[signo].sa_handler = SIG_IGN;
    }

  /* Set the default thread to receive task-global signals
     to this one, the main (first) user thread.  */
  _hurd_sigthread = ss->thread;

  /* Start the signal thread listening on the message port.  */

  if (__hurd_threadvar_stack_mask == 0)
    {
      err = __thread_create (__mach_task_self (), &_hurd_msgport_thread);
      assert_perror (err);

      stacksize = __vm_page_size * 8; /* Small stack for signal thread.  */
      err = __mach_setup_thread (__mach_task_self (), _hurd_msgport_thread,
				 _hurd_msgport_receive,
				 (vm_address_t *) &__hurd_sigthread_stack_base,
				 &stacksize);
      assert_perror (err);

      __hurd_sigthread_stack_end = __hurd_sigthread_stack_base + stacksize;
      __hurd_sigthread_variables =
	malloc (__hurd_threadvar_max * sizeof (unsigned long int));
      if (__hurd_sigthread_variables == NULL)
	__libc_fatal ("hurd: Can't allocate threadvars for signal thread\n");
      memset (__hurd_sigthread_variables, 0,
	      __hurd_threadvar_max * sizeof (unsigned long int));
      __hurd_sigthread_variables[_HURD_THREADVAR_LOCALE]
	= (unsigned long int) &_nl_global_locale;

      /* Reinitialize the MiG support routines so they will use a per-thread
	 variable for the cached reply port.  */
      __mig_init ((void *) __hurd_sigthread_stack_base);

      err = __thread_resume (_hurd_msgport_thread);
      assert_perror (err);
    }
  else
    {
      /* When cthreads is being used, we need to make the signal thread a
         proper cthread.  Otherwise it cannot use mutex_lock et al, which
         will be the cthreads versions.  Various of the message port RPC
         handlers need to take locks, so we need to be able to call into
         cthreads code and meet its assumptions about how our thread and
         its stack are arranged.  Since cthreads puts it there anyway,
         we'll let the signal thread's per-thread variables be found as for
         any normal cthread, and just leave the magic __hurd_sigthread_*
         values all zero so they'll be ignored.  */
#pragma weak cthread_fork
#pragma weak cthread_detach
      cthread_detach (cthread_fork ((cthread_fn_t) &_hurd_msgport_receive, 0));

      /* XXX We need the thread port for the signal thread further on
         in this thread (see hurdfault.c:_hurdsigfault_init).
         Therefore we block until _hurd_msgport_thread is initialized
         by the newly created thread.  This really shouldn't be
         necessary; we should be able to fetch the thread port for a
         cthread from here.  */
      while (_hurd_msgport_thread == 0)
	__swtch_pri (0);
    }

  /* Receive exceptions on the signal port.  */
#ifdef TASK_EXCEPTION_PORT
  __task_set_special_port (__mach_task_self (),
			   TASK_EXCEPTION_PORT, _hurd_msgport);
#elif defined (EXC_MASK_ALL)
  __task_set_exception_ports (__mach_task_self (),
			      EXC_MASK_ALL & ~(EXC_MASK_SYSCALL
					       | EXC_MASK_MACH_SYSCALL
					       | EXC_MASK_RPC_ALERT),
			      _hurd_msgport,
			      EXCEPTION_DEFAULT, MACHINE_THREAD_STATE);
#else
# error task_set_exception_port?
#endif

  /* Sanity check.  Any pending, unblocked signals should have been
     taken by our predecessor incarnation (i.e. parent or pre-exec state)
     before packing up our init ints.  This assert is last (not above)
     so that signal handling is all set up to handle the abort.  */
  assert ((ss->pending &~ ss->blocked) == 0);
}
				/* XXXX */
/* Reauthenticate with the proc server.  */

static void
reauth_proc (mach_port_t new)
{
  mach_port_t ref, ignore;

  ref = __mach_reply_port ();
  if (! HURD_PORT_USE (&_hurd_ports[INIT_PORT_PROC],
		       __proc_reauthenticate (port, ref,
					      MACH_MSG_TYPE_MAKE_SEND) ||
		       __auth_user_authenticate (new, ref,
						 MACH_MSG_TYPE_MAKE_SEND,
						 &ignore))
      && ignore != MACH_PORT_NULL)
    __mach_port_deallocate (__mach_task_self (), ignore);
  __mach_port_destroy (__mach_task_self (), ref);

  /* Set the owner of the process here too. */
  mutex_lock (&_hurd_id.lock);
  if (!_hurd_check_ids ())
    HURD_PORT_USE (&_hurd_ports[INIT_PORT_PROC],
		   __proc_setowner (port,
				    (_hurd_id.gen.nuids
				     ? _hurd_id.gen.uids[0] : 0),
				    !_hurd_id.gen.nuids));
  mutex_unlock (&_hurd_id.lock);

  (void) &reauth_proc;		/* Silence compiler warning.  */
}
text_set_element (_hurd_reauth_hook, reauth_proc);

/* Like `getenv', but safe for the signal thread to run.
   If the environment is trashed, this will just return NULL.  */

const char *
_hurdsig_getenv (const char *variable)
{
  if (__libc_enable_secure)
    return NULL;

  if (_hurdsig_catch_memory_fault (__environ))
    /* We bombed in getenv.  */
    return NULL;
  else
    {
      const size_t len = strlen (variable);
      char *value = NULL;
      char *volatile *ep = __environ;
      while (*ep)
	{
	  const char *p = *ep;
	  _hurdsig_fault_preemptor.first = (long int) p;
	  _hurdsig_fault_preemptor.last = VM_MAX_ADDRESS;
	  if (! strncmp (p, variable, len) && p[len] == '=')
	    {
	      size_t valuelen;
	      p += len + 1;
	      valuelen = strlen (p);
	      _hurdsig_fault_preemptor.last = (long int) (p + valuelen);
	      value = malloc (++valuelen);
	      if (value)
		memcpy (value, p, valuelen);
	      break;
	    }
	  _hurdsig_fault_preemptor.first = (long int) ++ep;
	  _hurdsig_fault_preemptor.last = (long int) (ep + 1);
	}
      _hurdsig_end_catch_fault ();
      return value;
    }
}
