Update sortix/process.cpp coding style.

This commit is contained in:
Jonas 'Sortie' Termansen 2013-06-12 01:01:49 +02:00
parent 8d420c9de7
commit 2cb3f2860a
1 changed files with 994 additions and 976 deletions

View File

@ -22,45 +22,46 @@
*******************************************************************************/ *******************************************************************************/
#include <assert.h>
#include <errno.h>
#include <stdint.h>
#include <string.h>
#include <sortix/clock.h>
#include <sortix/fcntl.h>
#include <sortix/fork.h>
#include <sortix/mman.h>
#include <sortix/signal.h>
#include <sortix/stat.h>
#include <sortix/unistd.h>
#include <sortix/wait.h>
#include <sortix/kernel/platform.h> #include <sortix/kernel/platform.h>
#include <sortix/kernel/kthread.h>
#include <sortix/kernel/refcount.h>
#include <sortix/kernel/ioctx.h>
#include <sortix/kernel/copy.h> #include <sortix/kernel/copy.h>
#include <sortix/kernel/descriptor.h> #include <sortix/kernel/descriptor.h>
#include <sortix/kernel/dtable.h> #include <sortix/kernel/dtable.h>
#include <sortix/kernel/mtable.h> #include <sortix/kernel/ioctx.h>
#include <sortix/kernel/worker.h> #include <sortix/kernel/kthread.h>
#include <sortix/kernel/memorymanagement.h> #include <sortix/kernel/memorymanagement.h>
#include <sortix/kernel/string.h> #include <sortix/kernel/mtable.h>
#include <sortix/kernel/syscall.h>
#include <sortix/kernel/sortedlist.h>
#include <sortix/kernel/scheduler.h>
#include <sortix/kernel/symbol.h>
#include <sortix/kernel/process.h> #include <sortix/kernel/process.h>
#include <sortix/kernel/refcount.h>
#include <sortix/kernel/scheduler.h>
#include <sortix/kernel/sortedlist.h>
#include <sortix/kernel/string.h>
#include <sortix/kernel/symbol.h>
#include <sortix/kernel/syscall.h>
#include <sortix/kernel/thread.h> #include <sortix/kernel/thread.h>
#include <sortix/kernel/time.h> #include <sortix/kernel/time.h>
#include <sortix/kernel/worker.h>
#include <sortix/clock.h>
#include <sortix/signal.h>
#include <sortix/unistd.h>
#include <sortix/fcntl.h>
#include <sortix/stat.h>
#include <sortix/fork.h>
#include <sortix/mman.h>
#include <sortix/wait.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
#include "initrd.h"
#include "elf.h" #include "elf.h"
#include "initrd.h"
namespace Sortix namespace Sortix {
bool ProcessSegment::Intersects(ProcessSegment* segments)
{ {
bool ProcessSegment::Intersects(ProcessSegment* segments)
{
for ( ProcessSegment* tmp = segments; tmp != NULL; tmp = tmp->next ) for ( ProcessSegment* tmp = segments; tmp != NULL; tmp = tmp->next )
{ {
if ( tmp->position < position + size && if ( tmp->position < position + size &&
@ -73,10 +74,10 @@ namespace Sortix
if ( next ) { return next->Intersects(segments); } if ( next ) { return next->Intersects(segments); }
return false; return false;
} }
ProcessSegment* ProcessSegment::Fork() ProcessSegment* ProcessSegment::Fork()
{ {
ProcessSegment* nextclone = NULL; ProcessSegment* nextclone = NULL;
if ( next ) if ( next )
{ {
@ -104,10 +105,10 @@ namespace Sortix
clone->size = size; clone->size = size;
return clone; return clone;
} }
Process::Process() Process::Process()
{ {
string_table = NULL; string_table = NULL;
string_table_length = 0; string_table_length = 0;
symbol_table = NULL; symbol_table = NULL;
@ -140,10 +141,10 @@ namespace Sortix
Time::InitializeProcessClocks(this); Time::InitializeProcessClocks(this);
alarm_timer.Attach(Time::GetClock(CLOCK_MONOTONIC)); alarm_timer.Attach(Time::GetClock(CLOCK_MONOTONIC));
Put(this); Put(this);
} }
Process::~Process() Process::~Process()
{ {
delete[] string_table; delete[] string_table;
delete[] symbol_table; delete[] symbol_table;
if ( alarm_timer.IsAttached() ) if ( alarm_timer.IsAttached() )
@ -160,30 +161,30 @@ namespace Sortix
assert(!root); assert(!root);
Remove(this); Remove(this);
} }
void Process::BootstrapTables(Ref<DescriptorTable> dtable, Ref<MountTable> mtable) void Process::BootstrapTables(Ref<DescriptorTable> dtable, Ref<MountTable> mtable)
{ {
ScopedLock lock(&ptrlock); ScopedLock lock(&ptrlock);
assert(!this->dtable); assert(!this->dtable);
assert(!this->mtable); assert(!this->mtable);
this->dtable = dtable; this->dtable = dtable;
this->mtable = mtable; this->mtable = mtable;
} }
void Process::BootstrapDirectories(Ref<Descriptor> root) void Process::BootstrapDirectories(Ref<Descriptor> root)
{ {
ScopedLock lock(&ptrlock); ScopedLock lock(&ptrlock);
assert(!this->root); assert(!this->root);
assert(!this->cwd); assert(!this->cwd);
this->root = root; this->root = root;
this->cwd = root; this->cwd = root;
} }
void Process__OnLastThreadExit(void* user); void Process__OnLastThreadExit(void* user);
void Process::OnThreadDestruction(Thread* thread) void Process::OnThreadDestruction(Thread* thread)
{ {
assert(thread->process == this); assert(thread->process == this);
kthread_mutex_lock(&threadlock); kthread_mutex_lock(&threadlock);
if ( thread->prevsibling ) if ( thread->prevsibling )
@ -202,41 +203,41 @@ namespace Sortix
// we handle the situation by killing ourselves. // we handle the situation by killing ourselves.
if ( !threadsleft ) if ( !threadsleft )
ScheduleDeath(); ScheduleDeath();
} }
void Process::ScheduleDeath() void Process::ScheduleDeath()
{ {
// All our threads must have exited at this point. // All our threads must have exited at this point.
assert(!firstthread); assert(!firstthread);
Worker::Schedule(Process__OnLastThreadExit, this); Worker::Schedule(Process__OnLastThreadExit, this);
} }
// Useful for killing a partially constructed process without waiting for // Useful for killing a partially constructed process without waiting for
// it to die and garbage collect its zombie. It is not safe to access this // it to die and garbage collect its zombie. It is not safe to access this
// process after this call as another thread may garbage collect it. // process after this call as another thread may garbage collect it.
void Process::AbortConstruction() void Process::AbortConstruction()
{ {
nozombify = true; nozombify = true;
ScheduleDeath(); ScheduleDeath();
} }
void Process__OnLastThreadExit(void* user) void Process__OnLastThreadExit(void* user)
{ {
return ((Process*) user)->OnLastThreadExit(); return ((Process*) user)->OnLastThreadExit();
} }
void Process::OnLastThreadExit() void Process::OnLastThreadExit()
{ {
LastPrayer(); LastPrayer();
} }
static void SwitchCurrentAddrspace(addr_t addrspace, void* user) static void SwitchCurrentAddrspace(addr_t addrspace, void* user)
{ {
((Thread*) user)->SwitchAddressSpace(addrspace); ((Thread*) user)->SwitchAddressSpace(addrspace);
} }
void Process::DeleteTimers() void Process::DeleteTimers()
{ {
for ( timer_t i = 0; i < PROCESS_TIMER_NUM_MAX; i++ ) for ( timer_t i = 0; i < PROCESS_TIMER_NUM_MAX; i++ )
{ {
if ( user_timers[i].timer.IsAttached() ) if ( user_timers[i].timer.IsAttached() )
@ -245,10 +246,10 @@ namespace Sortix
user_timers[i].timer.Detach(); user_timers[i].timer.Detach();
} }
} }
} }
void Process::LastPrayer() void Process::LastPrayer()
{ {
assert(this); assert(this);
// This must never be called twice. // This must never be called twice.
assert(!iszombie); assert(!iszombie);
@ -344,10 +345,10 @@ namespace Sortix
// If nobody is waiting for us, then simply commit suicide. // If nobody is waiting for us, then simply commit suicide.
if ( !zombify ) if ( !zombify )
delete this; delete this;
} }
void Process::ResetAddressSpace() void Process::ResetAddressSpace()
{ {
assert(Memory::GetAddressSpace() == addrspace); assert(Memory::GetAddressSpace() == addrspace);
ProcessSegment* tmp = segments; ProcessSegment* tmp = segments;
while ( tmp != NULL ) while ( tmp != NULL )
@ -359,10 +360,10 @@ namespace Sortix
} }
segments = NULL; segments = NULL;
} }
void Process::NotifyChildExit(Process* child, bool zombify) void Process::NotifyChildExit(Process* child, bool zombify)
{ {
kthread_mutex_lock(&childlock); kthread_mutex_lock(&childlock);
if ( child->prevsibling ) if ( child->prevsibling )
@ -387,25 +388,26 @@ namespace Sortix
if ( zombify ) if ( zombify )
NotifyNewZombies(); NotifyNewZombies();
} }
void Process::NotifyNewZombies() void Process::NotifyNewZombies()
{ {
ScopedLock lock(&childlock); ScopedLock lock(&childlock);
// TODO: Send SIGCHLD here? // TODO: Send SIGCHLD here?
if ( zombiewaiting ) if ( zombiewaiting )
kthread_cond_broadcast(&zombiecond); kthread_cond_broadcast(&zombiecond);
} }
pid_t Process::Wait(pid_t thepid, int* status, int options) pid_t Process::Wait(pid_t thepid, int* status, int options)
{ {
// TODO: Process groups are not supported yet. // TODO: Process groups are not supported yet.
if ( thepid < -1 || thepid == 0 ) { errno = ENOSYS; return -1; } if ( thepid < -1 || thepid == 0 ) { errno = ENOSYS; return -1; }
ScopedLock lock(&childlock); ScopedLock lock(&childlock);
// A process can only wait if it has children. // A process can only wait if it has children.
if ( !firstchild && !zombiechild ) { errno = ECHILD; return -1; } if ( !firstchild && !zombiechild )
return errno = ECHILD, -1;
// Processes can only wait for their own children to exit. // Processes can only wait for their own children to exit.
if ( 0 < thepid ) if ( 0 < thepid )
@ -419,7 +421,8 @@ namespace Sortix
for ( Process* p = zombiechild; !found && p; p = p->nextsibling ) for ( Process* p = zombiechild; !found && p; p = p->nextsibling )
if ( p->pid == thepid ) if ( p->pid == thepid )
found = true; found = true;
if ( !found ) { errno = ECHILD; return -1; } if ( !found )
return errno = ECHILD, -1;
} }
Process* zombie = NULL; Process* zombie = NULL;
@ -435,7 +438,8 @@ namespace Sortix
zombiewaiting++; zombiewaiting++;
unsigned long r = kthread_cond_wait_signal(&zombiecond, &childlock); unsigned long r = kthread_cond_wait_signal(&zombiecond, &childlock);
zombiewaiting--; zombiewaiting--;
if ( !r ) { errno = EINTR; return -1; } if ( !r )
return errno = EINTR, -1;
} }
if ( zombie->prevsibling ) if ( zombie->prevsibling )
@ -466,15 +470,15 @@ namespace Sortix
delete zombie; delete zombie;
return thepid; return thepid;
} }
pid_t SysWait(pid_t pid, int* status, int options) pid_t sys_waitpid(pid_t pid, int* status, int options)
{ {
return CurrentProcess()->Wait(pid, status, options); return CurrentProcess()->Wait(pid, status, options);
} }
void Process::Exit(int status) void Process::Exit(int status)
{ {
ScopedLock lock(&threadlock); ScopedLock lock(&threadlock);
// Status codes can only contain 8 bits according to ISO C and POSIX. // Status codes can only contain 8 bits according to ISO C and POSIX.
if ( exitstatus == -1 ) if ( exitstatus == -1 )
@ -486,25 +490,24 @@ namespace Sortix
// destroyed by SIGKILL once the system call returns. // destroyed by SIGKILL once the system call returns.
for ( Thread* t = firstthread; t; t = t->nextsibling ) for ( Thread* t = firstthread; t; t = t->nextsibling )
t->DeliverSignal(SIGKILL); t->DeliverSignal(SIGKILL);
} }
int SysExit(int status) int sys_exit(int status)
{ {
CurrentProcess()->Exit(status); CurrentProcess()->Exit(status);
return 0; return 0;
} }
bool Process::DeliverSignal(int signum) bool Process::DeliverSignal(int signum)
{ {
// TODO: How to handle signals that kill the process? // TODO: How to handle signals that kill the process?
if ( firstthread ) if ( firstthread )
return firstthread->DeliverSignal(signum); return firstthread->DeliverSignal(signum);
errno = EINIT; return errno = EINIT, false;
return false; }
}
void Process::AddChildProcess(Process* child) void Process::AddChildProcess(Process* child)
{ {
ScopedLock mylock(&childlock); ScopedLock mylock(&childlock);
ScopedLock itslock(&child->parentlock); ScopedLock itslock(&child->parentlock);
assert(!child->parent); assert(!child->parent);
@ -516,63 +519,64 @@ namespace Sortix
if ( firstchild ) if ( firstchild )
firstchild->prevsibling = child; firstchild->prevsibling = child;
firstchild = child; firstchild = child;
} }
Ref<MountTable> Process::GetMTable() Ref<MountTable> Process::GetMTable()
{ {
ScopedLock lock(&ptrlock); ScopedLock lock(&ptrlock);
assert(mtable); assert(mtable);
return mtable; return mtable;
} }
Ref<DescriptorTable> Process::GetDTable() Ref<DescriptorTable> Process::GetDTable()
{ {
ScopedLock lock(&ptrlock); ScopedLock lock(&ptrlock);
assert(dtable); assert(dtable);
return dtable; return dtable;
} }
Ref<Descriptor> Process::GetRoot() Ref<Descriptor> Process::GetRoot()
{ {
ScopedLock lock(&ptrlock); ScopedLock lock(&ptrlock);
assert(root); assert(root);
return root; return root;
} }
Ref<Descriptor> Process::GetCWD() Ref<Descriptor> Process::GetCWD()
{ {
ScopedLock lock(&ptrlock); ScopedLock lock(&ptrlock);
assert(cwd); assert(cwd);
return cwd; return cwd;
} }
void Process::SetRoot(Ref<Descriptor> newroot) void Process::SetRoot(Ref<Descriptor> newroot)
{ {
ScopedLock lock(&ptrlock); ScopedLock lock(&ptrlock);
assert(newroot); assert(newroot);
root = newroot; root = newroot;
} }
void Process::SetCWD(Ref<Descriptor> newcwd) void Process::SetCWD(Ref<Descriptor> newcwd)
{ {
ScopedLock lock(&ptrlock); ScopedLock lock(&ptrlock);
assert(newcwd); assert(newcwd);
cwd = newcwd; cwd = newcwd;
} }
Ref<Descriptor> Process::GetDescriptor(int fd) Ref<Descriptor> Process::GetDescriptor(int fd)
{ {
ScopedLock lock(&ptrlock); ScopedLock lock(&ptrlock);
assert(dtable); assert(dtable);
return dtable->Get(fd); return dtable->Get(fd);
} }
Process* Process::Fork() Process* Process::Fork()
{ {
assert(CurrentProcess() == this); assert(CurrentProcess() == this);
Process* clone = new Process; Process* clone = new Process;
if ( !clone ) { return NULL; } if ( !clone )
return NULL;
ProcessSegment* clonesegments = NULL; ProcessSegment* clonesegments = NULL;
@ -657,7 +661,6 @@ namespace Sortix
clone->symbol_table_length = symbol_table_length; clone->symbol_table_length = symbol_table_length;
} }
if ( pid == 1) if ( pid == 1)
assert(dtable->Get(1)); assert(dtable->Get(1));
@ -674,10 +677,10 @@ namespace Sortix
} }
return clone; return clone;
} }
void Process::ResetForExecute() void Process::ResetForExecute()
{ {
// TODO: Delete all threads and their stacks. // TODO: Delete all threads and their stacks.
string_table_length = 0; string_table_length = 0;
@ -688,14 +691,13 @@ namespace Sortix
DeleteTimers(); DeleteTimers();
ResetAddressSpace(); ResetAddressSpace();
} }
int Process::Execute(const char* programname, const uint8_t* program, int Process::Execute(const char* programname, const uint8_t* program,
size_t programsize, int argc, const char* const* argv, size_t programsize, int argc, const char* const* argv,
int envc, const char* const* envp, int envc, const char* const* envp,
CPU::InterruptRegisters* regs) CPU::InterruptRegisters* regs)
{ {
(void) programname;
assert(CurrentProcess() == this); assert(CurrentProcess() == this);
char* programname_clone = String::Clone(programname); char* programname_clone = String::Clone(programname);
@ -730,7 +732,8 @@ namespace Sortix
stackargv[argc] = NULL; stackargv[argc] = NULL;
if ( argvsize % 16UL ) { argvsize += 16 - (argvsize % 16UL); } if ( argvsize % 16UL )
argvsize += 16 - argvsize % 16UL;
// And then move envp onto the stack. // And then move envp onto the stack.
addr_t envppos = argvpos - argvsize - sizeof(char*) * (envc+1); addr_t envppos = argvpos - argvsize - sizeof(char*) * (envc+1);
@ -748,7 +751,8 @@ namespace Sortix
stackenvp[envc] = NULL; stackenvp[envc] = NULL;
if ( envpsize % 16UL ) { envpsize += 16 - (envpsize % 16UL); } if ( envpsize % 16UL )
envpsize += 16 - envpsize % 16UL;
stackpos = envppos - envpsize; stackpos = envppos - envpsize;
@ -757,19 +761,19 @@ namespace Sortix
ExecuteCPU(argc, stackargv, envc, stackenvp, stackpos, entry, regs); ExecuteCPU(argc, stackargv, envc, stackenvp, stackpos, entry, regs);
return 0; return 0;
} }
// TODO. This is a hack. Please remove this when execve is moved to another // TODO. This is a hack. Please remove this when execve is moved to another
// file/class, it doesn't belong here, it's a program loader ffs! // file/class, it doesn't belong here, it's a program loader ffs!
Ref<Descriptor> Process::Open(ioctx_t* ctx, const char* path, int flags, mode_t mode) Ref<Descriptor> Process::Open(ioctx_t* ctx, const char* path, int flags, mode_t mode)
{ {
// TODO: Locking the root/cwd pointers. How should that be arranged? // TODO: Locking the root/cwd pointers. How should that be arranged?
Ref<Descriptor> dir = path[0] == '/' ? root : cwd; Ref<Descriptor> dir = path[0] == '/' ? root : cwd;
return dir->open(ctx, path, flags, mode); return dir->open(ctx, path, flags, mode);
} }
int SysExecVE(const char* _filename, char* const _argv[], char* const _envp[]) int sys_execve(const char* _filename, char* const _argv[], char* const _envp[])
{ {
char* filename; char* filename;
int argc; int argc;
int envc; int envc;
@ -838,29 +842,33 @@ namespace Sortix
result = process->Execute(filename, buffer, count, argc, argv, envc, result = process->Execute(filename, buffer, count, argc, argv, envc,
envp, &regs); envp, &regs);
cleanup_buffer: cleanup_buffer:
delete[] buffer; delete[] buffer;
cleanup_desc: cleanup_desc:
desc.Reset(); desc.Reset();
cleanup_envp: cleanup_envp:
for ( int i = 0; i < envc; i++) { delete[] envp[i]; } for ( int i = 0; i < envc; i++)
delete[] envp[i];
delete[] envp; delete[] envp;
cleanup_argv: cleanup_argv:
for ( int i = 0; i < argc; i++) { delete[] argv[i]; } for ( int i = 0; i < argc; i++)
delete[] argv[i];
delete[] argv; delete[] argv;
cleanup_filename: cleanup_filename:
delete[] filename; delete[] filename;
cleanup_done: cleanup_done:
if ( !result ) { CPU::LoadRegisters(&regs); } if ( !result ) { CPU::LoadRegisters(&regs); }
return result; return result;
} }
pid_t SysTFork(int flags, tforkregs_t* regs) pid_t sys_tfork(int flags, tforkregs_t* regs)
{ {
if ( Signal::IsPending() ) { errno = EINTR; return -1; } if ( Signal::IsPending() )
return errno = EINTR, -1;
// TODO: Properly support tfork(2). // TODO: Properly support tfork(2).
if ( flags != SFFORK ) { errno = ENOSYS; return -1; } if ( flags != SFFORK )
return errno = ENOSYS, -1;
CPU::InterruptRegisters cpuregs; CPU::InterruptRegisters cpuregs;
InitializeThreadRegisters(&cpuregs, regs); InitializeThreadRegisters(&cpuregs, regs);
@ -868,7 +876,8 @@ namespace Sortix
// TODO: Is it a hack to create a new kernel stack here? // TODO: Is it a hack to create a new kernel stack here?
Thread* curthread = CurrentThread(); Thread* curthread = CurrentThread();
uint8_t* newkernelstack = new uint8_t[curthread->kernelstacksize]; uint8_t* newkernelstack = new uint8_t[curthread->kernelstacksize];
if ( !newkernelstack ) { return -1; } if ( !newkernelstack )
return -1;
Process* clone = CurrentProcess()->Fork(); Process* clone = CurrentProcess()->Fork();
if ( !clone ) { delete[] newkernelstack; return -1; } if ( !clone ) { delete[] newkernelstack; return -1; }
@ -892,38 +901,38 @@ namespace Sortix
StartKernelThread(thread); StartKernelThread(thread);
return clone->pid; return clone->pid;
} }
pid_t SysGetPID() pid_t sys_getpid()
{ {
return CurrentProcess()->pid; return CurrentProcess()->pid;
} }
pid_t Process::GetParentProcessId() pid_t Process::GetParentProcessId()
{ {
ScopedLock lock(&parentlock); ScopedLock lock(&parentlock);
if( !parent ) if( !parent )
return 0; return 0;
return parent->pid; return parent->pid;
} }
pid_t SysGetParentPID() pid_t sys_getppid()
{ {
return CurrentProcess()->GetParentProcessId(); return CurrentProcess()->GetParentProcessId();
} }
pid_t nextpidtoallocate; pid_t nextpidtoallocate;
kthread_mutex_t pidalloclock; kthread_mutex_t pidalloclock;
pid_t Process::AllocatePID() pid_t Process::AllocatePID()
{ {
ScopedLock lock(&pidalloclock); ScopedLock lock(&pidalloclock);
return nextpidtoallocate++; return nextpidtoallocate++;
} }
// TODO: This is not thread safe. // TODO: This is not thread safe.
pid_t Process::HackGetForegroundProcess() pid_t Process::HackGetForegroundProcess()
{ {
for ( pid_t i = nextpidtoallocate; 1 <= i; i-- ) for ( pid_t i = nextpidtoallocate; 1 <= i; i-- )
{ {
Process* process = Get(i); Process* process = Get(i);
@ -936,62 +945,71 @@ namespace Sortix
return i; return i;
} }
return 0; return 0;
} }
int ProcessCompare(Process* a, Process* b) int ProcessCompare(Process* a, Process* b)
{ {
if ( a->pid < b->pid ) { return -1; } if ( a->pid < b->pid )
if ( a->pid > b->pid ) { return 1; } return -1;
if ( a->pid > b->pid )
return 1;
return 0; return 0;
} }
int ProcessPIDCompare(Process* a, pid_t pid) int ProcessPIDCompare(Process* a, pid_t pid)
{ {
if ( a->pid < pid ) { return -1; } if ( a->pid < pid )
if ( a->pid > pid ) { return 1; } return -1;
if ( a->pid > pid )
return 1;
return 0; return 0;
} }
SortedList<Process*>* pidlist; SortedList<Process*>* pidlist;
Process* Process::Get(pid_t pid) Process* Process::Get(pid_t pid)
{ {
ScopedLock lock(&pidalloclock); ScopedLock lock(&pidalloclock);
size_t index = pidlist->Search(ProcessPIDCompare, pid); size_t index = pidlist->Search(ProcessPIDCompare, pid);
if ( index == SIZE_MAX ) { return NULL; } if ( index == SIZE_MAX )
return NULL;
return pidlist->Get(index); return pidlist->Get(index);
} }
bool Process::Put(Process* process) bool Process::Put(Process* process)
{ {
ScopedLock lock(&pidalloclock); ScopedLock lock(&pidalloclock);
return pidlist->Add(process); return pidlist->Add(process);
} }
void Process::Remove(Process* process) void Process::Remove(Process* process)
{ {
ScopedLock lock(&pidalloclock); ScopedLock lock(&pidalloclock);
size_t index = pidlist->Search(process); size_t index = pidlist->Search(process);
assert(index != SIZE_MAX); assert(index != SIZE_MAX);
pidlist->Remove(index); pidlist->Remove(index);
} }
void* SysSbrk(intptr_t increment) void* sys_sbrk(intptr_t increment)
{ {
Process* process = CurrentProcess(); Process* process = CurrentProcess();
ProcessSegment* dataseg = NULL; ProcessSegment* dataseg = NULL;
for ( ProcessSegment* iter = process->segments; iter; iter = iter->next ) for ( ProcessSegment* iter = process->segments; iter; iter = iter->next )
{ {
if ( !iter->type == SEG_DATA ) { continue; } if ( !iter->type == SEG_DATA )
if ( dataseg && iter->position < dataseg->position ) { continue; } continue;
if ( dataseg && iter->position < dataseg->position )
continue;
dataseg = iter; dataseg = iter;
} }
if ( !dataseg ) { errno = ENOMEM; return (void*) -1UL; } if ( !dataseg )
return errno = ENOMEM, (void*) -1UL;
addr_t currentend = dataseg->position + dataseg->size; addr_t currentend = dataseg->position + dataseg->size;
addr_t newend = currentend + increment; addr_t newend = currentend + increment;
if ( newend < dataseg->position ) { errno = EINVAL; return (void*) -1UL; } if ( newend < dataseg->position )
return errno = EINVAL, (void*) -1UL;
if ( newend < currentend ) if ( newend < currentend )
{ {
addr_t unmapfrom = Page::AlignUp(newend); addr_t unmapfrom = Page::AlignUp(newend);
@ -1011,50 +1029,50 @@ namespace Sortix
size_t mapbytes = Page::AlignUp(newend - mapfrom); size_t mapbytes = Page::AlignUp(newend - mapfrom);
int prot = PROT_FORK | PROT_READ | PROT_WRITE | PROT_KREAD | PROT_KWRITE; int prot = PROT_FORK | PROT_READ | PROT_WRITE | PROT_KREAD | PROT_KWRITE;
if ( !Memory::MapRange(mapfrom, mapbytes, prot) ) if ( !Memory::MapRange(mapfrom, mapbytes, prot) )
{
return (void*) -1UL; return (void*) -1UL;
} }
} }
}
dataseg->size += increment; dataseg->size += increment;
return (void*) newend; return (void*) newend;
} }
size_t SysGetPageSize() size_t sys_getpagesize()
{ {
return Page::Size(); return Page::Size();
} }
mode_t sys_umask(mode_t newmask) mode_t sys_umask(mode_t newmask)
{ {
Process* process = CurrentProcess(); Process* process = CurrentProcess();
ScopedLock lock(&process->idlock); ScopedLock lock(&process->idlock);
mode_t oldmask = process->umask; mode_t oldmask = process->umask;
process->umask = newmask & 0666; process->umask = newmask & 0666;
return oldmask; return oldmask;
} }
void Process::Init() void Process::Init()
{ {
Syscall::Register(SYSCALL_EXEC, (void*) SysExecVE); Syscall::Register(SYSCALL_EXEC, (void*) sys_execve);
Syscall::Register(SYSCALL_TFORK, (void*) SysTFork); Syscall::Register(SYSCALL_EXIT, (void*) sys_exit);
Syscall::Register(SYSCALL_GETPID, (void*) SysGetPID); Syscall::Register(SYSCALL_GET_PAGE_SIZE, (void*) sys_getpagesize);
Syscall::Register(SYSCALL_GETPPID, (void*) SysGetParentPID); Syscall::Register(SYSCALL_GETPID, (void*) sys_getpid);
Syscall::Register(SYSCALL_EXIT, (void*) SysExit); Syscall::Register(SYSCALL_GETPPID, (void*) sys_getppid);
Syscall::Register(SYSCALL_SBRK, (void*) sys_sbrk);
Syscall::Register(SYSCALL_TFORK, (void*) sys_tfork);
Syscall::Register(SYSCALL_UMASK, (void*) sys_umask); Syscall::Register(SYSCALL_UMASK, (void*) sys_umask);
Syscall::Register(SYSCALL_WAIT, (void*) SysWait); Syscall::Register(SYSCALL_WAIT, (void*) sys_waitpid);
Syscall::Register(SYSCALL_SBRK, (void*) SysSbrk);
Syscall::Register(SYSCALL_GET_PAGE_SIZE, (void*) SysGetPageSize);
pidalloclock = KTHREAD_MUTEX_INITIALIZER; pidalloclock = KTHREAD_MUTEX_INITIALIZER;
nextpidtoallocate = 0; nextpidtoallocate = 0;
pidlist = new SortedList<Process*>(ProcessCompare); pidlist = new SortedList<Process*>(ProcessCompare);
if ( !pidlist ) { Panic("could not allocate pidlist\n"); } if ( !pidlist )
} Panic("could not allocate pidlist\n");
addr_t Process::AllocVirtualAddr(size_t size)
{
return (mmapfrom -= size);
}
} }
addr_t Process::AllocVirtualAddr(size_t size)
{
return mmapfrom -= size;
}
} // namespace Sortix