|
|||
Prex Home / Browse Source - Prex Version: 0.9.0 |
|||
root/usr/server/proc/proc_sig.c/* [<][>][^][v][top][bottom][index][help] */DEFINITIONSThis source file includes following definitions.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 * proc_sig.c - signal transfer. 32 */ 33 34 #include <sys/prex.h> 35 #include <sys/capability.h> 36 #include <ipc/proc.h> 37 #include <sys/list.h> 38 39 #include <unistd.h> 40 #include <errno.h> 41 42 #include "proc.h" 43 44 /* 45 * Check if current process has CAP_KILL capability. 46 */ 47 static int 48 kill_capable(void) 49 { 50 51 if (task_chkcap(curproc->p_task, CAP_KILL) == 0) 52 return 1; 53 return 0; 54 } 55 56 /* 57 * Send a signal to the process. 58 */ 59 static int 60 sendsig(struct proc *p, int sig) 61 { 62 63 /* 64 * We never allow to send signal to the 65 * process server in any case. 66 */ 67 if (p->p_pid == 0) 68 return EPERM; 69 70 /* 71 * Filter signals for init process. 72 * This is for fail safe... 73 */ 74 if (p->p_pid == 1 && sig != SIGCHLD) 75 return EPERM; 76 77 DPRINTF(("proc: sendsig task=%x\n", p->p_task)); 78 return exception_raise(p->p_task, sig); 79 } 80 81 /* 82 * Send a signal to one process. 83 */ 84 static int 85 kill_one(pid_t pid, int sig) 86 { 87 struct proc *p; 88 89 DPRINTF(("proc: killone pid=%d sig=%d\n", pid, sig)); 90 91 if ((p = p_find(pid)) == NULL) 92 return ESRCH; 93 return sendsig(p, sig); 94 } 95 96 /* 97 * Send a signal to all process in the process group. 98 */ 99 int 100 kill_pg(pid_t pgid, int sig) 101 { 102 struct proc *p; 103 struct pgrp *pgrp; 104 list_t head, n; 105 int error = 0; 106 107 DPRINTF(("proc: killpg pgid=%d sig=%d\n", pgid, sig)); 108 109 if ((pgrp = pg_find(pgid)) == NULL) 110 return ESRCH; 111 112 head = &pgrp->pg_members; 113 for (n = list_first(head); n != head; n = list_next(n)) { 114 p = list_entry(n, struct proc, p_pgrp_link); 115 if ((error = sendsig(p, sig)) != 0) 116 break; 117 } 118 return error; 119 } 120 121 /* 122 * Send a signal. 123 * 124 * The behavior is different for the pid value. 125 * 126 * if (pid > 0) 127 * Send a signal to specific process. 128 * 129 * if (pid == 0) 130 * Send a signal to all processes in same process group. 131 * 132 * if (pid == -1) 133 * Send a signal to all processes except init. 134 * 135 * if (pid < -1) 136 * Send a signal to the process group. 137 * 138 * Note: Need CAP_KILL capability to send a signal to the different 139 * process/group. 140 */ 141 int 142 sys_kill(pid_t pid, int sig) 143 { 144 struct proc *p; 145 list_t n; 146 int error = 0; 147 148 DPRINTF(("proc: kill pid=%d sig=%d\n", pid, sig)); 149 150 switch (sig) { 151 case SIGFPE: 152 case SIGILL: 153 case SIGSEGV: 154 return EINVAL; 155 } 156 157 if (pid > 0) { 158 if (pid != curproc->p_pid && !kill_capable()) { 159 DPRINTF(("proc: EPERM\n")); 160 return EPERM; 161 } 162 error = kill_one(pid, sig); 163 } 164 else if (pid == -1) { 165 DPRINTF(("proc: kill? curproc=%x\n", curproc)); 166 if (!kill_capable()) 167 return EPERM; 168 169 DPRINTF(("proc: kill all!\n")); 170 for (n = list_first(&allproc); n != &allproc; 171 n = list_next(n)) { 172 p = list_entry(n, struct proc, p_link); 173 174 /* 175 * We don't send a signal to the following processes. 176 * 177 * pid=0 - process server 178 * pid=1 - init process 179 * curproc - current process (sleeping in msg_send) 180 */ 181 if (p->p_pid != 0 && p->p_pid != 1 && 182 p->p_pid != curproc->p_pid) 183 { 184 error = kill_one(p->p_pid, sig); 185 if (error != 0) 186 break; 187 } 188 } 189 } 190 else if (pid == 0) { 191 error = kill_pg(curproc->p_pgrp->pg_pgid, sig); 192 } 193 else { /* pid < -1 */ 194 if (curproc->p_pgrp->pg_pgid != -pid && !kill_capable()) 195 return EPERM; 196 error = kill_pg(-pid, sig); 197 } 198 return error; 199 } /* [<][>][^][v][top][bottom][index][help] */ | |||
Copyright© 2005-2009 Kohsuke Ohtani |