X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=AcessNative%2Fld-acess_src%2Fsyscalls.c;h=c649f28f600cc5c2880c7c6a7de75185acb14bb4;hb=c7acbe49842c871244d76ce9dd7e4e9e70ec3a97;hp=7bb3b03945c3559d1d26fe4a8141c0e56fede3d6;hpb=b4e2712f6a0849de53207ad50a38c9f468f22651;p=tpg%2Facess2.git diff --git a/AcessNative/ld-acess_src/syscalls.c b/AcessNative/ld-acess_src/syscalls.c index 7bb3b039..c649f28f 100644 --- a/AcessNative/ld-acess_src/syscalls.c +++ b/AcessNative/ld-acess_src/syscalls.c @@ -8,9 +8,24 @@ #include #include #include +#include +#ifndef __WIN32__ +# include // posix_spawn +#endif #include "request.h" +#if SYSCALL_TRACE #define DEBUG(str, x...) Debug(str, x) +#else +#define DEBUG(...) do{}while(0) +#endif + +#define assert(cnd) do{ \ + if( !(cnd) ) { \ + fprintf(stderr, "%s:%i - assert failed - " #cnd, __FILE__, __LINE__);\ + exit(-1); \ + } \ +}while(0) #define MAX_FPS 16 @@ -29,11 +44,13 @@ const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const int direction = 0; // 0: Invalid, 1: Out, 2: In, 3: Out char *str; int len; - + // Eat whitespace while(*ArgTypes && *ArgTypes == ' ') ArgTypes ++; if( *ArgTypes == '\0' ) return ArgTypes; +// DEBUG("ArgTypes = '%s'", ArgTypes); + // Get direction switch(*ArgTypes) { @@ -105,7 +122,7 @@ const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const break; // Data (special handling) case 'd': - len = va_arg(*Args, int); + len = va_arg(*Args, size_t); str = va_arg(*Args, char*); // Save the pointer for later @@ -113,7 +130,7 @@ const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const // Create parameter block Dest->Type = ARG_TYPE_DATA; - Dest->Length = len; + Dest->Length = str ? len : 0; Dest->Flags = 0; if( direction & 2 ) Dest->Flags |= ARG_FLAG_RETURN; @@ -121,7 +138,7 @@ const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const // Has data? if( direction & 1 ) { - if( DataDest ) + if( DataDest && str ) memcpy(DataDest, str, len); } else @@ -153,7 +170,7 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...) { va_list args; int paramCount, dataLength; - int retCount = 1, retLength = sizeof(uint64_t); + int retCount = 2, retLength = sizeof(uint64_t) + sizeof(uint32_t); void **retPtrs; // Pointers to return buffers const char *str; tRequestHeader *req; @@ -203,6 +220,7 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...) req->ClientID = 0; //< Filled later req->CallID = SyscallID; req->NParams = paramCount; + req->MessageLength = dataLength; dataPtr = &req->Params[paramCount]; // Fill `output` and `input` @@ -225,33 +243,33 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...) } va_end(args); - // Send syscall request + // --- Send syscall request if( SendRequest(req, dataLength, retLength) < 0 ) { fprintf(stderr, "syscalls.c: SendRequest failed (SyscallID = %i)\n", SyscallID); exit(127); } - // Parse return value - dataPtr = &req->Params[req->NParams]; - retValue = 0; - if( req->NParams >= 1 ) - { - switch(req->Params[0].Type) - { - case ARG_TYPE_INT64: - retValue = *(uint64_t*)dataPtr; - dataPtr += req->Params[0].Length; - break; - case ARG_TYPE_INT32: - retValue = *(uint32_t*)dataPtr; - dataPtr += req->Params[0].Length; - break; - } - } + Debug("req->NParams = %i", req->NParams); + assert(req->NParams >= 2); + // return + assert(req->Params[0].Type == ARG_TYPE_INT64); + assert(req->Params[0].Length == sizeof(uint64_t)); + retValue = *(uint64_t*)dataPtr; + dataPtr += sizeof(uint64_t); + // errno + assert(req->Params[1].Type == ARG_TYPE_INT32); + assert(req->Params[1].Length == sizeof(uint32_t)); + acess__errno = *(uint32_t*)dataPtr; + dataPtr += sizeof(uint32_t); // Write changes to buffers + if( req->NParams - 2 != retCount ) { + fprintf(stderr, "syscalls.c: Return count inbalance (%i - 1 != exp %i) [Call %i]\n", + req->NParams, retCount, SyscallID); + exit(127); + } retCount = 0; - for( i = 1; i < req->NParams; i ++ ) + for( i = 2; i < req->NParams; i ++ ) { #if 0 int j; @@ -260,6 +278,7 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...) printf(" %02x", ((uint8_t*)dataPtr)[j]); printf("\n"); #endif + assert( req->Params[i].Type == ARG_TYPE_DATA ); memcpy( retPtrs[retCount++], dataPtr, req->Params[i].Length ); dataPtr += req->Params[i].Length; } @@ -267,7 +286,7 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...) free( req ); free( retPtrs ); - DEBUG(": %llx", retValue); + DEBUG(": %i 0x%llx", SyscallID, retValue); return retValue; } @@ -314,3 +333,24 @@ uint64_t native_tell(int FD) { return ftell( gaSyscall_LocalFPs[FD] ); } + +int native_execve(const char *filename, const char *const argv[], const char *const envp[]) +{ + int ret; + ret = execve(filename, (void*)argv, (void*)envp); + perror("native_execve"); + return ret; +} + +int native_spawn(const char *filename, const char *const argv[], const char *const envp[]) +{ + int rv; + + #if __WIN32__ + rv = _spawnve(_P_NOWAIT, filename, argv, envp); + #else + rv = posix_spawn(NULL, filename, NULL, NULL, (void*)argv, (void*)envp); + #endif + + return rv; +}