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.
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.
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]
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
30 #pragma ident "%Z%%M% %I% %E% SMI" /* from SVr4.0 1.78 */
32 #include <sys/param.h>
33 #include <sys/types.h>
34 #include <sys/sysmacros.h>
35 #include <sys/systm.h>
36 #include <sys/errno.h>
39 #include <sys/session.h>
40 #include <sys/debug.h>
44 setpgrp(int flag
, int pid
, int pgid
)
52 case 1: /* setpgrp() */
53 mutex_enter(&pidlock
);
54 if (p
->p_sessp
->s_sidp
!= p
->p_pidp
&& !pgmembers(p
->p_pid
)) {
59 mutex_enter(&p
->p_splock
);
60 sid
= p
->p_sessp
->s_sid
;
61 mutex_exit(&p
->p_splock
);
64 case 3: /* setsid() */
65 mutex_enter(&pidlock
);
66 if (p
->p_pgidp
== p
->p_pidp
|| pgmembers(p
->p_pid
)) {
68 return (set_errno(EPERM
));
72 mutex_enter(&p
->p_splock
);
73 sid
= p
->p_sessp
->s_sid
;
74 mutex_exit(&p
->p_splock
);
77 case 5: /* setpgid() */
79 mutex_enter(&pidlock
);
82 else if (pid
< 0 || pid
>= maxpid
) {
84 return (set_errno(EINVAL
));
85 } else if (pid
!= p
->p_pid
) {
86 for (p
= p
->p_child
; /* empty */; p
= p
->p_sibling
) {
89 return (set_errno(ESRCH
));
94 if (p
->p_flag
& SEXECED
) {
96 return (set_errno(EACCES
));
98 if (p
->p_sessp
!= ttoproc(curthread
)->p_sessp
) {
100 return (set_errno(EPERM
));
104 if (p
->p_sessp
->s_sid
== pid
) {
105 mutex_exit(&pidlock
);
106 return (set_errno(EPERM
));
111 else if (pgid
< 0 || pgid
>= maxpid
) {
112 mutex_exit(&pidlock
);
113 return (set_errno(EINVAL
));
116 if (p
->p_pgrp
== pgid
) {
117 mutex_exit(&pidlock
);
119 } else if (p
->p_pid
== pgid
) {
121 * We need to protect p_pgidp with p_lock because
122 * /proc looks at it while holding only p_lock.
124 mutex_enter(&p
->p_lock
);
126 pgjoin(p
, p
->p_pidp
);
127 mutex_exit(&p
->p_lock
);
131 if ((q
= pgfind(pgid
)) == NULL
||
132 q
->p_sessp
!= p
->p_sessp
) {
133 mutex_exit(&pidlock
);
134 return (set_errno(EPERM
));
137 * See comment above about p_lock and /proc
139 mutex_enter(&p
->p_lock
);
141 pgjoin(p
, q
->p_pgidp
);
142 mutex_exit(&p
->p_lock
);
144 mutex_exit(&pidlock
);
148 case 0: /* getpgrp() */
149 mutex_enter(&pidlock
);
151 mutex_exit(&pidlock
);
154 case 2: /* getsid() */
155 case 4: /* getpgid() */
156 if (pid
< 0 || pid
>= maxpid
) {
157 return (set_errno(EINVAL
));
159 mutex_enter(&pidlock
);
160 if (pid
!= 0 && p
->p_pid
!= pid
&&
161 ((p
= prfind(pid
)) == NULL
|| p
->p_stat
== SIDL
)) {
162 mutex_exit(&pidlock
);
163 return (set_errno(ESRCH
));
166 retval
= p
->p_sessp
->s_sid
;
169 mutex_exit(&pidlock
);