*参照元 [#k97cd3fc] #backlinks *説明 [#l787cb05] -パス: [[linux-2.6.33/kernel/fork.c]] -FIXME: これは何? --説明 **引数 [#uac72978] -unsigned long clone_flags -- -unsigned long stack_start -- -struct pt_regs *regs -- --[[linux-2.6.33/pt_regs]] -unsigned long stack_size -- -int __user *parent_tidptr -- --[[linux-2.6.33/__user]] -int __user *child_tidptr -- **返り値 [#d24c5956] -long -- **参考 [#ldede19d] *実装 [#d2c59d36] /* * Ok, this is the main fork-routine. * * It copies the process, and if successful kick-starts * it and waits for it to finish using the VM if required. */ long do_fork(unsigned long clone_flags, unsigned long stack_start, struct pt_regs *regs, unsigned long stack_size, int __user *parent_tidptr, int __user *child_tidptr) { struct task_struct *p; int trace = 0; long nr; - --[[linux-2.6.33/task_struct]] /* * Do some preliminary argument and permissions checking before we * actually start allocating stuff */ if (clone_flags & CLONE_NEWUSER) { if (clone_flags & CLONE_THREAD) return -EINVAL; - --[[linux-2.6.33/CLONE_NEWUSER]] - --[[linux-2.6.33/CLONE_THREAD]] /* hopefully this check will go away when userns support is * complete */ if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SETUID) || !capable(CAP_SETGID)) return -EPERM; - --[[linux-2.6.33/capable()]] - --[[linux-2.6.33/CAP_SYS_ADMIN]] - --[[linux-2.6.33/CAP_SETUID]] - --[[linux-2.6.33/CAP_SETGID]] } /* * We hope to recycle these flags after 2.6.26 */ if (unlikely(clone_flags & CLONE_STOPPED)) { static int __read_mostly count = 100; - --[[linux-2.6.33/unlikely()]] - --[[linux-2.6.33/CLONE_STOPPED]] - --[[linux-2.6.33/__read_mostly]] if (count > 0 && printk_ratelimit()) { char comm[TASK_COMM_LEN]; - --[[linux-2.6.33/printk_ratelimit()]] - --[[linux-2.6.33/TASK_COMM_LEN]] count--; printk(KERN_INFO "fork(): process `%s' used deprecated " "clone flags 0x%lx\n", get_task_comm(comm, current), clone_flags & CLONE_STOPPED); - --[[linux-2.6.33/printk()]] - --[[linux-2.6.33/get_task_comm()]] - --[[linux-2.6.33/current(global)]] } } /* * When called from kernel_thread, don't do user tracing stuff. */ if (likely(user_mode(regs))) trace = tracehook_prepare_clone(clone_flags); - --[[linux-2.6.33/likely()]] - --[[linux-2.6.33/user_mode()]] - --[[linux-2.6.33/tracehook_prepare_clone()]] p = copy_process(clone_flags, stack_start, regs, stack_size, child_tidptr, NULL, trace); - --[[linux-2.6.33/copy_process()]] /* * Do this prior waking up the new thread - the thread pointer * might get invalid after that point, if the thread exits quickly. */ if (!IS_ERR(p)) { struct completion vfork; - --[[linux-2.6.33/IS_ERR()]] - --[[linux-2.6.33/completion]] trace_sched_process_fork(current, p); - --[[linux-2.6.33/trace_sched_process_fork()]] nr = task_pid_vnr(p); - --[[linux-2.6.33/task_pid_vnr()]] if (clone_flags & CLONE_PARENT_SETTID) put_user(nr, parent_tidptr); - --[[linux-2.6.33/CLONE_PARENT_SETTID]] - --[[linux-2.6.33/put_user()]] if (clone_flags & CLONE_VFORK) { p->vfork_done = &vfork; init_completion(&vfork); } - --[[linux-2.6.33/CLONE_VFORK]] - --[[linux-2.6.33/init_completion()]] audit_finish_fork(p); tracehook_report_clone(regs, clone_flags, nr, p); - --[[linux-2.6.33/audit_finish_fork()]] - --[[linux-2.6.33/tracehook_report_clone()]] /* * We set PF_STARTING at creation in case tracing wants to * use this to distinguish a fully live task from one that * hasn't gotten to tracehook_report_clone() yet. Now we * clear it and set the child going. */ p->flags &= ~PF_STARTING; - --[[linux-2.6.33/PF_STARTING]] if (unlikely(clone_flags & CLONE_STOPPED)) { /* * We'll start up with an immediate SIGSTOP. */ sigaddset(&p->pending.signal, SIGSTOP); set_tsk_thread_flag(p, TIF_SIGPENDING); __set_task_state(p, TASK_STOPPED); - --[[linux-2.6.33/sigaddset()]] - --[[linux-2.6.33/SIGSTOP]] - --[[linux-2.6.33/set_tsk_thread_flag()]] - --[[linux-2.6.33/TIF_SIGPENDING]] - --[[linux-2.6.33/__set_task_state()]] - --[[linux-2.6.33/TASK_STOPPED]] } else { wake_up_new_task(p, clone_flags); - --[[linux-2.6.33/wake_up_new_task()]] } tracehook_report_clone_complete(trace, regs, clone_flags, nr, p); - --[[linux-2.6.33/tracehook_report_clone_complete()]] if (clone_flags & CLONE_VFORK) { freezer_do_not_count(); wait_for_completion(&vfork); freezer_count(); tracehook_report_vfork_done(p, nr); - --[[linux-2.6.33/freezer_do_not_count()]] - --[[linux-2.6.33/wait_for_completion()]] - --[[linux-2.6.33/freezer_count()]] - --[[linux-2.6.33/tracehook_report_vfork_done()]] } } else { nr = PTR_ERR(p); - --[[linux-2.6.33/PTR_ERR()]] } return nr; } *コメント [#lf1b4559]