X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Fsyscalls.c;h=492c33e3d606d95b81b1d424f7ba2b9c46d7c6a4;hb=3f47fd7edcc581911a23ca075a463c5c8de9ab9a;hp=ddcdfa2d4c145324a5a35111d73ac53a6e63c96f;hpb=c90736022b1f62a99b15c8613aa7e3f514e01fc9;p=tpg%2Facess2.git diff --git a/Kernel/syscalls.c b/Kernel/syscalls.c index ddcdfa2d..492c33e3 100644 --- a/Kernel/syscalls.c +++ b/Kernel/syscalls.c @@ -11,39 +11,54 @@ // === IMPORTS === extern int Proc_Clone(Uint *Err, Uint Flags); +extern int Threads_WaitTID(int TID, int *status); extern Uint Proc_SendMessage(Uint *Err, Uint Dest, Uint Length, void *Data); extern int Proc_GetMessage(Uint *Err, Uint *Source, void *Buffer); extern int Proc_Execve(char *File, char **ArgV, char **EnvP); extern Uint Binary_Load(char *file, Uint *entryPoint); +extern int VFS_FInfo(int FD, void *Dest, int MaxACLs); +extern int VFS_GetACL(int FD, void *Dest); +extern int VFS_ChDir(char *Dest); +extern int Threads_SetName(char *NewName); +extern int Threads_GetPID(); +extern int Threads_GetTID(); +extern int Threads_GetUID(); +extern int Threads_GetGID(); + +// === PROTOTYPES === + int Syscall_ValidString(Uint Addr); + int Syscall_Valid(int Size, Uint Addr); // === CODE === +// TODO: Do sanity checking on arguments, ATM the user can really fuck with the kernel void SyscallHandler(tSyscallRegs *Regs) { Uint64 ret = 0; Uint err = 0; #if DEBUG - ENTER("iThread iNum", gCurrentThread->TID, Regs->Num); + ENTER("iThread iNum", Threads_GetTID(), Regs->Num); if(Regs->Num < NUM_SYSCALLS) LOG("Syscall %s", cSYSCALL_NAMES[Regs->Num]); LOG("Arg1: 0x%x, Arg2: 0x%x, Arg3: 0x%x", Regs->Arg1, Regs->Arg2, Regs->Arg3); #endif + switch(Regs->Num) { // -- Exit the current thread - case SYS_EXIT: Proc_Exit(); break; + case SYS_EXIT: Threads_Exit(); break; // -- Put the current thread to sleep - case SYS_SLEEP: Proc_Sleep(); Log(" SyscallHandler: %i is alive", gCurrentThread->TID); break; + case SYS_SLEEP: Threads_Sleep(); break; // -- Yield current timeslice - case SYS_YIELD: Proc_Yield(); break; + case SYS_YIELD: Threads_Yield(); break; // -- Clone the current thread case SYS_CLONE: // Call clone system call ret = Proc_Clone(&err, Regs->Arg1); // Change user stack if requested - if(ret == 0 && Regs->Arg2) + if(ret == 0 && !(Regs->Arg2 & CLONE_VM)) Regs->StackPointer = Regs->Arg2; break; @@ -53,22 +68,32 @@ void SyscallHandler(tSyscallRegs *Regs) ret = -1; break; + // -- Wait for a thread + case SYS_WAITTID: + ret = Threads_WaitTID(Regs->Arg1, (void*)Regs->Arg2); + break; + + // -- Get the physical address of a page case SYS_GETPHYS: ret = MM_GetPhysAddr(Regs->Arg1); break; + // -- Map an address case SYS_MAP: MM_Map(Regs->Arg1, Regs->Arg2); break; + // -- Allocate an address case SYS_ALLOCATE: ret = MM_Allocate(Regs->Arg1); break; + // -- Unmap an address case SYS_UNMAP: MM_Deallocate(Regs->Arg1); break; // -- Get Thread/Process IDs - case SYS_GETTID: ret = gCurrentThread->TID; break; - case SYS_GETPID: ret = gCurrentThread->TGID; break; + case SYS_GETTID: ret = Threads_GetTID(); break; + case SYS_GETPID: ret = Threads_GetPID(); break; + // -- Get User/Group IDs - case SYS_GETUID: ret = gCurrentThread->UID; break; - case SYS_GETGID: ret = gCurrentThread->GID; break; + case SYS_GETUID: ret = Threads_GetUID(); break; + case SYS_GETGID: ret = Threads_GetGID(); break; // -- Send Message case SYS_SENDMSG: @@ -83,16 +108,7 @@ void SyscallHandler(tSyscallRegs *Regs) case SYS_SETNAME: // Sanity Check if(!Regs->Arg1) { ret = -1; err = -EINVAL; break; } - // Lock Process - LOCK( &gCurrentThread->IsLocked ); - // Free old name - if(gCurrentThread->ThreadName && (Uint)gCurrentThread->ThreadName > 0xE0800000) - free(gCurrentThread->ThreadName); - // Change name - gCurrentThread->ThreadName = malloc( strlen( (char*)Regs->Arg1 ) + 1 ); - strcpy(gCurrentThread->ThreadName, (char*)Regs->Arg1); - // Unlock - RELEASE( &gCurrentThread->IsLocked ); + Threads_SetName( (void*)Regs->Arg1 ); break; // --- @@ -132,6 +148,39 @@ void SyscallHandler(tSyscallRegs *Regs) #endif break; + case SYS_FINFO: + ret = VFS_FInfo( Regs->Arg1, (void*)Regs->Arg2, Regs->Arg3 ); + break; + + // Get ACL Value + case SYS_GETACL: + if( !Syscall_Valid(8, Regs->Arg1) ) { + err = -EINVAL; + ret = -1; + break; + } + ret = VFS_GetACL( Regs->Arg1, (void*)Regs->Arg2 ); + break; + + // Read Directory + case SYS_READDIR: + if( !Syscall_ValidString(Regs->Arg2) ) { + err = -EINVAL; + ret = -1; + break; + } + ret = VFS_ReadDir( Regs->Arg1, (void*)Regs->Arg2 ); + break; + + // Change Directory + case SYS_CHDIR: + if( !Syscall_ValidString(Regs->Arg1) ) { + err = -EINVAL; + ret = -1; + break; + } + ret = VFS_ChDir( (void*)Regs->Arg1 ); + break; // -- Debug case SYS_DEBUG: @@ -143,7 +192,7 @@ void SyscallHandler(tSyscallRegs *Regs) default: Warning("SyscallHandler: Unknown System Call %i", Regs->Num); if(Regs->Num < NUM_SYSCALLS) - Warning(" Syscall %s", cSYSCALL_NAMES[Regs->Num]); + Warning(" Syscall '%s'", cSYSCALL_NAMES[Regs->Num]); err = -ENOSYS; ret = -1; break; @@ -161,3 +210,36 @@ void SyscallHandler(tSyscallRegs *Regs) #endif } +/** + * \fn int Syscall_ValidString(Uint Addr) + * \brief Checks if a memory address contains a valid string + */ +int Syscall_ValidString(Uint Addr) +{ + // Check 1st page + if(!MM_GetPhysAddr(Addr)) return 0; + + // Traverse String + while(*(char*)Addr) + { + if(!MM_GetPhysAddr(Addr)) return 0; + // Increment string pointer + Addr ++; + } + + return 1; +} + +/** + * \fn int Syscall_Valid(int Size, Uint Addr) + * \brief Checks if a memory address is valid + */ +int Syscall_Valid(int Size, Uint Addr) +{ + while(Size--) + { + if(!MM_GetPhysAddr(Addr)) return 0; + Addr ++; + } + return 1; +}