/* Copyright (C) 1991-2014 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, see
   <http://www.gnu.org/licenses/>.  */

#include <errno.h>
#include <sys/types.h>
#include <signal.h>
#include <hurd.h>
#include <hurd/port.h>
#include <hurd/signal.h>
#include <hurd/msg.h>

/* Send signal SIG to process number PID.  If PID is zero,
   send SIG to all processes in the current process's process group.
   If PID is < -1, send SIG to all processes in process group - PID.  */
int
__kill (pid_t pid, int sig)
{
  int delivered = 0;		/* Set when we deliver any signal.  */
  error_t err;
  mach_port_t proc;
  struct hurd_userlink ulink;

  void kill_pid (pid_t pid) /* Kill one PID.  */
    {
      /* SIGKILL is not delivered as a normal signal.
	 Sending SIGKILL to a process means to terminate its task.  */
      if (sig == SIGKILL)
	/* Fetch the process's task port and terminate the task.  We
	   loop in case the process execs and changes its task port.
	   If the old task port dies after we fetch it but before we
	   send the RPC, we get MACH_SEND_INVALID_DEST; if it dies
	   after we send the RPC request but before it is serviced, we
	   get MIG_SERVER_DIED.  */
	do
	  {
	    task_t refport;
	    err = __proc_pid2task (proc, pid, &refport);
	    /* Ignore zombies.  */
	    if (!err && refport != MACH_PORT_NULL)
	      {
		err = __task_terminate (refport);
		__mach_port_deallocate (__mach_task_self (), refport);
	      }
	  } while (err == MACH_SEND_INVALID_DEST ||
		   err == MIG_SERVER_DIED);
      else
	{
	  error_t taskerr;
	  error_t kill_port (mach_port_t msgport, mach_port_t refport)
	    {
	      if (msgport != MACH_PORT_NULL)
		/* Send a signal message to his message port.  */
		return __msg_sig_post (msgport, sig, 0, refport);

	      /* The process has no message port.  Perhaps try direct
		 frobnication of the task.  */

	      if (taskerr)
		/* If we could not get the task port, we can do nothing.  */
		return taskerr;

	      if (refport == MACH_PORT_NULL)
		/* proc_pid2task returned success with a null task port.
		   That means the process is a zombie.  Signals
		   to zombies should return success and do nothing.  */
		return 0;

	      /* For user convenience in the case of a task that has
		 not registered any message port with the proc server,
		 translate a few signals to direct task operations.  */
	      switch (sig)
		{
		  /* The only signals that really make sense for an
		     unregistered task are kill, suspend, and continue.  */
		case SIGSTOP:
		case SIGTSTP:
		  return __task_suspend (refport);
		case SIGCONT:
		  return __task_resume (refport);
		case SIGTERM:
		case SIGQUIT:
		case SIGINT:
		  return __task_terminate (refport);
		default:
		  /* We have full permission to send signals, but there is
		     no meaningful way to express this signal.  */
		  return EPERM;
		}
	    }
	  err = HURD_MSGPORT_RPC (__proc_getmsgport (proc, pid, &msgport),
				  (taskerr = __proc_pid2task (proc, pid,
							      &refport)) ?
				  __proc_getsidport (proc, &refport) : 0, 1,
				  kill_port (msgport, refport));
	}
      if (! err)
	delivered = 1;
    }

  proc = _hurd_port_get (&_hurd_ports[INIT_PORT_PROC], &ulink);

  if (pid <= 0)
    {
      /* Send SIG to each process in pgrp (- PID).  */
      pid_t pidbuf[10], *pids = pidbuf;
      mach_msg_type_number_t i, npids = sizeof (pidbuf) / sizeof (pidbuf[0]);

      err = __proc_getpgrppids (proc, - pid, &pids, &npids);
      if (!err)
	{
	  for (i = 0; i < npids; ++i)
	    {
	      kill_pid (pids[i]);
	      if (err == ESRCH)
		/* The process died already.  Ignore it.  */
		err = 0;
	    }
	  if (pids != pidbuf)
	    __vm_deallocate (__mach_task_self (),
			     (vm_address_t) pids, npids * sizeof (pids[0]));
	}
    }
  else
    kill_pid (pid);

  _hurd_port_free (&_hurd_ports[INIT_PORT_PROC], &ulink, proc);

  /* If we delivered no signals, but ERR is clear, this must mean that
     every kill_pid call failed with ESRCH, meaning all the processes in
     the pgrp died between proc_getpgrppids and kill_pid; in that case we
     fail with ESRCH.  */
  return delivered ? 0 : __hurd_fail (err ?: ESRCH);
}

weak_alias (__kill, kill)
