Back to index

glibc  2.9
kill.c
Go to the documentation of this file.
00001 /* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003 
00004    The GNU C Library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Lesser General Public
00006    License as published by the Free Software Foundation; either
00007    version 2.1 of the License, or (at your option) any later version.
00008 
00009    The GNU C Library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Lesser General Public License for more details.
00013 
00014    You should have received a copy of the GNU Lesser General Public
00015    License along with the GNU C Library; if not, write to the Free
00016    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00017    02111-1307 USA.  */
00018 
00019 #include <errno.h>
00020 #include <sys/types.h>
00021 #include <signal.h>
00022 #include <hurd.h>
00023 #include <hurd/port.h>
00024 #include <hurd/signal.h>
00025 #include <hurd/msg.h>
00026 
00027 /* Send signal SIG to process number PID.  If PID is zero,
00028    send SIG to all processes in the current process's process group.
00029    If PID is < -1, send SIG to all processes in process group - PID.  */
00030 int
00031 __kill (pid_t pid, int sig)
00032 {
00033   int delivered = 0;        /* Set when we deliver any signal.  */
00034   error_t err;
00035   mach_port_t proc;
00036   struct hurd_userlink ulink;
00037 
00038   void kill_pid (pid_t pid) /* Kill one PID.  */
00039     {
00040       /* SIGKILL is not delivered as a normal signal.
00041         Sending SIGKILL to a process means to terminate its task.  */
00042       if (sig == SIGKILL)
00043        /* Fetch the process's task port and terminate the task.  We
00044           loop in case the process execs and changes its task port.
00045           If the old task port dies after we fetch it but before we
00046           send the RPC, we get MACH_SEND_INVALID_DEST; if it dies
00047           after we send the RPC request but before it is serviced, we
00048           get MIG_SERVER_DIED.  */
00049        do
00050          {
00051            task_t refport;
00052            err = __proc_pid2task (proc, pid, &refport);
00053            /* Ignore zombies.  */
00054            if (!err && refport != MACH_PORT_NULL)
00055              {
00056               err = __task_terminate (refport);
00057               __mach_port_deallocate (__mach_task_self (), refport);
00058              }
00059          } while (err == MACH_SEND_INVALID_DEST ||
00060                  err == MIG_SERVER_DIED);
00061       else
00062        {
00063          error_t taskerr;
00064          error_t kill_port (mach_port_t msgport, mach_port_t refport)
00065            {
00066              if (msgport != MACH_PORT_NULL)
00067               /* Send a signal message to his message port.  */
00068               return __msg_sig_post (msgport, sig, 0, refport);
00069 
00070              /* The process has no message port.  Perhaps try direct
00071                frobnication of the task.  */
00072 
00073              if (taskerr)
00074               /* If we could not get the task port, we can do nothing.  */
00075               return taskerr;
00076 
00077              if (refport == MACH_PORT_NULL)
00078               /* proc_pid2task returned success with a null task port.
00079                  That means the process is a zombie.  Signals
00080                  to zombies should return success and do nothing.  */
00081               return 0;
00082 
00083              /* For user convenience in the case of a task that has
00084                not registered any message port with the proc server,
00085                translate a few signals to direct task operations.  */
00086              switch (sig)
00087               {
00088                 /* The only signals that really make sense for an
00089                    unregistered task are kill, suspend, and continue.  */
00090               case SIGSTOP:
00091               case SIGTSTP:
00092                 return __task_suspend (refport);
00093               case SIGCONT:
00094                 return __task_resume (refport);
00095               case SIGTERM:
00096               case SIGQUIT:
00097               case SIGINT:
00098                 return __task_terminate (refport);
00099               default:
00100                 /* We have full permission to send signals, but there is
00101                    no meaningful way to express this signal.  */
00102                 return EPERM;
00103               }
00104            }
00105          err = HURD_MSGPORT_RPC (__proc_getmsgport (proc, pid, &msgport),
00106                               (taskerr = __proc_pid2task (proc, pid,
00107                                                        &refport)) ?
00108                               __proc_getsidport (proc, &refport) : 0, 1,
00109                               kill_port (msgport, refport));
00110        }
00111       if (! err)
00112        delivered = 1;
00113     }
00114 
00115   proc = _hurd_port_get (&_hurd_ports[INIT_PORT_PROC], &ulink);
00116 
00117   if (pid <= 0)
00118     {
00119       /* Send SIG to each process in pgrp (- PID).  */
00120       pid_t pidbuf[10], *pids = pidbuf;
00121       mach_msg_type_number_t i, npids = sizeof (pidbuf) / sizeof (pidbuf[0]);
00122 
00123       err = __proc_getpgrppids (proc, - pid, &pids, &npids);
00124       if (!err)
00125        {
00126          for (i = 0; i < npids; ++i)
00127            {
00128              kill_pid (pids[i]);
00129              if (err == ESRCH)
00130               /* The process died already.  Ignore it.  */
00131               err = 0;
00132            }
00133          if (pids != pidbuf)
00134            __vm_deallocate (__mach_task_self (),
00135                           (vm_address_t) pids, npids * sizeof (pids[0]));
00136        }
00137     }
00138   else
00139     kill_pid (pid);
00140 
00141   _hurd_port_free (&_hurd_ports[INIT_PORT_PROC], &ulink, proc);
00142 
00143   /* If we delivered no signals, but ERR is clear, this must mean that
00144      every kill_pid call failed with ESRCH, meaning all the processes in
00145      the pgrp died between proc_getpgrppids and kill_pid; in that case we
00146      fail with ESRCH.  */
00147   return delivered ? 0 : __hurd_fail (err ?: ESRCH);
00148 }
00149 
00150 weak_alias (__kill, kill)