*参照元 [#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]


トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS