AcessNative - Spawn in libacess-native (with AN_GETPATH syscall)
[tpg/acess2.git] / AcessNative / ld-acess_src / syscalls.c
index 3fdbc72..60b7d95 100644 (file)
@@ -9,19 +9,24 @@
 #include <string.h>
 #include <stddef.h>
 #include <unistd.h>
+#ifndef __WIN32__
+# include <spawn.h>    // 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"\n", __FILE__, __LINE__);\
+               exit(-1); \
+       } \
+}while(0)
 
 #define        MAX_FPS 16
 
 // === Types ===
 
 // === IMPORTS ===
+extern int     gbSyscallDebugEnabled;
 
 // === GLOBALS ===
 FILE   *gaSyscall_LocalFPs[MAX_FPS];
@@ -160,7 +165,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;
@@ -233,38 +238,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;
-               }       
-       }
+       dataPtr = (void*)&req->Params[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 - 1 != retCount ) {
+       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;
@@ -273,6 +273,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;
        }
@@ -280,7 +281,9 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...)
        free( req );
        free( retPtrs );
        
-       DEBUG(": %i 0x%llx", SyscallID, retValue);
+       if( gbSyscallDebugEnabled ) {
+               SYSTRACE(": %i 0x%llx", SyscallID, retValue);
+       }
        
        return retValue;
 }
@@ -335,3 +338,22 @@ int native_execve(const char *filename, const char *const argv[], const char *co
        perror("native_execve");
        return ret;
 }
+
+int native_spawn(const char *filename, const char *const argv[], const char *const envp[])
+{
+       int rv;
+
+       fprintf(stderr, "native_spawn('%s')\n", filename);
+
+       #if __WIN32__
+       rv = _spawnve(_P_NOWAIT, filename, argv, envp);
+       #else
+       rv = posix_spawn(NULL, filename, NULL, NULL, (void*)argv, (void*)envp);
+       #endif
+       
+       if( rv == 0 ) {
+               perror("native_spawn");
+       }
+       
+       return rv;
+}

UCC git Repository :: git.ucc.asn.au