386BSD 0.1 development
[unix-history] / usr / src / sys.386bsd / kern / kern_fork.c
CommitLineData
85b6e46b
WJ
1/*
2 * Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California.
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. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)kern_fork.c 7.29 (Berkeley) 5/15/91
34 */
35
36#include "param.h"
37#include "systm.h"
38#include "filedesc.h"
39#include "kernel.h"
40#include "malloc.h"
41#include "proc.h"
42#include "resourcevar.h"
43#include "vnode.h"
44#include "file.h"
45#include "acct.h"
46#include "ktrace.h"
47#include "vm/vm.h"
48
49/* ARGSUSED */
50fork(p, uap, retval)
51 struct proc *p;
52 void *uap;
53 int retval[];
54{
55
56 return (fork1(p, 0, retval));
57}
58
59/* ARGSUSED */
60vfork(p, uap, retval)
61 struct proc *p;
62 void *uap;
63 int retval[];
64{
65
66 return (fork1(p, 1, retval));
67}
68
69int nprocs = 1; /* process 0 */
70
71fork1(p1, isvfork, retval)
72 register struct proc *p1;
73 int isvfork, retval[];
74{
75 register struct proc *p2;
76 register int count, uid;
77 static int nextpid, pidchecked = 0;
78
79 count = 0;
80 if ((uid = p1->p_ucred->cr_uid) != 0) {
81 for (p2 = allproc; p2; p2 = p2->p_nxt)
82 if (p2->p_ucred->cr_uid == uid)
83 count++;
84 for (p2 = zombproc; p2; p2 = p2->p_nxt)
85 if (p2->p_ucred->cr_uid == uid)
86 count++;
87 }
88 /*
89 * Although process entries are dynamically entries,
90 * we still keep a global limit on the maximum number
91 * we will create. Don't allow a nonprivileged user
92 * to exceed its current limit or to bring us within one
93 * of the global limit; don't let root exceed the limit.
94 * nprocs is the current number of processes,
95 * maxproc is the limit.
96 */
97 if (nprocs >= maxproc || uid == 0 && nprocs >= maxproc + 1) {
98 tablefull("proc");
99 return (EAGAIN);
100 }
101 if (count > p1->p_rlimit[RLIMIT_NPROC].rlim_cur)
102 return (EAGAIN);
103
104 /*
105 * Find an unused process ID.
106 * We remember a range of unused IDs ready to use
107 * (from nextpid+1 through pidchecked-1).
108 */
109 nextpid++;
110retry:
111 /*
112 * If the process ID prototype has wrapped around,
113 * restart somewhat above 0, as the low-numbered procs
114 * tend to include daemons that don't exit.
115 */
116 if (nextpid >= PID_MAX) {
117 nextpid = 100;
118 pidchecked = 0;
119 }
120 if (nextpid >= pidchecked) {
121 int doingzomb = 0;
122
123 pidchecked = PID_MAX;
124 /*
125 * Scan the active and zombie procs to check whether this pid
126 * is in use. Remember the lowest pid that's greater
127 * than nextpid, so we can avoid checking for a while.
128 */
129 p2 = allproc;
130again:
131 for (; p2 != NULL; p2 = p2->p_nxt) {
132 if (p2->p_pid == nextpid ||
133 p2->p_pgrp->pg_id == nextpid) {
134 nextpid++;
135 if (nextpid >= pidchecked)
136 goto retry;
137 }
138 if (p2->p_pid > nextpid && pidchecked > p2->p_pid)
139 pidchecked = p2->p_pid;
140 if (p2->p_pgrp->pg_id > nextpid &&
141 pidchecked > p2->p_pgrp->pg_id)
142 pidchecked = p2->p_pgrp->pg_id;
143 }
144 if (!doingzomb) {
145 doingzomb = 1;
146 p2 = zombproc;
147 goto again;
148 }
149 }
150
151
152 /*
153 * Allocate new proc.
154 * Link onto allproc (this should probably be delayed).
155 */
156 MALLOC(p2, struct proc *, sizeof(struct proc), M_PROC, M_WAITOK);
157 nprocs++;
158 p2->p_nxt = allproc;
159 p2->p_nxt->p_prev = &p2->p_nxt; /* allproc is never NULL */
160 p2->p_prev = &allproc;
161 allproc = p2;
162 p2->p_link = NULL; /* shouldn't be necessary */
163 p2->p_rlink = NULL; /* shouldn't be necessary */
164
165 /*
166 * Make a proc table entry for the new process.
167 * Start by zeroing the section of proc that is zero-initialized,
168 * then copy the section that is copied directly from the parent.
169 */
170 bzero(&p2->p_startzero,
171 (unsigned) ((caddr_t)&p2->p_endzero - (caddr_t)&p2->p_startzero));
172 bcopy(&p1->p_startcopy, &p2->p_startcopy,
173 (unsigned) ((caddr_t)&p2->p_endcopy - (caddr_t)&p2->p_startcopy));
174 p2->p_spare[0] = 0; /* XXX - should be in zero range */
175 p2->p_spare[1] = 0; /* XXX - should be in zero range */
176 p2->p_spare[2] = 0; /* XXX - should be in zero range */
177 p2->p_spare[3] = 0; /* XXX - should be in zero range */
178
179 /*
180 * Duplicate sub-structures as needed.
181 * Increase reference counts on shared objects.
182 * The p_stats and p_sigacts substructs are set in vm_fork.
183 */
184 MALLOC(p2->p_cred, struct pcred *, sizeof(struct pcred),
185 M_SUBPROC, M_WAITOK);
186 bcopy(p1->p_cred, p2->p_cred, sizeof(*p2->p_cred));
187 p2->p_cred->p_refcnt = 1;
188 crhold(p1->p_ucred);
189
190 p2->p_fd = fdcopy(p1);
191 /*
192 * If p_limit is still copy-on-write, bump refcnt,
193 * otherwise get a copy that won't be modified.
194 * (If PL_SHAREMOD is clear, the structure is shared
195 * copy-on-write.)
196 */
197 if (p1->p_limit->p_lflags & PL_SHAREMOD)
198 p2->p_limit = limcopy(p1->p_limit);
199 else {
200 p2->p_limit = p1->p_limit;
201 p2->p_limit->p_refcnt++;
202 }
203
204 p2->p_flag = SLOAD | (p1->p_flag & SHPUX);
205 if (p1->p_session->s_ttyvp != NULL && p1->p_flag & SCTTY)
206 p2->p_flag |= SCTTY;
207 if (isvfork)
208 p2->p_flag |= SPPWAIT;
209 p2->p_stat = SIDL;
210 p2->p_pid = nextpid;
211 {
212 struct proc **hash = &pidhash[PIDHASH(p2->p_pid)];
213
214 p2->p_hash = *hash;
215 *hash = p2;
216 }
217 p2->p_pgrpnxt = p1->p_pgrpnxt;
218 p1->p_pgrpnxt = p2;
219 p2->p_pptr = p1;
220 p2->p_osptr = p1->p_cptr;
221 if (p1->p_cptr)
222 p1->p_cptr->p_ysptr = p2;
223 p1->p_cptr = p2;
224#ifdef KTRACE
225 /*
226 * Copy traceflag and tracefile if enabled.
227 * If not inherited, these were zeroed above.
228 */
229 if (p1->p_traceflag&KTRFAC_INHERIT) {
230 p2->p_traceflag = p1->p_traceflag;
231 if ((p2->p_tracep = p1->p_tracep) != NULL)
232 VREF(p2->p_tracep);
233 }
234#endif
235
236#if defined(tahoe)
237 p2->p_vmspace->p_ckey = p1->p_vmspace->p_ckey; /* XXX move this */
238#endif
239
240 /*
241 * This begins the section where we must prevent the parent
242 * from being swapped.
243 */
244 p1->p_flag |= SKEEP;
245 /*
246 * Set return values for child before vm_fork,
247 * so they can be copied to child stack.
248 * We return parent pid, and mark as child in retval[1].
249 * NOTE: the kernel stack may be at a different location in the child
250 * process, and thus addresses of automatic variables (including retval)
251 * may be invalid after vm_fork returns in the child process.
252 */
253 retval[0] = p1->p_pid;
254 retval[1] = 1;
255 if (vm_fork(p1, p2, isvfork)) {
256 /*
257 * Child process. Set start time and get to work.
258 */
259 (void) splclock();
260 p2->p_stats->p_start = time;
261 (void) spl0();
262 p2->p_acflag = AFORK;
263 return (0);
264 }
265
266 /*
267 * Make child runnable and add to run queue.
268 */
269 (void) splhigh();
270 p2->p_stat = SRUN;
271 setrq(p2);
272 (void) spl0();
273
274 /*
275 * Now can be swapped.
276 */
277 p1->p_flag &= ~SKEEP;
278
279 /*
280 * Preserve synchronization semantics of vfork.
281 * If waiting for child to exec or exit, set SPPWAIT
282 * on child, and sleep on our proc (in case of exit).
283 */
284 if (isvfork)
285 while (p2->p_flag & SPPWAIT)
286 tsleep((caddr_t)p1, PWAIT, "ppwait", 0);
287
288 /*
289 * Return child pid to parent process,
290 * marking us as parent via retval[1].
291 */
292 retval[0] = p2->p_pid;
293 retval[1] = 0;
294 return (0);
295}