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