Import 2.0.2
[davej-history.git] / kernel / fork.c
blob723e4242cd2b026dfefaf7c6ba6d10bee4ef68a8
1 /*
2 * linux/kernel/fork.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */
7 /*
8 * 'fork.c' contains the help-routines for the 'fork' system call
9 * (see also system_call.s).
10 * Fork is rather simple, once you get the hang of it, but the memory
11 * management can be a bitch. See 'mm/mm.c': 'copy_page_tables()'
14 #include <linux/errno.h>
15 #include <linux/sched.h>
16 #include <linux/kernel.h>
17 #include <linux/mm.h>
18 #include <linux/stddef.h>
19 #include <linux/unistd.h>
20 #include <linux/ptrace.h>
21 #include <linux/malloc.h>
22 #include <linux/ldt.h>
23 #include <linux/smp.h>
25 #include <asm/segment.h>
26 #include <asm/system.h>
27 #include <asm/pgtable.h>
29 int nr_tasks=1;
30 int nr_running=1;
31 unsigned long int total_forks=0;/* Handle normal Linux uptimes. */
32 int last_pid=0;
34 staticinlineintfind_empty_process(void)
36 int i;
38 if(nr_tasks >= NR_TASKS - MIN_TASKS_LEFT_FOR_ROOT) {
39 if(current->uid)
40 return-EAGAIN;
42 if(current->uid) {
43 long max_tasks = current->rlim[RLIMIT_NPROC].rlim_cur;
45 max_tasks--;/* count the new process.. */
46 if(max_tasks < nr_tasks) {
47 struct task_struct *p;
48 for_each_task(p) {
49 if(p->uid == current->uid)
50 if(--max_tasks <0)
51 return-EAGAIN;
55 for(i =0; i < NR_TASKS ; i++) {
56 if(!task[i])
57 return i;
59 return-EAGAIN;
62 static intget_pid(unsigned long flags)
64 struct task_struct *p;
66 if(flags & CLONE_PID)
67 return current->pid;
68 repeat:
69 if((++last_pid) &0xffff8000)
70 last_pid=1;
71 for_each_task(p) {
72 if(p->pid == last_pid ||
73 p->pgrp == last_pid ||
74 p->session == last_pid)
75 goto repeat;
77 return last_pid;
80 staticinlineintdup_mmap(struct mm_struct * mm)
82 struct vm_area_struct * mpnt, **p, *tmp;
84 mm->mmap = NULL;
85 p = &mm->mmap;
86 for(mpnt = current->mm->mmap ; mpnt ; mpnt = mpnt->vm_next) {
87 tmp = (struct vm_area_struct *)kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
88 if(!tmp) {
89 exit_mmap(mm);
90 return-ENOMEM;
92 *tmp = *mpnt;
93 tmp->vm_flags &= ~VM_LOCKED;
94 tmp->vm_mm = mm;
95 tmp->vm_next = NULL;
96 if(tmp->vm_inode) {
97 tmp->vm_inode->i_count++;
98 /* insert tmp into the share list, just after mpnt */
99 tmp->vm_next_share->vm_prev_share = tmp;
100 mpnt->vm_next_share = tmp;
101 tmp->vm_prev_share = mpnt;
103 if(tmp->vm_ops && tmp->vm_ops->open)
104 tmp->vm_ops->open(tmp);
105 if(copy_page_range(mm, current->mm, tmp)) {
106 exit_mmap(mm);
107 return-ENOMEM;
109 *p = tmp;
110 p = &tmp->vm_next;
112 build_mmap_avl(mm);
113 return0;
116 staticinlineintcopy_mm(unsigned long clone_flags,struct task_struct * tsk)
118 if(!(clone_flags & CLONE_VM)) {
119 struct mm_struct * mm =kmalloc(sizeof(*tsk->mm), GFP_KERNEL);
120 if(!mm)
121 return-1;
122 *mm = *current->mm;
123 mm->count =1;
124 mm->def_flags =0;
125 tsk->mm = mm;
126 tsk->min_flt = tsk->maj_flt =0;
127 tsk->cmin_flt = tsk->cmaj_flt =0;
128 tsk->nswap = tsk->cnswap =0;
129 if(new_page_tables(tsk))
130 return-1;
131 if(dup_mmap(mm)) {
132 free_page_tables(mm);
133 return-1;
135 return0;
137 SET_PAGE_DIR(tsk, current->mm->pgd);
138 current->mm->count++;
139 return0;
142 staticinlineintcopy_fs(unsigned long clone_flags,struct task_struct * tsk)
144 if(clone_flags & CLONE_FS) {
145 current->fs->count++;
146 return0;
148 tsk->fs =kmalloc(sizeof(*tsk->fs), GFP_KERNEL);
149 if(!tsk->fs)
150 return-1;
151 tsk->fs->count =1;
152 tsk->fs->umask = current->fs->umask;
153 if((tsk->fs->root = current->fs->root))
154 tsk->fs->root->i_count++;
155 if((tsk->fs->pwd = current->fs->pwd))
156 tsk->fs->pwd->i_count++;
157 return0;
160 staticinlineintcopy_files(unsigned long clone_flags,struct task_struct * tsk)
162 int i;
163 struct files_struct *oldf, *newf;
164 struct file **old_fds, **new_fds;
166 oldf = current->files;
167 if(clone_flags & CLONE_FILES) {
168 oldf->count++;
169 return0;
172 newf =kmalloc(sizeof(*newf), GFP_KERNEL);
173 tsk->files = newf;
174 if(!newf)
175 return-1;
177 newf->count =1;
178 newf->close_on_exec = oldf->close_on_exec;
179 newf->open_fds = oldf->open_fds;
181 old_fds = oldf->fd;
182 new_fds = newf->fd;
183 for(i = NR_OPEN; i !=0; i--) {
184 struct file * f = *old_fds;
185 old_fds++;
186 *new_fds = f;
187 new_fds++;
188 if(f)
189 f->f_count++;
191 return0;
194 staticinlineintcopy_sighand(unsigned long clone_flags,struct task_struct * tsk)
196 if(clone_flags & CLONE_SIGHAND) {
197 current->sig->count++;
198 return0;
200 tsk->sig =kmalloc(sizeof(*tsk->sig), GFP_KERNEL);
201 if(!tsk->sig)
202 return-1;
203 tsk->sig->count =1;
204 memcpy(tsk->sig->action, current->sig->action,sizeof(tsk->sig->action));
205 return0;
209 * Ok, this is the main fork-routine. It copies the system process
210 * information (task[nr]) and sets up the necessary registers. It
211 * also copies the data segment in its entirety.
213 intdo_fork(unsigned long clone_flags,unsigned long usp,struct pt_regs *regs)
215 int nr;
216 int error = -ENOMEM;
217 unsigned long new_stack;
218 struct task_struct *p;
220 p = (struct task_struct *)kmalloc(sizeof(*p), GFP_KERNEL);
221 if(!p)
222 goto bad_fork;
223 new_stack =alloc_kernel_stack();
224 if(!new_stack)
225 goto bad_fork_free_p;
226 error = -EAGAIN;
227 nr =find_empty_process();
228 if(nr <0)
229 goto bad_fork_free_stack;
231 *p = *current;
233 if(p->exec_domain && p->exec_domain->use_count)
234 (*p->exec_domain->use_count)++;
235 if(p->binfmt && p->binfmt->use_count)
236 (*p->binfmt->use_count)++;
238 p->did_exec =0;
239 p->swappable =0;
240 p->kernel_stack_page = new_stack;
241 *(unsigned long*) p->kernel_stack_page = STACK_MAGIC;
242 p->state = TASK_UNINTERRUPTIBLE;
243 p->flags &= ~(PF_PTRACED|PF_TRACESYS|PF_SUPERPRIV);
244 p->flags |= PF_FORKNOEXEC;
245 p->pid =get_pid(clone_flags);
246 p->next_run = NULL;
247 p->prev_run = NULL;
248 p->p_pptr = p->p_opptr = current;
249 p->p_cptr = NULL;
250 p->signal =0;
251 p->it_real_value = p->it_virt_value = p->it_prof_value =0;
252 p->it_real_incr = p->it_virt_incr = p->it_prof_incr =0;
253 init_timer(&p->real_timer);
254 p->real_timer.data = (unsigned long) p;
255 p->leader =0;/* process leadership doesn't inherit */
256 p->tty_old_pgrp =0;
257 p->utime = p->stime =0;
258 p->cutime = p->cstime =0;
259 #ifdef __SMP__
260 p->processor = NO_PROC_ID;
261 p->lock_depth =1;
262 #endif
263 p->start_time = jiffies;
264 task[nr] = p;
265 SET_LINKS(p);
266 nr_tasks++;
268 error = -ENOMEM;
269 /* copy all the process information */
270 if(copy_files(clone_flags, p))
271 goto bad_fork_cleanup;
272 if(copy_fs(clone_flags, p))
273 goto bad_fork_cleanup_files;
274 if(copy_sighand(clone_flags, p))
275 goto bad_fork_cleanup_fs;
276 if(copy_mm(clone_flags, p))
277 goto bad_fork_cleanup_sighand;
278 copy_thread(nr, clone_flags, usp, p, regs);
279 p->semundo = NULL;
281 /* ok, now we should be set up.. */
282 p->swappable =1;
283 p->exit_signal = clone_flags & CSIGNAL;
284 p->counter = current->counter >>1;
285 wake_up_process(p);/* do this last, just in case */
286 ++total_forks;
287 return p->pid;
289 bad_fork_cleanup_sighand:
290 exit_sighand(p);
291 bad_fork_cleanup_fs:
292 exit_fs(p);
293 bad_fork_cleanup_files:
294 exit_files(p);
295 bad_fork_cleanup:
296 if(p->exec_domain && p->exec_domain->use_count)
297 (*p->exec_domain->use_count)--;
298 if(p->binfmt && p->binfmt->use_count)
299 (*p->binfmt->use_count)--;
300 task[nr] = NULL;
301 REMOVE_LINKS(p);
302 nr_tasks--;
303 bad_fork_free_stack:
304 free_kernel_stack(new_stack);
305 bad_fork_free_p:
306 kfree(p);
307 bad_fork:
308 return error;
close