Ambos padres e hijos devuelven valores diferentes debido a la manipulación de los registros de la CPU en el contexto del niño.
Cada proceso en el kernel de Linux representado por task_struct. task_struct está encerrado (puntero) en la estructura thread_info que se encuentra al final de la pila del modo kernel. Todo el contexto de la CPU (registros) se almacena en esta estructura thread_info.
struct thread_info {
struct task_struct *task; /* main task structure */
struct cpu_context_save cpu_context; /* cpu context */
}
Todo sistema de tenedor/clone() llama llamadas kernel equivalente do_fork función().
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)
Aquí está la secuencia de ejecución
do_fork() -> copy_process-> copy_thread() (copy_thread es arco de llamada a una función específica)
copy_thread() copia los valores de registro de los padres y cambia el valor de retorno a 0 (En caso de brazo)
struct pt_regs *childregs = task_pt_regs(p);
*childregs = *regs; /* Copy register value from parent process*/
childregs->ARM_r0 = 0; /*Change the return value*/
thread->cpu_context.sp = (unsigned long)childregs;/*Write back the value to thread info*/
thread->cpu_context.pc = (unsigned long)ret_from_fork;
Cuando se programa al niño, ejecuta una rutina de ensamblaje ret_from_fork() que devolverá cero. Para el padre se pone el valor de retorno de la do_fork() que es pid del proceso
nr = task_pid_vnr(p);
return nr;
Es más comúnmente llamado proceso de "niño" "padre" y. La gente puede acusarlo de sexismo. – Thomas