Back to index

glibc  2.9
hurdkill.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 a `sig_post' RPC to process number PID.  If PID is zero,
00028    send the message 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    SIG and REFPORT are passed along in the request message.  */
00031 error_t
00032 _hurd_sig_post (pid_t pid, int sig, mach_port_t arg_refport)
00033 {
00034   int delivered = 0;        /* Set when we deliver any signal.  */
00035   error_t err;
00036   mach_port_t proc;
00037   struct hurd_userlink ulink;
00038 
00039   inline void kill_pid (pid_t pid) /* Kill one PID.  */
00040     {
00041       err = HURD_MSGPORT_RPC (__proc_getmsgport (proc, pid, &msgport),
00042                            (refport = arg_refport, 0), 0,
00043                            /* If no message port we cannot send signals.  */
00044                            msgport == MACH_PORT_NULL ? EPERM :
00045                            __msg_sig_post (msgport, sig, 0, refport));
00046       if (! err)
00047        delivered = 1;
00048     }
00049 
00050   proc = _hurd_port_get (&_hurd_ports[INIT_PORT_PROC], &ulink);
00051 
00052   if (pid <= 0)
00053     {
00054       /* Send SIG to each process in pgrp (- PID).  */
00055       mach_msg_type_number_t npids = 10, i;
00056       pid_t pidsbuf[10], *pids = pidsbuf;
00057 
00058       err = __proc_getpgrppids (proc, - pid, &pids, &npids);
00059       if (!err)
00060        {
00061          int self = 0;
00062          for (i = 0; i < npids; ++i)
00063            if (pids[i] == _hurd_pid)
00064              /* We must do ourselves last so we are not suspended
00065                and fail to suspend the other processes in the pgrp.  */
00066              self = 1;
00067            else
00068              {
00069               kill_pid (pids[i]);
00070               if (err == ESRCH)
00071                 /* The process died already.  Ignore it.  */
00072                 err = 0;
00073              }
00074          if (pids != pidsbuf)
00075            __vm_deallocate (__mach_task_self (),
00076                           (vm_address_t) pids, npids * sizeof (pids[0]));
00077 
00078          if (self)
00079            kill_pid (_hurd_pid);
00080        }
00081     }
00082   else
00083     kill_pid (pid);
00084 
00085   _hurd_port_free (&_hurd_ports[INIT_PORT_PROC], &ulink, proc);
00086 
00087   /* If we delivered no signals, but ERR is clear, this must mean that
00088      every kill_pid call failed with ESRCH, meaning all the processes in
00089      the pgrp died between proc_getpgrppids and kill_pid; in that case we
00090      fail with ESRCH.  */
00091   return delivered ? 0 : err ?: ESRCH;
00092 }
00093 weak_alias (_hurd_sig_post, hurd_sig_post)