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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 27 /* All Rights Reserved */ 28 29 #include <sys/param.h> 30 #include <sys/types.h> 31 #include <sys/sysmacros.h> 32 #include <sys/systm.h> 33 #include <sys/errno.h> 34 #include <sys/file.h> 35 #include <sys/proc.h> 36 #include <sys/session.h> 37 #include <sys/debug.h> 38 39 /* ARGSUSED */ 40 int 41 setpgrp(int flag, int pid, int pgid) 42 { 43 proc_t *p = curproc; 44 int retval = 0; 45 int sid; 46 47 switch (flag) { 48 49 case 1: /* setpgrp() */ 50 mutex_enter(&pidlock); 51 if (p->p_sessp->s_sidp != p->p_pidp && !pgmembers(p->p_pid)) { 52 mutex_exit(&pidlock); 53 sess_create(); 54 } else 55 mutex_exit(&pidlock); 56 mutex_enter(&p->p_splock); 57 sid = p->p_sessp->s_sid; 58 mutex_exit(&p->p_splock); 59 return (sid); 60 61 case 3: /* setsid() */ 62 mutex_enter(&pidlock); 63 if (p->p_pgidp == p->p_pidp || pgmembers(p->p_pid)) { 64 mutex_exit(&pidlock); 65 return (set_errno(EPERM)); 66 } 67 mutex_exit(&pidlock); 68 sess_create(); 69 mutex_enter(&p->p_splock); 70 sid = p->p_sessp->s_sid; 71 mutex_exit(&p->p_splock); 72 return (sid); 73 74 case 5: /* setpgid() */ 75 { 76 mutex_enter(&pidlock); 77 if (pid == 0) 78 pid = p->p_pid; 79 else if (pid < 0 || pid >= maxpid) { 80 mutex_exit(&pidlock); 81 return (set_errno(EINVAL)); 82 } else if (pid != p->p_pid) { 83 for (p = p->p_child; /* empty */; p = p->p_sibling) { 84 if (p == NULL) { 85 mutex_exit(&pidlock); 86 return (set_errno(ESRCH)); 87 } 88 if (p->p_pid == pid) 89 break; 90 } 91 if (p->p_flag & SEXECED) { 92 mutex_exit(&pidlock); 93 return (set_errno(EACCES)); 94 } 95 if (p->p_sessp != ttoproc(curthread)->p_sessp) { 96 mutex_exit(&pidlock); 97 return (set_errno(EPERM)); 98 } 99 } 100 101 if (p->p_sessp->s_sid == pid) { 102 mutex_exit(&pidlock); 103 return (set_errno(EPERM)); 104 } 105 106 if (pgid == 0) 107 pgid = p->p_pid; 108 else if (pgid < 0 || pgid >= maxpid) { 109 mutex_exit(&pidlock); 110 return (set_errno(EINVAL)); 111 } 112 113 if (p->p_pgrp == pgid) { 114 mutex_exit(&pidlock); 115 break; 116 } else if (p->p_pid == pgid) { 117 /* 118 * We need to protect p_pgidp with p_lock because 119 * /proc looks at it while holding only p_lock. 120 */ 121 mutex_enter(&p->p_lock); 122 pgexit(p); 123 pgjoin(p, p->p_pidp); 124 mutex_exit(&p->p_lock); 125 } else { 126 register proc_t *q; 127 128 if ((q = pgfind(pgid)) == NULL || 129 q->p_sessp != p->p_sessp) { 130 mutex_exit(&pidlock); 131 return (set_errno(EPERM)); 132 } 133 /* 134 * See comment above about p_lock and /proc 135 */ 136 mutex_enter(&p->p_lock); 137 pgexit(p); 138 pgjoin(p, q->p_pgidp); 139 mutex_exit(&p->p_lock); 140 } 141 mutex_exit(&pidlock); 142 break; 143 } 144 145 case 0: /* getpgrp() */ 146 mutex_enter(&pidlock); 147 retval = p->p_pgrp; 148 mutex_exit(&pidlock); 149 break; 150 151 case 2: /* getsid() */ 152 case 4: /* getpgid() */ 153 if (pid < 0 || pid >= maxpid) { 154 return (set_errno(EINVAL)); 155 } 156 mutex_enter(&pidlock); 157 if (pid != 0 && p->p_pid != pid && 158 ((p = prfind(pid)) == NULL || p->p_stat == SIDL)) { 159 mutex_exit(&pidlock); 160 return (set_errno(ESRCH)); 161 } 162 if (flag == 2) 163 retval = p->p_sessp->s_sid; 164 else 165 retval = p->p_pgrp; 166 mutex_exit(&pidlock); 167 break; 168 169 } 170 return (retval); 171 } 172