]>
Commit | Line | Data |
---|---|---|
f7a9f785 | 1 | /* Copyright (C) 1991-2016 Free Software Foundation, Inc. |
c84142e8 | 2 | This file is part of the GNU C Library. |
28f540f4 | 3 | |
c84142e8 | 4 | The GNU C Library is free software; you can redistribute it and/or |
41bdb6e2 AJ |
5 | modify it under the terms of the GNU Lesser General Public |
6 | License as published by the Free Software Foundation; either | |
7 | version 2.1 of the License, or (at your option) any later version. | |
28f540f4 | 8 | |
c84142e8 UD |
9 | The GNU C Library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41bdb6e2 | 12 | Lesser General Public License for more details. |
28f540f4 | 13 | |
41bdb6e2 | 14 | You should have received a copy of the GNU Lesser General Public |
59ba27a6 PE |
15 | License along with the GNU C Library; if not, see |
16 | <http://www.gnu.org/licenses/>. */ | |
28f540f4 RM |
17 | |
18 | #include <errno.h> | |
19 | #include <sys/types.h> | |
20 | #include <signal.h> | |
21 | #include <hurd.h> | |
22 | #include <hurd/port.h> | |
23 | #include <hurd/signal.h> | |
24 | #include <hurd/msg.h> | |
25 | ||
26 | /* Send a `sig_post' RPC to process number PID. If PID is zero, | |
27 | send the message to all processes in the current process's process group. | |
28 | If PID is < -1, send SIG to all processes in process group - PID. | |
29 | SIG and REFPORT are passed along in the request message. */ | |
30 | error_t | |
31 | _hurd_sig_post (pid_t pid, int sig, mach_port_t arg_refport) | |
32 | { | |
33 | int delivered = 0; /* Set when we deliver any signal. */ | |
34 | error_t err; | |
35 | mach_port_t proc; | |
36 | struct hurd_userlink ulink; | |
37 | ||
38 | inline void kill_pid (pid_t pid) /* Kill one PID. */ | |
39 | { | |
40 | err = HURD_MSGPORT_RPC (__proc_getmsgport (proc, pid, &msgport), | |
41 | (refport = arg_refport, 0), 0, | |
42 | /* If no message port we cannot send signals. */ | |
43 | msgport == MACH_PORT_NULL ? EPERM : | |
8f0c527e | 44 | __msg_sig_post (msgport, sig, 0, refport)); |
28f540f4 RM |
45 | if (! err) |
46 | delivered = 1; | |
47 | } | |
48 | ||
49 | proc = _hurd_port_get (&_hurd_ports[INIT_PORT_PROC], &ulink); | |
50 | ||
51 | if (pid <= 0) | |
52 | { | |
53 | /* Send SIG to each process in pgrp (- PID). */ | |
54 | mach_msg_type_number_t npids = 10, i; | |
55 | pid_t pidsbuf[10], *pids = pidsbuf; | |
56 | ||
57 | err = __proc_getpgrppids (proc, - pid, &pids, &npids); | |
58 | if (!err) | |
59 | { | |
67f27f3a | 60 | int self = 0; |
28f540f4 | 61 | for (i = 0; i < npids; ++i) |
67f27f3a RM |
62 | if (pids[i] == _hurd_pid) |
63 | /* We must do ourselves last so we are not suspended | |
64 | and fail to suspend the other processes in the pgrp. */ | |
65 | self = 1; | |
66 | else | |
67 | { | |
68 | kill_pid (pids[i]); | |
69 | if (err == ESRCH) | |
70 | /* The process died already. Ignore it. */ | |
71 | err = 0; | |
72 | } | |
28f540f4 RM |
73 | if (pids != pidsbuf) |
74 | __vm_deallocate (__mach_task_self (), | |
75 | (vm_address_t) pids, npids * sizeof (pids[0])); | |
67f27f3a RM |
76 | |
77 | if (self) | |
78 | kill_pid (_hurd_pid); | |
28f540f4 RM |
79 | } |
80 | } | |
81 | else | |
82 | kill_pid (pid); | |
83 | ||
84 | _hurd_port_free (&_hurd_ports[INIT_PORT_PROC], &ulink, proc); | |
85 | ||
86 | /* If we delivered no signals, but ERR is clear, this must mean that | |
87 | every kill_pid call failed with ESRCH, meaning all the processes in | |
88 | the pgrp died between proc_getpgrppids and kill_pid; in that case we | |
89 | fail with ESRCH. */ | |
90 | return delivered ? 0 : err ?: ESRCH; | |
91 | } | |
92 | weak_alias (_hurd_sig_post, hurd_sig_post) |