1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23 /* All Rights Reserved */ 24 25 26 /* 27 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 #include <sys/types.h> 32 #include <sys/sysmacros.h> 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/cred.h> 36 #include <sys/vnode.h> 37 #include <sys/errno.h> 38 #include <sys/user.h> 39 #include <sys/mount.h> 40 #include <sys/proc.h> 41 #include <sys/signal.h> 42 #include <sys/siginfo.h> 43 #include <sys/ucontext.h> 44 #include <sys/prsystm.h> 45 #include <sys/session.h> 46 #include <sys/stream.h> 47 #include <sys/strsubr.h> 48 #include <sys/debug.h> 49 50 /* 51 * Return 1 if process pointed to by 'cp' has a parent that would 52 * prevent its process group from being orphaned, 0 otherwise 53 */ 54 55 static int 56 pglinked(cp) 57 register proc_t *cp; 58 { 59 register proc_t *pp; 60 61 ASSERT(MUTEX_HELD(&pidlock)); 62 63 if ((pp = cp->p_parent) != NULL && 64 pp->p_pgidp != cp->p_pgidp && 65 pp->p_sessp == cp->p_sessp) 66 return (1); 67 return (0); 68 } 69 70 /* 71 * Send the specified signal to all processes whose process group ID is 72 * equal to 'pgid' 73 */ 74 75 void 76 pgsignal(pidp, sig) 77 register struct pid *pidp; 78 int sig; 79 { 80 register proc_t *prp; 81 82 mutex_enter(&pidlock); 83 for (prp = pidp->pid_pglink; prp; prp = prp->p_pglink) { 84 mutex_enter(&prp->p_lock); 85 sigtoproc(prp, NULL, sig); 86 mutex_exit(&prp->p_lock); 87 } 88 mutex_exit(&pidlock); 89 } 90 91 /* 92 * similiar to pgsignal in function except that pidlock mutex is assumed 93 * to be held by the caller. 94 */ 95 void 96 sigtopg(pidp, sig) 97 register struct pid *pidp; 98 int sig; 99 { 100 register proc_t *prp; 101 102 ASSERT(MUTEX_HELD(&pidlock)); 103 104 for (prp = pidp->pid_pglink; prp; prp = prp->p_pglink) { 105 mutex_enter(&prp->p_lock); 106 sigtoproc(prp, NULL, sig); 107 mutex_exit(&prp->p_lock); 108 } 109 } 110 111 /* 112 * Add a process to a process group 113 */ 114 115 void 116 pgjoin(p, pgp) 117 register proc_t *p; 118 register struct pid *pgp; 119 { 120 ASSERT(MUTEX_HELD(&pidlock)); 121 122 p->p_pgidp = pgp; 123 124 if (pgp->pid_pglink == NULL) { 125 ASSERT(pgp->pid_pgtail == NULL); 126 p->p_ppglink = NULL; 127 p->p_pglink = NULL; 128 pgp->pid_pglink = p; 129 pgp->pid_pgtail = p; 130 } else { 131 ASSERT(pgp->pid_pgtail != NULL); 132 if (pglinked(p)) { 133 p->p_ppglink = NULL; 134 p->p_pglink = pgp->pid_pglink; 135 pgp->pid_pglink->p_ppglink = p; 136 pgp->pid_pglink = p; 137 } else { 138 p->p_ppglink = pgp->pid_pgtail; 139 p->p_pglink = NULL; 140 pgp->pid_pgtail->p_pglink = p; 141 pgp->pid_pgtail = p; 142 } 143 } 144 145 if (pgp->pid_pglink == pgp->pid_pgtail) { 146 PID_HOLD(pgp); 147 if (pglinked(p)) 148 pgp->pid_pgorphaned = 0; 149 else 150 pgp->pid_pgorphaned = 1; 151 } else if (pgp->pid_pgorphaned && pglinked(p)) 152 pgp->pid_pgorphaned = 0; 153 } 154 155 void 156 pgexit(prp) 157 proc_t *prp; 158 { 159 register proc_t *p; 160 register struct pid *pgp; 161 162 ASSERT(MUTEX_HELD(&pidlock)); 163 164 pgp = prp->p_pgidp; 165 166 if (pgp->pid_pglink == prp) { 167 ASSERT(prp->p_ppglink == NULL); /* must be at the front */ 168 pgp->pid_pglink = prp->p_pglink; 169 } 170 if (prp->p_ppglink) { 171 prp->p_ppglink->p_pglink = prp->p_pglink; 172 } 173 if (prp->p_pglink) { 174 prp->p_pglink->p_ppglink = prp->p_ppglink; 175 } 176 if (pgp->pid_pgtail == prp) { 177 pgp->pid_pgtail = prp->p_ppglink; 178 } 179 180 prp->p_pgidp = NULL; 181 prp->p_pglink = NULL; 182 prp->p_ppglink = NULL; 183 184 if ((p = pgp->pid_pglink) == NULL) { 185 PID_RELE(pgp); 186 } else if (pgp->pid_pgorphaned == 0) { 187 do { 188 if (pglinked(p)) { 189 return; 190 } 191 } while ((p = p->p_pglink) != NULL); 192 pgp->pid_pgorphaned = 1; 193 } 194 } 195 196 /* 197 * process 'pp' is exiting - check to see if this will 198 * orphan its children's process groups 199 */ 200 201 void 202 pgdetach(pp) 203 proc_t *pp; 204 { 205 int stopped; 206 register proc_t *cp; 207 register proc_t *mp; 208 register struct pid *pgp; 209 210 ASSERT(MUTEX_HELD(&pidlock)); 211 212 for (cp = pp->p_child; cp; cp = cp->p_sibling) { 213 if ((pgp = cp->p_pgidp)->pid_pgorphaned) 214 continue; 215 stopped = 0; 216 mp = pgp->pid_pglink; 217 ASSERT(mp != NULL); 218 for (;;) { 219 if (mp != pp && mp->p_parent != pp && pglinked(mp)) 220 break; 221 if (!stopped && mp != curproc) { 222 mutex_enter(&mp->p_lock); 223 stopped = jobstopped(mp); 224 mutex_exit(&mp->p_lock); 225 } 226 if ((mp = mp->p_pglink) == NULL) { 227 pgp->pid_pgorphaned = 1; 228 if (stopped) { 229 sigtopg(pgp, SIGHUP); 230 sigtopg(pgp, SIGCONT); 231 } 232 break; 233 } 234 } 235 } 236 } 237 238 /* 239 * Return 1 if pgid is the process group ID of an existing process group 240 * that has members not the process group leader in it. 241 * 242 * Otherwise, return 0. 243 */ 244 245 int 246 pgmembers(pgid) 247 register pid_t pgid; 248 { 249 register proc_t *prp; 250 251 ASSERT(MUTEX_HELD(&pidlock)); 252 253 for (prp = pgfind(pgid); prp; prp = prp->p_pglink) 254 if (prp->p_pid != pgid) { 255 return (1); 256 } 257 return (0); 258 } 259