diff options
Diffstat (limited to 'REORG.TODO/hurd/hurdkill.c')
-rw-r--r-- | REORG.TODO/hurd/hurdkill.c | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/REORG.TODO/hurd/hurdkill.c b/REORG.TODO/hurd/hurdkill.c new file mode 100644 index 0000000000..e8375d3d3d --- /dev/null +++ b/REORG.TODO/hurd/hurdkill.c @@ -0,0 +1,92 @@ +/* Copyright (C) 1991-2017 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 a `sig_post' RPC to process number PID. If PID is zero, + send the message to all processes in the current process's process group. + If PID is < -1, send SIG to all processes in process group - PID. + SIG and REFPORT are passed along in the request message. */ +error_t +_hurd_sig_post (pid_t pid, int sig, mach_port_t arg_refport) +{ + int delivered = 0; /* Set when we deliver any signal. */ + error_t err; + mach_port_t proc; + struct hurd_userlink ulink; + + inline void kill_pid (pid_t pid) /* Kill one PID. */ + { + err = HURD_MSGPORT_RPC (__proc_getmsgport (proc, pid, &msgport), + (refport = arg_refport, 0), 0, + /* If no message port we cannot send signals. */ + msgport == MACH_PORT_NULL ? EPERM : + __msg_sig_post (msgport, sig, 0, 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). */ + mach_msg_type_number_t npids = 10, i; + pid_t pidsbuf[10], *pids = pidsbuf; + + err = __proc_getpgrppids (proc, - pid, &pids, &npids); + if (!err) + { + int self = 0; + for (i = 0; i < npids; ++i) + if (pids[i] == _hurd_pid) + /* We must do ourselves last so we are not suspended + and fail to suspend the other processes in the pgrp. */ + self = 1; + else + { + kill_pid (pids[i]); + if (err == ESRCH) + /* The process died already. Ignore it. */ + err = 0; + } + if (pids != pidsbuf) + __vm_deallocate (__mach_task_self (), + (vm_address_t) pids, npids * sizeof (pids[0])); + + if (self) + kill_pid (_hurd_pid); + } + } + 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 : err ?: ESRCH; +} +weak_alias (_hurd_sig_post, hurd_sig_post) |