Annotation of prex/usr/server/proc/kill.c, Revision 1.1.1.1
1.1 nbrk 1: /*
2: * Copyright (c) 2005-2006, Kohsuke Ohtani
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: * 3. Neither the name of the author nor the names of any co-contributors
14: * may be used to endorse or promote products derived from this software
15: * without specific prior written permission.
16: *
17: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27: * SUCH DAMAGE.
28: */
29:
30: /*
31: * kill.c - signal transfer.
32: */
33:
34: #include <prex/prex.h>
35: #include <prex/capability.h>
36: #include <server/proc.h>
37: #include <sys/list.h>
38:
39: #include <unistd.h>
40: #include <errno.h>
41:
42: #include "proc.h"
43:
44: /*
45: * Send a signal to the process.
46: */
47: static int
48: send_sig(struct proc *p, int sig)
49: {
50:
51: if (p->p_pid == 0 || p->p_pid == 1)
52: return EPERM;
53:
54: DPRINTF(("proc: send_sig task=%x\n", p->p_task));
55: return exception_raise(p->p_task, sig);
56: }
57:
58: /*
59: * Send a signal to one process.
60: */
61: static int
62: kill_one(pid_t pid, int sig)
63: {
64: struct proc *p;
65:
66: DPRINTF(("proc: killone pid=%d sig=%d\n", pid, sig));
67:
68: if ((p = proc_find(pid)) == NULL)
69: return ESRCH;
70: return send_sig(p, sig);
71: }
72:
73: /*
74: * Send a signal to all process in the process group.
75: */
76: int
77: kill_pg(pid_t pgid, int sig)
78: {
79: struct proc *p;
80: struct pgrp *pgrp;
81: list_t head, n;
82: int err = 0;
83:
84: DPRINTF(("proc: killpg pgid=%d sig=%d\n", pgid, sig));
85:
86: if ((pgrp = pgrp_find(pgid)) == NULL)
87: return ESRCH;
88:
89: head = &pgrp->pg_members;
90: for (n = list_first(head); n != head; n = list_next(n)) {
91: p = list_entry(n, struct proc, p_link);
92: if ((err = send_sig(p, sig)) != 0)
93: break;
94: }
95: return err;
96: }
97:
98: /*
99: * Send a signal.
100: *
101: * The behavior is different for the pid value.
102: *
103: * if (pid > 0)
104: * Send a signal to specific process.
105: *
106: * if (pid == 0)
107: * Send a signal to all processes in same process group.
108: *
109: * if (pid == -1)
110: * Send a signal to all processes except init.
111: *
112: * if (pid < -1)
113: * Send a signal to the process group.
114: *
115: * Note: Need CAP_KILL capability to send a signal to the different
116: * process/group.
117: */
118: int
119: proc_kill(struct msg *msg)
120: {
121: pid_t pid;
122: struct proc *p;
123: list_t n;
124: int sig, capable = 0;
125: int err = 0;
126:
127: pid = (pid_t)msg->data[0];
128: sig = msg->data[1];
129:
130: DPRINTF(("proc: kill pid=%d sig=%d\n", pid, sig));
131:
132: switch (sig) {
133: case SIGFPE:
134: case SIGILL:
135: case SIGSEGV:
136: return EINVAL;
137: }
138:
139: if (curproc->p_cap & CAP_KILL)
140: capable = 1;
141:
142: if (pid > 0) {
143: if (pid != curproc->p_pid && !capable)
144: return EPERM;
145: err = kill_one(pid, sig);
146: }
147: else if (pid == -1) {
148: if (!capable)
149: return EPERM;
150: for (n = list_first(&allproc); n != &allproc;
151: n = list_next(n)) {
152: p = list_entry(n, struct proc, p_link);
153: if (p->p_pid != 0 && p->p_pid != 1) {
154: err = kill_one(p->p_pid, sig);
155: if (err != 0)
156: break;
157: }
158: }
159: }
160: else if (pid == 0) {
161: if ((p = proc_find(pid)) == NULL)
162: return ESRCH;
163: err = kill_pg(p->p_pgrp->pg_pgid, sig);
164: }
165: else {
166: if (curproc->p_pgrp->pg_pgid != -pid && !capable)
167: return EPERM;
168: err = kill_pg(-pid, sig);
169: }
170: return err;
171: }
CVSweb