Annotation of prex-old/usr/server/proc/kill.c, Revision 1.1.1.1.2.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: /*
1.1.1.1.2.1! nbrk 45: * Send a signal to the process.
1.1 nbrk 46: */
47: static int
1.1.1.1.2.1! nbrk 48: send_sig(struct proc *p, int sig)
1.1 nbrk 49: {
50:
1.1.1.1.2.1! nbrk 51: if (p->p_pid == 0 || p->p_pid == 1)
1.1 nbrk 52: return EPERM;
1.1.1.1.2.1! nbrk 53:
! 54: DPRINTF(("proc: send_sig task=%x\n", p->p_task));
! 55: return exception_raise(p->p_task, sig);
1.1 nbrk 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:
1.1.1.1.2.1! nbrk 66: DPRINTF(("proc: killone pid=%d sig=%d\n", pid, sig));
! 67:
1.1 nbrk 68: if ((p = proc_find(pid)) == NULL)
69: return ESRCH;
70: return send_sig(p, sig);
71: }
72:
73: /*
1.1.1.1.2.1! nbrk 74: * Send a signal to all process in the process group.
1.1 nbrk 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:
1.1.1.1.2.1! nbrk 84: DPRINTF(("proc: killpg pgid=%d sig=%d\n", pgid, sig));
1.1 nbrk 85:
86: if ((pgrp = pgrp_find(pgid)) == NULL)
87: return ESRCH;
88:
1.1.1.1.2.1! nbrk 89: head = &pgrp->pg_members;
1.1 nbrk 90: for (n = list_first(head); n != head; n = list_next(n)) {
1.1.1.1.2.1! nbrk 91: p = list_entry(n, struct proc, p_link);
1.1 nbrk 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:
1.1.1.1.2.1! nbrk 130: DPRINTF(("proc: kill pid=%d sig=%d\n", pid, sig));
1.1 nbrk 131:
132: switch (sig) {
133: case SIGFPE:
134: case SIGILL:
135: case SIGSEGV:
136: return EINVAL;
137: }
138:
1.1.1.1.2.1! nbrk 139: if (curproc->p_cap & CAP_KILL)
1.1 nbrk 140: capable = 1;
141:
142: if (pid > 0) {
1.1.1.1.2.1! nbrk 143: if (pid != curproc->p_pid && !capable)
1.1 nbrk 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)) {
1.1.1.1.2.1! nbrk 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);
1.1 nbrk 155: if (err != 0)
156: break;
157: }
158: }
159: }
160: else if (pid == 0) {
161: if ((p = proc_find(pid)) == NULL)
162: return ESRCH;
1.1.1.1.2.1! nbrk 163: err = kill_pg(p->p_pgrp->pg_pgid, sig);
1.1 nbrk 164: }
165: else {
1.1.1.1.2.1! nbrk 166: if (curproc->p_pgrp->pg_pgid != -pid && !capable)
1.1 nbrk 167: return EPERM;
168: err = kill_pg(-pid, sig);
169: }
170: return err;
171: }
CVSweb