Implement thread creation in tfork(2).

This commit is contained in:
Jonas 'Sortie' Termansen 2013-08-31 18:02:53 +02:00
parent ff443c9f5e
commit b4d494cf8b
1 changed files with 16 additions and 6 deletions

View File

@ -1084,8 +1084,11 @@ static pid_t sys_tfork(int flags, tforkregs_t* user_regs)
if ( Signal::IsPending() ) if ( Signal::IsPending() )
return errno = EINTR, -1; return errno = EINTR, -1;
bool making_process = flags == SFFORK;
bool making_thread = (flags & (SFPROC | SFPID | SFFD | SFMEM | SFCWD | SFROOT)) == SFPROC;
// TODO: Properly support tfork(2). // TODO: Properly support tfork(2).
if ( flags != SFFORK ) if ( !(making_thread || making_process) )
return errno = ENOSYS, -1; return errno = ENOSYS, -1;
CPU::InterruptRegisters cpuregs; CPU::InterruptRegisters cpuregs;
@ -1097,16 +1100,23 @@ static pid_t sys_tfork(int flags, tforkregs_t* user_regs)
if ( !newkernelstack ) if ( !newkernelstack )
return -1; return -1;
Process* clone = CurrentProcess()->Fork(); Process* child_process;
if ( !clone ) { delete[] newkernelstack; return -1; } if ( making_thread )
child_process = CurrentProcess();
else if ( !(child_process = CurrentProcess()->Fork()) )
{
delete[] newkernelstack;
return -1;
}
// If the thread could not be created, make the process commit suicide // If the thread could not be created, make the process commit suicide
// in a manner such that we don't wait for its zombie. // in a manner such that we don't wait for its zombie.
Thread* thread = CreateKernelThread(clone, &cpuregs, regs.fsbase, Thread* thread = CreateKernelThread(child_process, &cpuregs, regs.fsbase,
regs.gsbase); regs.gsbase);
if ( !thread ) if ( !thread )
{ {
clone->AbortConstruction(); if ( making_process )
child_process->AbortConstruction();
return -1; return -1;
} }
@ -1117,7 +1127,7 @@ static pid_t sys_tfork(int flags, tforkregs_t* user_regs)
StartKernelThread(thread); StartKernelThread(thread);
return clone->pid; return child_process->pid;
} }
static pid_t sys_getpid() static pid_t sys_getpid()