From 9b61291b136d9fdc196ddab582cdb6cff8b70b09 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 12 Oct 2012 20:29:30 +0800 Subject: [PATCH] Acessnative - Sys_Spawn implimented --- AcessNative/acesskernel_src/server.c | 5 +++- AcessNative/acesskernel_src/syscalls.c | 10 ++++++- AcessNative/acesskernel_src/threads.c | 32 +++++++++++++++++++--- AcessNative/acesskernel_src/vfs_handle.c | 34 ++++++++++++++++++++++++ AcessNative/ld-acess_src/exports.c | 11 +++++--- AcessNative/ld-acess_src/request.c | 1 + 6 files changed, 83 insertions(+), 10 deletions(-) diff --git a/AcessNative/acesskernel_src/server.c b/AcessNative/acesskernel_src/server.c index 0930fd58..45806e2b 100644 --- a/AcessNative/acesskernel_src/server.c +++ b/AcessNative/acesskernel_src/server.c @@ -161,7 +161,10 @@ int Server_WorkerThread(void *ClientPtr) tRequestHeader *hdr = (void*)lbuf; size_t len = recv(Client->Socket, (void*)hdr, sizeof(*hdr), 0); // Log_Debug("Server", "%i bytes of header", len); - if( len == 0 ) break; + if( len == 0 ) { + Log_Notice("Server", "Zero RX on %i (worker %p)", Client->Socket, Client); + break; + } if( len == -1 ) { perror("recv header"); // Log_Warning("Server", "recv() error - %s", strerror(errno)); diff --git a/AcessNative/acesskernel_src/syscalls.c b/AcessNative/acesskernel_src/syscalls.c index 886eb1bf..d14a1d9f 100644 --- a/AcessNative/acesskernel_src/syscalls.c +++ b/AcessNative/acesskernel_src/syscalls.c @@ -15,6 +15,7 @@ // === IMPORTS === extern int Threads_Fork(void); // AcessNative only function +extern int Threads_Spawn(int nFD, int FDs[], const void *info); // === TYPES === typedef int (*tSyscallHandler)(Uint *Errno, const char *Format, void *Args, int *Sizes); @@ -193,6 +194,13 @@ SYSCALL1(Syscall_AN_Fork, "d", int *, return *a0; ); +SYSCALL3(Syscall_AN_Spawn, "ddd", int *, int *, void *, + if(Sizes[0] < sizeof(int)) + return -1; + *a0 = Threads_Spawn(Sizes[1] / sizeof(int), a1, a2); + return *a0; +); + SYSCALL2(Syscall_SendMessage, "id", int, void *, return Proc_SendMessage(a0, Sizes[1], a1); ); @@ -247,7 +255,7 @@ const tSyscallHandler caSyscalls[] = { Syscall_Sleep, Syscall_AN_Fork, - NULL, + Syscall_AN_Spawn, Syscall_SendMessage, Syscall_GetMessage, diff --git a/AcessNative/acesskernel_src/threads.c b/AcessNative/acesskernel_src/threads.c index ecc9f331..661d584b 100644 --- a/AcessNative/acesskernel_src/threads.c +++ b/AcessNative/acesskernel_src/threads.c @@ -10,6 +10,8 @@ #include #include #include "../../KernelLand/Kernel/include/semaphore.h" +typedef signed long long int time_t; +#include "../../Usermode/Libraries/ld-acess.so_src/include_exp/acess/syscall_types.h" #include #include #include @@ -19,7 +21,8 @@ #define THREAD_EVENT_WAKEUP 0x80000000 // === IMPORTS === -void VFS_CloneHandleList(int PID); +extern void VFS_CloneHandleList(int PID); +extern void VFS_CloneHandlesFromList(int PID, int nFD, int FDs[]); // === STRUCTURES === // === PROTOTYPES === @@ -264,13 +267,34 @@ int Threads_Fork(void) { tThread *thread = Threads_CloneTCB(gpCurrentThread); thread->PID = thread->TID; + // Duplicate the VFS handles (and nodes) from vfs_handle.c - VFS_CloneHandleList(thread->PID); return thread->PID; } +int Threads_Spawn(int nFD, int FDs[], struct s_sys_spawninfo *info) +{ + tThread *thread = Threads_CloneTCB(gpCurrentThread); + thread->PID = thread->TID; + if( info ) + { + // TODO: PGID? + //if( info->flags & SPAWNFLAG_NEWPGID ) + // thread->PGID = thread->PID; + if( info->gid && thread->UID == 0 ) + thread->GID = info->gid; + if( info->uid && thread->UID == 0 ) // last because ->UID is used above + thread->UID = info->uid; + } + + VFS_CloneHandlesFromList(thread->PID, nFD, FDs); + + Log_Debug("Threads", "_spawn: %i", thread->PID); + return thread->PID; +} + // -------------------------------------------------------------------- // Mutexes // -------------------------------------------------------------------- @@ -335,8 +359,8 @@ Uint32 Threads_WaitEvents(Uint32 Mask) void Threads_PostEvent(tThread *Thread, Uint32 Events) { Thread->Events |= Events; - Log_Debug("Threads", "Trigger event %x (->Events = %p) on %p", Events, Thread->Events, Thread); - +// Log_Debug("Threads", "Trigger event %x (->Events = %p) on %p", Events, Thread->Events, Thread); + if( Events == 0 || Thread->WaitMask & Events ) { Threads_Glue_SemSignal( Thread->EventSem, 1 ); // Log_Debug("Threads", "Waking %p(%i %s)", Thread, Thread->TID, Thread->ThreadName); diff --git a/AcessNative/acesskernel_src/vfs_handle.c b/AcessNative/acesskernel_src/vfs_handle.c index cfe04898..fc881ab9 100644 --- a/AcessNative/acesskernel_src/vfs_handle.c +++ b/AcessNative/acesskernel_src/vfs_handle.c @@ -88,6 +88,40 @@ void VFS_CloneHandleList(int PID) } } +void VFS_CloneHandlesFromList(int PID, int nFD, int FDs[]) +{ + tUserHandles *ent; + tUserHandles *cur; + int i, maxhandles; + + cur = VFS_int_GetUserHandles(Threads_GetPID(), 0); + if(!cur) return ; // Don't need to do anything if the current list is empty + + ent = VFS_int_GetUserHandles(PID, 1); + + maxhandles = *Threads_GetMaxFD(); + if( nFD > maxhandles ) + nFD = maxhandles; + for( i = 0; i < nFD; i ++ ) + { + if( FDs[i] >= maxhandles ) { + ent->Handles[i].Node = NULL; + continue ; + } + memcpy(&ent->Handles[i], &cur->Handles[ FDs[i] ], sizeof(tVFS_Handle)); + } + for( ; i < maxhandles; i ++ ) + cur->Handles[i].Node = NULL; + + for( i = 0; i < maxhandles; i ++ ) + { + if(!cur->Handles[i].Node) continue; + + if(ent->Handles[i].Node->Type->Reference) + ent->Handles[i].Node->Type->Reference(ent->Handles[i].Node); + } +} + /** * \fn tVFS_Handle *VFS_GetHandle(int FD) * \brief Gets a pointer to the handle information structure diff --git a/AcessNative/ld-acess_src/exports.c b/AcessNative/ld-acess_src/exports.c index b75b8fdf..07662a5b 100644 --- a/AcessNative/ld-acess_src/exports.c +++ b/AcessNative/ld-acess_src/exports.c @@ -256,15 +256,18 @@ int acess_execve(char *path, char **argv, const char **envp) int acess__SysSpawn(const char *binary, const char **argv, const char **envp, int nfd, int fds[], struct s_sys_spawninfo *info) { + int argc = 0; + while( argv[argc++] ); + + Debug("_SysSpawn('%s', %p (%i), %p, %i, %p, %p)", + binary, argv, argc, envp, nfd, fds, info); + int kernel_tid; int newID; - newID = _Syscall(SYS_AN_SPAWN, "d>d", sizeof(int), &kernel_tid, + newID = _Syscall(SYS_AN_SPAWN, "d >d", sizeof(int), &kernel_tid, nfd*sizeof(int), fds, info ? sizeof(*info) : 0, info); - int argc = 0; - while( argv[argc++] ); - const char *new_argv[5+argc+1]; int new_argc = 0, i; char client_id_str[11]; diff --git a/AcessNative/ld-acess_src/request.c b/AcessNative/ld-acess_src/request.c index c9e85657..5bcf8cd3 100644 --- a/AcessNative/ld-acess_src/request.c +++ b/AcessNative/ld-acess_src/request.c @@ -309,6 +309,7 @@ int ReadData(void *Dest, int MaxLength, int Timeout) } if( ret == 0 ) { fprintf(stderr, "[ERROR %i] Connection closed.\n", giSyscall_ClientID); + close(gSocket); exit(0); } -- 2.20.1