AcessNative - Huge changes, cleaning up and getting it to work
authorJohn Hodge <[email protected]>
Sat, 7 May 2011 10:05:04 +0000 (18:05 +0800)
committerJohn Hodge <[email protected]>
Sat, 7 May 2011 10:07:49 +0000 (18:07 +0800)
- Restructure to the client IDs (now Acess PIDs)
- Fixing up fork() behavior
- Implemented waittid()
- Fixed some bugs with video
- Implemented NativeFS
- Many other changes that I can't remember

22 files changed:
AcessNative/acesskernel_src/Makefile
AcessNative/acesskernel_src/helpers.c
AcessNative/acesskernel_src/include/arch.h
AcessNative/acesskernel_src/include/heap.h
AcessNative/acesskernel_src/keyboard.c
AcessNative/acesskernel_src/main.c
AcessNative/acesskernel_src/nativefs.c
AcessNative/acesskernel_src/server.c
AcessNative/acesskernel_src/syscalls.c
AcessNative/acesskernel_src/threads.c
AcessNative/acesskernel_src/ui_sdl.c
AcessNative/acesskernel_src/vfs_handle.c
AcessNative/acesskernel_src/video.c
AcessNative/ld-acess_src/Makefile
AcessNative/ld-acess_src/binary.c
AcessNative/ld-acess_src/common.h
AcessNative/ld-acess_src/elf.c
AcessNative/ld-acess_src/main.c
AcessNative/ld-acess_src/request.c
AcessNative/ld-acess_src/request.h
AcessNative/ld-acess_src/syscalls.c
AcessNative/syscalls.h

index c69cf06..1c92b47 100644 (file)
@@ -7,8 +7,9 @@ endif
 \r
 KERNEL_SRC = ../../Kernel/\r
 \r
-KERNEL_OBJ := logging.o adt.o lib.o drvutil.o\r
-KERNEL_OBJ += vfs/main.o vfs/open.o vfs/acls.o vfs/io.o vfs/dir.o vfs/nodecache.o vfs/mount.o vfs/memfile.o\r
+KERNEL_OBJ := logging.o adt.o lib.o drvutil.o debug.o\r
+KERNEL_OBJ += vfs/main.o vfs/open.o vfs/acls.o vfs/io.o vfs/dir.o\r
+KERNEL_OBJ += vfs/nodecache.o vfs/mount.o vfs/memfile.o vfs/select.o\r
 KERNEL_OBJ += vfs/fs/root.o vfs/fs/devfs.o\r
 KERNEL_OBJ += drv/vterm.o drv/fifo.o drv/proc.o\r
 \r
@@ -17,6 +18,8 @@ OBJ += video.o keyboard.o mouse.o nativefs.o vfs_handle.o ui_sdl.o
 OBJ += $(addprefix $(KERNEL_SRC),$(KERNEL_OBJ))\r
 \r
 OBJ := $(addsuffix .$(PLATFORM),$(OBJ))\r
+DEPFILES  = $(filter %.o.$(PLATFORM),$(OBJ))\r
+DEPFILES := $(DEPFILES:%.o.$(PLATFORM)=%.d.$(PLATFORM))\r
 \r
 CPPFLAGS += -I include/ -I $(KERNEL_SRC)include/\r
 CFLAGS += -Wall -g\r
@@ -38,7 +41,10 @@ clean:
        $(RM) $(BIN) $(OBJ)\r
 \r
 $(BIN): $(OBJ)\r
-       $(CC) $(LDFLAGS) -o $@ $(OBJ)\r
+       @echo [LINK] -o $@\r
+       @$(CC) $(LDFLAGS) -o $@ $(OBJ)\r
 \r
 %.o.$(PLATFORM): %.c\r
-       $(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS)\r
+       @echo [CC] -o $@\r
+       @$(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS)\r
+       @$(CC) -M $(CPPFLAGS) -MT $@ -o $*.d.$(PLATFORM) $<\r
index e598ef1..b08906c 100644 (file)
@@ -10,6 +10,7 @@
 #include <stdarg.h>
 #include <sys/time.h>
 
+#if 0
 void LogF(const char *Fmt, ...)
 {
        va_list args;
@@ -51,7 +52,25 @@ void Panic(const char *Format, ...)
 
 void Debug_SetKTerminal(const char *Path)
 {
-       // Ignored, kernel debug goes to stdout
+       // Ignored, kernel debug goes to stdout instead of a virtual terminal
+}
+#endif
+
+void KernelPanic_SetMode(void)
+{
+       // NOP - No need
+}
+void KernelPanic_PutChar(char ch)
+{
+       fprintf(stderr, "%c", ch);
+}
+void Debug_PutCharDebug(char ch)
+{
+       printf("%c", ch);
+}
+void Debug_PutStringDebug(const char *String)
+{
+       printf("%s", String);
 }
 
 void *Heap_Allocate(const char *File, int Line, int ByteCount)
@@ -59,6 +78,21 @@ void *Heap_Allocate(const char *File, int Line, int ByteCount)
        return malloc(ByteCount);
 }
 
+void *Heap_AllocateZero(const char *File, int Line, int ByteCount)
+{
+       return calloc(ByteCount, 1);
+}
+
+void *Heap_Reallocate(const char *File, int Line, void *Ptr, int Bytes)
+{
+       return realloc(Ptr, Bytes);
+}
+
+void Heap_Deallocate(void *Ptr)
+{
+       free(Ptr);
+}
+
 tPAddr MM_GetPhysAddr(tVAddr VAddr)
 {
        return VAddr;   // HACK!
index a6685b2..849eba8 100644 (file)
@@ -28,10 +28,10 @@ typedef intptr_t    tPAddr;
 
 typedef        int     BOOL;
 
-typedef uint32_t       tTID;
-typedef uint32_t       tPID;
-typedef uint32_t       tUID;
-typedef uint32_t       tGID;
+//typedef uint32_t     tTID;
+//typedef uint32_t     tPID;
+//typedef uint32_t     tUID;
+//typedef uint32_t     tGID;
 
 struct sShortSpinlock
 {
@@ -42,7 +42,7 @@ struct sShortSpinlock
 #define SHORTLOCK(...)
 #define SHORTREL(...)
 
-#define        NUM_CFG_ENTRIES 10
+//#define      NUM_CFG_ENTRIES 10
 
 #endif
 
index 9315142..287250c 100644 (file)
@@ -6,5 +6,18 @@
 // NOP (stdlib.h defines the heap functions)
 // Heap_Allocate is used in _strdup
 extern void    *Heap_Allocate(const char *File, int Line, int ByteCount);
+extern void    *Heap_AllocateZero(const char *File, int Line, size_t Bytes);
+extern void    *Heap_Reallocate(const char *File, int Line, void *Ptr, size_t Bytes);
+extern void    Heap_Deallocate(void *Ptr);
+extern int     Heap_IsHeapAddr(void *Ptr);
+extern void    Heap_Validate(void);
+
+#define malloc(size)   Heap_Allocate(_MODULE_NAME_"/"__FILE__, __LINE__, (size))
+#define calloc(num,size)       Heap_AllocateZero(_MODULE_NAME_"/"__FILE__, __LINE__, (num)*(size))
+#define realloc(ptr,size)      Heap_Reallocate(_MODULE_NAME_"/"__FILE__, __LINE__, (ptr), (size))
+#define        free(ptr)       Heap_Deallocate((ptr))
+#define IsHeap(ptr)    Heap_IsHeapAddr((ptr))
+
+#define strdup(Str)    _strdup(_MODULE_NAME_"/"__FILE__, __LINE__, (Str))
 
 #endif
index 7689483..86f3787 100644 (file)
@@ -35,7 +35,7 @@ int NativeKeyboard_Install(char **Arguments)
        return MODULE_ERR_OK;
 }
 
-static const char * const csaIOCTL_NAMES[] = {
+static const char * csaIOCTL_NAMES[] = {
        DRV_IOCTLNAMES,
        DRV_KEYBAORD_IOCTLNAMES,
        NULL
index 3f152ef..363fea1 100644 (file)
@@ -13,21 +13,26 @@ extern int  VFS_Init(void);
 extern int     Video_Install(char **Arguments);
 extern int     NativeKeyboard_Install(char **Arguments);
 extern int     VT_Install(char **Arguments);
+extern int     VFS_Mount(const char *Device, const char *MountPoint, const char *Filesystem, const char *Options);
 extern int     SyscallServer(void);
 
+// === GLOBALS ===
+const char     *gsAcessDir = "../Usermode/Output/i386";
+
 // === CODE ===
 int main(int argc, char *argv[])
 {
        // Parse command line settings
        
        // Start UI subsystem
-       UI_Initialise(640, 480);
+       UI_Initialise(800, 480);
        
        // Initialise VFS
        VFS_Init();
        // - Start IO Drivers
        Video_Install(NULL);
        NativeKeyboard_Install(NULL);
+       NativeFS_Install(NULL);
        // - Start VTerm
        {
                char    *args[] = {
@@ -38,6 +43,10 @@ int main(int argc, char *argv[])
                VT_Install(args);
        }
        
+       VFS_Mount(gsAcessDir, "/Acess", "nativefs", "");
+
+       Debug_SetKTerminal("/Devices/VTerm/8");
+       
        // Start syscall server
        // - Blocks
        SyscallServer();
index 71774e2..6d6e2fe 100644 (file)
  * nativefs.c\r
  * - Host filesystem access\r
  */\r
-#include <acess.h>\r
-#include <vfs.h>\r
+#define DEBUG  1\r
+#include <acess.h>     // Acess\r
+#include <vfs.h>       // Acess\r
+#include <dirent.h>    // Posix\r
+#include <sys/stat.h>  // Posix\r
+#include <stdio.h>     // Posix\r
+\r
+//NOTES:\r
+// tVFS_Node->ImplPtr is a pointer to the filesystem flags (tNativeFS)\r
+// tVFS_Node->Data is the path string (heap string)\r
+// tVFS_Node->ImplInt is the path length\r
+\r
+// === STRUCTURES ===\r
+typedef struct\r
+{\r
+        int    InodeHandle;\r
+        int    bReadOnly;\r
+}      tNativeFS;\r
+\r
+// === PROTOTYPES ===\r
+ int   NativeFS_Install(char **Arguments);\r
+tVFS_Node      *NativeFS_Mount(const char *Device, const char **Arguments);\r
+void   NativeFS_Unmount(tVFS_Node *Node);\r
+tVFS_Node      *NativeFS_FindDir(tVFS_Node *Node, const char *Name);\r
+char   *NativeFS_ReadDir(tVFS_Node *Node, int Position);\r
+Uint64 NativeFS_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);\r
 \r
 // === GLOBALS ===\r
+tVFS_Driver    gNativeFS_Driver = {\r
+       "nativefs", 0,\r
+       NativeFS_Mount, NativeFS_Unmount,\r
+       NULL,\r
+};\r
 \r
 // === CODE ===\r
-tVFS_Node *Native_Mount(const char *Device, const char **Arguments)\r
+int NativeFS_Install(char **Arguments)\r
+{\r
+       VFS_AddDriver(&gNativeFS_Driver);\r
+       return 0;\r
+}\r
+\r
+tVFS_Node *NativeFS_Mount(const char *Device, const char **Arguments)\r
+{\r
+       tVFS_Node       *ret;\r
+       tNativeFS       *info;\r
+       DIR     *dp;\r
+       \r
+       dp = opendir(Device);\r
+       if(!dp) return NULL;\r
+       \r
+       // Check if directory exists\r
+       // Parse flags from arguments\r
+       info = malloc(sizeof(tNativeFS));\r
+       info->InodeHandle = Inode_GetHandle();\r
+       info->bReadOnly = 0;\r
+       // Create node\r
+       ret = malloc(sizeof(tVFS_Node));\r
+       memset(ret, 0, sizeof(tVFS_Node));\r
+       ret->Data = strdup(Device);\r
+       ret->ImplInt = strlen(ret->Data);\r
+       ret->ImplPtr = info;\r
+       ret->Inode = (Uint64)dp;\r
+       \r
+       ret->FindDir = NativeFS_FindDir;\r
+       ret->ReadDir = NativeFS_ReadDir;\r
+       \r
+       return ret;\r
+}\r
+\r
+void NativeFS_Unmount(tVFS_Node *Node)\r
 {\r
+       tNativeFS       *info = Node->ImplPtr;\r
+       Inode_ClearCache( info->InodeHandle );\r
+       closedir( (void *)Node->Inode );\r
+       free(Node->Data);\r
+       free(Node);\r
+       free(info);\r
+}\r
+\r
+void NativeFS_Close(tVFS_Node *Node)\r
+{\r
+       tNativeFS       *info = Node->ImplPtr;\r
+       Inode_UncacheNode( info->InodeHandle, Node->Inode );\r
+}\r
+\r
+tVFS_Node *NativeFS_FindDir(tVFS_Node *Node, const char *Name)\r
+{\r
+       char    *path = malloc(Node->ImplInt + 1 + strlen(Name) + 1);\r
+       tNativeFS       *info = Node->ImplPtr;\r
+       tVFS_Node       baseRet;\r
+       struct stat statbuf;\r
+\r
+       ENTER("pNode sName", Node, Name);\r
+       \r
+       // Create path\r
+       strcpy(path, Node->Data);\r
+       path[Node->ImplInt] = '/';\r
+       strcpy(path + Node->ImplInt + 1, Name);\r
+       \r
+       LOG("path = '%s'", path);\r
+       \r
+       // Check if file exists\r
+       if( stat(path, &statbuf) ) {\r
+               free(path);\r
+               LOG("Doesn't exist");\r
+               LEAVE('n');\r
+               return NULL;\r
+       }\r
+       \r
+       memset(&baseRet, 0, sizeof(tVFS_Node));\r
+       \r
+       // Check file type\r
+       if( S_ISDIR(statbuf.st_mode) )\r
+       {\r
+               LOG("Directory");\r
+               baseRet.Inode = (Uint64) opendir(path);\r
+               baseRet.FindDir = NativeFS_FindDir;\r
+               baseRet.ReadDir = NativeFS_ReadDir;\r
+               baseRet.Flags |= VFS_FFLAG_DIRECTORY;\r
+       }\r
+       else\r
+       {\r
+               LOG("File");\r
+               baseRet.Inode = (Uint64) fopen(path, "r+");\r
+               baseRet.Read = NativeFS_Read;\r
+       }\r
+       \r
+       // Create new node\r
+       baseRet.ImplPtr = info;\r
+       baseRet.ImplInt = strlen(path);\r
+       baseRet.Data = path;\r
+       \r
+       LEAVE('-');\r
+       return Inode_CacheNode(info->InodeHandle, &baseRet);\r
+}\r
+\r
+char *NativeFS_ReadDir(tVFS_Node *Node, int Position)\r
+{\r
+       // Keep track of the current directory position\r
        return NULL;\r
 }\r
+\r
+Uint64 NativeFS_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)\r
+{\r
+       ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);\r
+       if( fseek( (void *)Node->Inode, Offset, SEEK_SET ) != 0 )\r
+       {\r
+               LEAVE('i', 0);\r
+               return 0;\r
+       }\r
+       LEAVE('-');\r
+       return fread( Buffer, 1, Length, (void *)Node->Inode );\r
+}\r
index 5d46f20..725a326 100644 (file)
@@ -17,6 +17,7 @@
 # include <netinet/in.h>
 #endif
 #include "../syscalls.h"
+//#include <debug.h>
 
 #define        USE_TCP 0
 #define MAX_CLIENTS    16
@@ -36,6 +37,10 @@ typedef struct {
 
 // === IMPORTS ===
 extern tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength);
+extern int     Threads_CreateRootProcess(void);
+// HACK: Should have these in a header
+extern void    Log_Debug(const char *Subsys, const char *Message, ...);
+extern void    Log_Notice(const char *Subsys, const char *Message, ...);
 
 // === PROTOTYPES ===
 tClient        *Server_GetClient(int ClientID);
@@ -50,7 +55,6 @@ SOCKET        gSocket = INVALID_SOCKET;
 # define INVALID_SOCKET -1
  int   gSocket = INVALID_SOCKET;
 #endif
- int   giServer_NextClientID = 1;
 tClient        gaServer_Clients[MAX_CLIENTS];
 
 // === CODE ===
@@ -75,12 +79,17 @@ tClient *Server_GetClient(int ClientID)
        tClient *ret = NULL;
         int    i;
        
+       // Allocate an ID if needed
+       if(ClientID == 0)
+               ClientID = Threads_CreateRootProcess();
+       
        for( i = 0; i < MAX_CLIENTS; i ++ )
        {
                if( gaServer_Clients[i].ClientID == ClientID ) {
-                       ret = &gaServer_Clients[i];
-                       break;
+                       return &gaServer_Clients[i];
                }
+               if(!ret && gaServer_Clients[i].ClientID == 0)
+                       ret = &gaServer_Clients[i];
        }
        
        // Uh oh, no free slots
@@ -88,20 +97,18 @@ tClient *Server_GetClient(int ClientID)
        if( !ret )
                return NULL;
        
-       if( ClientID == 0 )
-       {
-               ret->ClientID = giServer_NextClientID ++;
-               ret->CurrentRequest = NULL;
+       // Allocate a thread for the process
+       ret->ClientID = ClientID;
+       ret->CurrentRequest = NULL;
                
-               if( !ret->WorkerThread ) {
-                       ret->WaitFlag = SDL_CreateCond();
-                       ret->Mutex = SDL_CreateMutex();
-                       SDL_mutexP( ret->Mutex );
-                       ret->WorkerThread = SDL_CreateThread( Server_WorkerThread, ret );
-               }
+       if( !ret->WorkerThread ) {
+               ret->WaitFlag = SDL_CreateCond();
+               ret->Mutex = SDL_CreateMutex();
+               SDL_mutexP( ret->Mutex );
+               ret->WorkerThread = SDL_CreateThread( Server_WorkerThread, ret );
        }
        
-       return &gaServer_Clients[i];
+       return ret;
 }
 
 int Server_WorkerThread(void *ClientPtr)
@@ -120,14 +127,15 @@ int Server_WorkerThread(void *ClientPtr)
                while( Client->CurrentRequest == NULL )
                        SDL_CondWait(Client->WaitFlag, Client->Mutex);
                
-               printf("Worker for %i, Job: %p\n", Client->ClientID, Client->CurrentRequest);
+               Log_Debug("AcessSrv", "Worker %i takes %p",
+                       Client->ClientID, Client->CurrentRequest);
                
                // Get the response
                retHeader = SyscallRecieve(Client->CurrentRequest, &retSize);
                
                if( !retHeader ) {
                        // Return an error to the client
-                       printf("Error returned by SyscallRecieve\n");
+                       printf("ERROR: SyscallRecieve failed\n");
                        errorHeader.CallID = Client->CurrentRequest->CallID;
                        errorHeader.NParams = 0;
                        retHeader = &errorHeader;
@@ -140,9 +148,10 @@ int Server_WorkerThread(void *ClientPtr)
                // Mark the thread as ready for another job
                Client->CurrentRequest = 0;
                
-               printf("Sending %i to %x:%i\n",
+               Log_Debug("AcessSrv", "Sending %i to %x:%i (Client %i)",
                        retSize, ntohl(Client->ClientAddr.sin_addr.s_addr),
-                       ntohs(Client->ClientAddr.sin_port)
+                       ntohs(Client->ClientAddr.sin_port),
+                       Client->ClientID
                        );
                
                // Return the data
@@ -213,7 +222,7 @@ int SyscallServer(void)
        listen(gSocket, 5);
        #endif
        
-       Log_Notice("Syscall", "Listening on 0.0.0.0:%i\n", SERVER_PORT);
+       Log_Notice("AcessSrv", "Listening on 0.0.0.0:%i", SERVER_PORT);
        
        // Wait for something to do :)
        for( ;; )
@@ -227,7 +236,7 @@ int SyscallServer(void)
                        break ;
                }
                
-               printf("Client connection %x:%i",
+               Log("Client connection %x:%i\n",
                        ntohl(client.sin_addr), ntohs(client.sin_port)
                        );
                
@@ -269,7 +278,8 @@ int SyscallServer(void)
                        continue;
                }
                
-               printf("client = %p, ClientID = %i\n", client, client->ClientID);
+               Log_Debug("AcessSrv", "Message from Client %i (%p)",
+                       client->ClientID, client);
                
                client->CurrentRequest = req;
                SDL_CondSignal(client->WaitFlag);
index eb9d8a2..f48b1a9 100644 (file)
@@ -5,13 +5,27 @@
  * Syscall Distribution
  */
 #include <acess.h>
+#include <threads.h>
 #include "../syscalls.h"
 
+// === IMPORTS ===
+extern int     Threads_Fork(void);     // AcessNative only function
+
 // === TYPES ===
-typedef int    (*tSyscallHandler)(const char *Format, void *Args, int *Sizes);
+typedef int    (*tSyscallHandler)(Uint *Errno, const char *Format, void *Args, int *Sizes);
 
 // === MACROS ===
-#define SYSCALL3(_name, _fmtstr, _t0, _t1, _t2, _call) int _name(const char*Fmt,void*Args,int*Sizes){\
+#define SYSCALL4(_name, _fmtstr, _t0, _t1, _t2, _t3, _call) int _name(Uint*Errno,const char*Fmt,void*Args,int*Sizes){\
+       _t0 a0;_t1 a1;_t2 a2;_t3 a3;\
+       if(strcmp(Fmt,_fmtstr)!=0)return 0;\
+       a0 = *(_t0*)Args;Args+=sizeof(_t0);\
+       a1 = *(_t1*)Args;Args+=sizeof(_t1);\
+       a2 = *(_t2*)Args;Args+=sizeof(_t2);\
+       a3 = *(_t3*)Args;Args+=sizeof(_t3);\
+       _call\
+}
+
+#define SYSCALL3(_name, _fmtstr, _t0, _t1, _t2, _call) int _name(Uint*Errno,const char*Fmt,void*Args,int*Sizes){\
        _t0 a0;_t1 a1;_t2 a2;\
        if(strcmp(Fmt,_fmtstr)!=0)return 0;\
        a0 = *(_t0*)Args;Args+=sizeof(_t0);\
@@ -20,7 +34,7 @@ typedef int   (*tSyscallHandler)(const char *Format, void *Args, int *Sizes);
        _call\
 }
 
-#define SYSCALL2(_name, _fmtstr, _t0, _t1, _call) int _name(const char*Fmt,void*Args,int*Sizes){\
+#define SYSCALL2(_name, _fmtstr, _t0, _t1, _call) int _name(Uint*Errno,const char*Fmt,void*Args,int*Sizes){\
        _t0 a0;_t1 a1;\
        if(strcmp(Fmt,_fmtstr)!=0)return 0;\
        a0 = *(_t0*)Args;Args+=sizeof(_t0);\
@@ -28,19 +42,29 @@ typedef int (*tSyscallHandler)(const char *Format, void *Args, int *Sizes);
        _call;\
 }
 
-#define SYSCALL1(_name, _fmtstr, _t0, _call) int _name(const char*Fmt, void*Args,int*Sizes){\
+#define SYSCALL1(_name, _fmtstr, _t0, _call) int _name(Uint*Errno,const char*Fmt, void*Args,int*Sizes){\
        _t0 a0;\
        if(strcmp(Fmt,_fmtstr)!=0)return 0;\
        a0 = *(_t0*)Args;Args+=sizeof(_t0);\
        _call;\
 }
 
+#define SYSCALL0(_name, _call) int _name(Uint*Errno,const char*Fmt, void*Args,int*Sizes){\
+       if(strcmp(Fmt,"")!=0)return 0;\
+       _call;\
+}
+
 // === CODE ===
-int Syscall_Null(const char *Format, void *Args, int *Sizes)
+int Syscall_Null(Uint*Errno, const char *Format, void *Args, int *Sizes)
 {
        return 0;
 }
 
+SYSCALL1(Syscall_Exit, "i", int,
+       Threads_Exit(0, a0);
+       return 0;
+);
+
 SYSCALL2(Syscall_Open, "si", const char *, int,
        return VFS_Open(a0, a1|VFS_OPENFLAG_USER);
 );
@@ -49,12 +73,12 @@ SYSCALL1(Syscall_Close, "i", int,
        return 0;
 );
 SYSCALL3(Syscall_Read, "iid", int, int, void *,
-       if( Sizes[2] <= a1 )
+       if( Sizes[2] < a1 )
                return -1;
        return VFS_Read(a0, a1, a2);
 );
 SYSCALL3(Syscall_Write, "iid", int, int, const void *,
-       if( Sizes[2] <= a1 )
+       if( Sizes[2] < a1 )
                return -1;
        return VFS_Write(a0, a1, a2);
 );
@@ -72,10 +96,53 @@ SYSCALL3(Syscall_FInfo, "idi", int, void *, int,
                return -1;
        return VFS_FInfo(a0, a1, a2);
 );
+SYSCALL2(Syscall_ReadDir, "id", int, char *,
+       if(Sizes[1] < 255)
+               return -1;
+       return VFS_ReadDir(a0, a1);
+);
+SYSCALL3(Syscall_OpenChild, "isi", int, const char *, int,
+       return VFS_OpenChild(NULL, a0, a1, a2|VFS_OPENFLAG_USER);
+);
+SYSCALL2(Syscall_GetACL, "id", int, void *,
+       if(Sizes[1] < sizeof(tVFS_ACL))
+               return -1;
+       return VFS_GetACL(a0, (void*)a1);
+);
+SYSCALL4(Syscall_Mount, "ssss", const char *, const char *, const char *, const char *,
+       return VFS_Mount(a0, a1, a2, a3);
+);
+SYSCALL0(Syscall_Sleep,
+       Threads_Sleep();
+       return 0;
+);
+SYSCALL2(Syscall_WaitTID, "id", int, int *,
+       if(Sizes[1] < sizeof(int))
+               return -1;
+       return Threads_WaitTID(a0, a1);
+);
+SYSCALL1(Syscall_SetUID, "i", int,
+       if(Sizes[0] < sizeof(int)) {
+               *Errno = -EINVAL;       // TODO: Better message
+               return -1;
+       }
+       return Threads_SetUID(Errno, a0);
+);
+SYSCALL1(Syscall_SetGID, "i", int,
+       if(Sizes[0] < sizeof(int)) {
+               *Errno = -EINVAL;       // TODO: Better message
+               return -1;
+       }
+       return Threads_SetGID(Errno, a0);
+);
 
+SYSCALL0(Syscall_Fork,
+       return Threads_Fork();
+);
 
 const tSyscallHandler  caSyscalls[] = {
        Syscall_Null,
+       Syscall_Exit,
        Syscall_Open,
        Syscall_Close,
        Syscall_Read,
@@ -83,7 +150,19 @@ const tSyscallHandler       caSyscalls[] = {
        Syscall_Seek,
        Syscall_Tell,
        Syscall_IOCtl,
-       Syscall_FInfo
+       Syscall_FInfo,
+       Syscall_ReadDir,
+       Syscall_OpenChild,
+       Syscall_GetACL,
+       Syscall_Mount,
+       NULL,   // SYS_REOPEN
+       
+       Syscall_WaitTID,
+       Syscall_SetUID,
+       Syscall_SetGID,
+       
+       Syscall_Sleep,
+       Syscall_Fork
 };
 const int      ciNumSyscalls = sizeof(caSyscalls)/sizeof(caSyscalls[0]);
 /**
@@ -100,6 +179,7 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
         int    retDataLen = sizeof(Uint64);
        void    *returnData[Request->NParams];
         int    argSizes[Request->NParams];
+       Uint    ret_errno = 0;
        
        // Sanity check
        if( Request->CallID >= ciNumSyscalls ) {
@@ -107,6 +187,11 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
                return NULL;
        }
        
+       if( !caSyscalls[Request->CallID] ) {
+               Log_Notice("Syscalls", "Unimplemented syscall %i", Request->CallID);
+               return NULL;
+       }
+       
        // Get size of argument list
        for( i = 0; i < Request->NParams; i ++ )
        {
@@ -138,7 +223,7 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
        }
        formatString[i] = '\0';
        
-       Log_Debug("Syscalls", "Request %i '%s'", Request->CallID, formatString);
+       LOG("Request %i(%s) '%s'", Request->CallID, casSYSCALL_NAMES[Request->CallID], formatString);
        
        {
                char    argListData[argListLen];
@@ -152,19 +237,19 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
                        case ARG_TYPE_VOID:
                                break;
                        case ARG_TYPE_INT32:
-                               Log_Debug("Syscalls", "Arg %i: 0x%x", i, *(Uint32*)inData);
+                               LOG("Syscalls", "%i INT32: 0x%x", i, *(Uint32*)inData);
                                *(Uint32*)&argListData[argListLen] = *(Uint32*)inData;
                                argListLen += sizeof(Uint32);
                                inData += sizeof(Uint32);
                                break;
                        case ARG_TYPE_INT64:
-                               Log_Debug("Syscalls", "Arg %i: 0x%llx", i, *(Uint64*)inData);
+                               LOG("Syscalls", "%i INT64: 0x%llx", i, *(Uint64*)inData);
                                *(Uint64*)&argListData[argListLen] = *(Uint64*)inData;
                                argListLen += sizeof(Uint64);
                                inData += sizeof(Uint64);
                                break;
                        case ARG_TYPE_STRING:
-                               Log_Debug("Syscalls", "Arg %i: '%s'", i, (char*)inData);
+                               LOG("Syscalls", "%i STR: '%s'", i, (char*)inData);
                                *(char**)&argListData[argListLen] = (char*)inData;
                                argListLen += sizeof(void*);
                                inData += Request->Params[i].Length;
@@ -185,7 +270,7 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
                                {
                                        // Allocate and zero the buffer
                                        returnData[i] = calloc(1, Request->Params[i].Length);
-                                       Log_Debug("Syscalls", "Arg %i: %i %p", i,
+                                       LOG("Syscalls", "%i ZDAT: %i %p", i,
                                                Request->Params[i].Length, returnData[i]);
                                        *(void**)&argListData[argListLen] = returnData[i];
                                        argListLen += sizeof(void*);
@@ -193,7 +278,7 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
                                else
                                {
                                        returnData[i] = (void*)inData;
-                                       Log_Debug("Syscalls", "Arg %i: %i %p", i,
+                                       LOG("Syscalls", "%i DATA: %i %p", i,
                                                Request->Params[i].Length, returnData[i]);
                                        *(void**)&argListData[argListLen] = (void*)inData;
                                        argListLen += sizeof(void*);
@@ -203,7 +288,7 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
                        }
                }
                
-               retVal = caSyscalls[Request->CallID](formatString, argListData, argSizes);
+               retVal = caSyscalls[Request->CallID](&ret_errno, formatString, argListData, argSizes);
        }
        
        // Allocate the return
@@ -221,22 +306,27 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
        *(Uint64*)inData = retVal;
        inData += sizeof(Uint64);
        
-       Log_Debug("Syscalls", "Return 0x%llx", retVal);
+       LOG("Syscalls", "Return 0x%llx", retVal);
        
+       retValueCount = 1;
        for( i = 0; i < Request->NParams; i ++ )
        {
                if( Request->Params[i].Type != ARG_TYPE_DATA )  continue;
                if( !(Request->Params[i].Flags & ARG_FLAG_RETURN) )     continue;
                
-               ret->Params[1 + i].Type = Request->Params[i].Type;
-               ret->Params[1 + i].Flags = 0;
-               ret->Params[1 + i].Length = Request->Params[i].Length;
+               ret->Params[retValueCount].Type = Request->Params[i].Type;
+               ret->Params[retValueCount].Flags = 0;
+               ret->Params[retValueCount].Length = Request->Params[i].Length;
+               
+               LOG("Syscalls", "Ret %i: Type %i, Len %i",
+                       i, Request->Params[i].Type, Request->Params[i].Length);
                
                memcpy(inData, returnData[i], Request->Params[i].Length);
                inData += Request->Params[i].Length;
                
                if( Request->Params[i].Flags & ARG_FLAG_ZEROED )
                        free( returnData[i] );  // Free temp buffer from above
+               retValueCount ++;
        }
        
        *ReturnLength = sizeof(tRequestHeader)
index 5a0ce13..9d12517 100644 (file)
@@ -5,13 +5,23 @@
  * threads.c
  * - Thread and process handling
  */
-#define _SIGNAL_H_
+#define _SIGNAL_H_     // Stop the acess signal.h being used
+#define _HEAP_H_       // Stop heap.h being imported (collides with stdlib heap)
+#define _VFS_EXT_H     // Stop vfs_ext.h being imported (collides with fd_set)
 #undef CLONE_VM        // Such a hack
 #include <arch.h>
+#undef NULL    // Remove acess definition
+#include <acess.h>
+#include <mutex.h>
+#include <semaphore.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <stdint.h>
 #include "/usr/include/signal.h"
+#include <SDL/SDL.h>
+
+// === IMPORTS ===
+void   VFS_CloneHandleList(int PID);
 
 // === STRUCTURES ===
 #if 0
@@ -24,6 +34,7 @@ typedef struct sState
 
 typedef struct sThread
 {
+       struct sThread  *GlobalNext;
        struct sThread  *Next;
 
         int    KernelTID;
@@ -36,27 +47,55 @@ typedef struct sThread
        char    *ThreadName;
 
         int    State;  // 0: Dead, 1: Active, 2: Paused, 3: Asleep
+        int    ExitStatus;
        #if 0
        tState  CurState;
        #endif
 
+       // Threads waiting for this thread to exit.
+       // Quit logic:
+       // - Wait for `WaitingThreads` to be non-null (maybe?)
+       // - Wake first in the queue, wait for it to be removed
+       // - Repeat
+       // - Free thread and quit kernel thread
+       struct sThread  *WaitingThreads;
+       struct sThread  *WaitingThreadsEnd;
+
        // Config?
        Uint    Config[NUM_CFG_ENTRIES];
 }      tThread;
 
+// === PROTOTYPES ===
+ int   Threads_Wake(tThread *Thread);
+
 // === GLOBALS ===
-tThread        gThread_Zero = {
+tThread        gThreadZero = {
        State: 1,
        ThreadName: "ThreadZero"
 };
-tThread        *gpThreads = &gThread_Zero;
-__thread tThread       *gpCurrentThread = &gThread_Zero;
+tThread        *gpThreads = &gThreadZero;
+__thread tThread       *gpCurrentThread = &gThreadZero;
+ int   giThreads_NextThreadID = 1;
 
 // === CODE ===
+void Threads_Dump(void)
+{
+       tThread *thread;
+       for( thread = gpThreads; thread; thread = thread->GlobalNext )
+       {
+               Log_Log("Threads", "TID %i (%s), PID %i",
+                       thread->TID, thread->ThreadName, thread->PID);
+               Log_Log("Threads", "User: %i, Group: %i",
+                       thread->UID, thread->GID);
+               Log_Log("Threads", "Kernel Thread ID: %i",
+                       thread->KernelTID);
+       }
+}
+
 tThread        *Threads_GetThread(int TID)
 {
        tThread *thread;
-       for( thread = gpThreads; thread; thread = thread->Next )
+       for( thread = gpThreads; thread; thread = thread->GlobalNext )
        {
                if( thread->TID == TID )
                        return thread;
@@ -64,12 +103,55 @@ tThread    *Threads_GetThread(int TID)
        return NULL;
 }
 
+/**
+ * \brief Clone a thread control block (with a different TID)
+ */
+tThread *Threads_CloneTCB(tThread *TemplateThread)
+{
+       tThread *ret = malloc(sizeof(tThread));
+       
+       memcpy(ret, TemplateThread, sizeof(tThread));
+       
+       ret->TID = giThreads_NextThreadID ++;
+       
+       ret->ThreadName = strdup(TemplateThread->ThreadName);
+       
+       ret->WaitingThreads = NULL;
+       ret->WaitingThreadsEnd = NULL;
+       
+       // Add to the end of the queue
+       // TODO: Handle concurrency issues
+       ret->GlobalNext = gpThreads;
+       gpThreads = ret;
+       
+       return ret;
+}
+
 tUID Threads_GetUID() { return gpCurrentThread->UID; }
 tGID Threads_GetGID() { return gpCurrentThread->GID; }
 tTID Threads_GetTID() { return gpCurrentThread->TID; }
-tPID Threads_GetPID() {
-       return SDL_ThreadID();
-       //return gpCurrentThread->PID;
+tPID Threads_GetPID() { return gpCurrentThread->PID; }
+
+int Threads_SetUID(int *Errno, tUID NewUID)
+{
+       if(Threads_GetUID() != 0) {
+               if(Errno)       *Errno = -EACCES;
+               return -1;
+       }
+       
+       gpCurrentThread->UID = NewUID;
+       return 0;
+}
+
+int Threads_SetGID(int *Errno, tGID NewGID)
+{
+       if(Threads_GetUID() != 0) {
+               if(Errno)       *Errno = -EACCES;
+               return -1;
+       }
+       
+       gpCurrentThread->GID = NewGID;
+       return 0;
 }
 
 Uint *Threads_GetCfgPtr(int Index)
@@ -81,8 +163,62 @@ Uint *Threads_GetCfgPtr(int Index)
        return &gpCurrentThread->Config[Index];
 }
 
+int Threads_WaitTID(int TID, int *Status)
+{
+       // Any Child
+       if(TID == -1) {
+               Log_Error("Threads", "TODO: Threads_WaitTID(TID=-1) - Any Child");
+               return -1;
+       }
+       
+       // Any peer/child thread
+       if(TID == 0) {
+               Log_Error("Threads", "TODO: Threads_WaitTID(TID=0) - Any Child/Sibling");
+               return -1;
+       }
+       
+       // TGID = abs(TID)
+       if(TID < -1) {
+               Log_Error("Threads", "TODO: Threads_WaitTID(TID<0) - TGID");
+               return -1;
+       }
+       
+       // Specific Thread
+       if(TID > 0) {
+               
+               tThread *thread = Threads_GetThread(TID);
+               tThread *us = gpCurrentThread;
+               if(!thread)     return -1;
+               
+               us->Next = NULL;
+               us->State = 3;
+               if(thread->WaitingThreadsEnd)
+               {
+                       thread->WaitingThreadsEnd->Next = us;
+                       thread->WaitingThreadsEnd = us;
+               }
+               else
+               {
+                       thread->WaitingThreads = us;
+                       thread->WaitingThreadsEnd = us;
+               }
+               
+               while(thread->State != 0)
+                       pause();
+               
+               if(Status)      *Status = thread->ExitStatus;
+               thread->WaitingThreads = thread->WaitingThreads->Next;
+               us->Next = NULL;
+               
+               return TID;
+       }
+       
+       return 0;
+}
+
 void Threads_Sleep(void)
 {
+       // TODO: Add to a sleeping queue
        pause();
 }
 
@@ -91,22 +227,70 @@ void Threads_Yield(void)
 //     yield();
 }
 
+void Threads_Exit(int TID, int Status)
+{
+       tThread *toWake;
+       
+//     VFS_Handles_Cleanup();
+       
+       #if 1
+       // Wait for the thread to be waited upon
+       while( gpCurrentThread->WaitingThreads == NULL )
+               SDL_Delay(10);
+       #endif
+       
+       while( (toWake = gpCurrentThread->WaitingThreads) )
+       {
+               Threads_Wake(toWake);
+               
+               while(gpCurrentThread->WaitingThreads == toWake)
+                       SDL_Delay(10);
+       }
+}
+
+int Threads_Wake(tThread *Thread)
+{
+       kill( Thread->KernelTID, SIGUSR1 );
+       return 0;
+}
+
 int Threads_WakeTID(tTID TID)
 {
        tThread *thread;
        thread = Threads_GetThread(TID);
        if( !thread )   return -1;
-       kill( thread->KernelTID, SIGUSR1 );
-       return 0;
+       return Threads_Wake(thread);
+}
+
+int Threads_CreateRootProcess(void)
+{
+       tThread *thread = Threads_CloneTCB(&gThreadZero);
+       thread->PID = thread->TID;
+       
+       // Handle list is created on first open
+       
+       return thread->PID;
+}
+
+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;
 }
 
-void Mutex_Acquire(tMutex *Mutex)
+int Mutex_Acquire(tMutex *Mutex)
 {
        if(!Mutex->Protector.IsValid) {
                pthread_mutex_init( &Mutex->Protector.Mutex, NULL );
                Mutex->Protector.IsValid = 1;
        }
        pthread_mutex_lock( &Mutex->Protector.Mutex );
+       return 0;
 }
 
 void Mutex_Release(tMutex *Mutex)
@@ -114,6 +298,27 @@ void Mutex_Release(tMutex *Mutex)
        pthread_mutex_unlock( &Mutex->Protector.Mutex );
 }
 
+void Semaphore_Init(tSemaphore *Sem, int InitValue, int MaxValue, const char *Module, const char *Name)
+{
+       memset(Sem, 0, sizeof(tSemaphore));
+       // HACK: Use `Sem->Protector` as space for the semaphore pointer
+       *(void**)(&Sem->Protector) = SDL_CreateSemaphore(InitValue);
+}
+
+int Semaphore_Wait(tSemaphore *Sem, int MaxToTake)
+{
+       SDL_SemWait( *(void**)(&Sem->Protector) );
+       return 1;
+}
+
+int Semaphore_Signal(tSemaphore *Sem, int AmmountToAdd)
+{
+        int    i;
+       for( i = 0; i < AmmountToAdd; i ++ )
+               SDL_SemPost( *(void**)(&Sem->Protector) );
+       return AmmountToAdd;
+}
+
 #if 0
 void Threads_Sleep()
 {
index 546021a..3f3cb13 100644 (file)
@@ -39,6 +39,9 @@ int UI_Initialise(int MaxWidth, int MaxHeight)
        // Start main thread
        gInputThread = SDL_CreateThread(UI_MainThread, NULL);
        
+       while(gScreen == NULL)
+               SDL_Delay(10);
+       
        return 0;
 }
 
@@ -152,15 +155,21 @@ void UI_BlitBitmap(int DstX, int DstY, int SrcW, int SrcH, Uint32 *Bitmap)
        SDL_Surface     *tmp;
        SDL_Rect        dstRect;
        
+//     printf("UI_BlitBitmap: Blit to (%i,%i) from %p (%ix%i 32bpp bitmap)\n",
+//             DstX, DstY, Bitmap, SrcW, SrcH);
+       
        tmp = SDL_CreateRGBSurfaceFrom(Bitmap, SrcW, SrcH, 32, SrcW*4,
                0xFF0000, 0x00FF00, 0x0000FF, 0xFF000000);
        SDL_SetAlpha(tmp, 0, SDL_ALPHA_OPAQUE);
        
        dstRect.x = DstX;       dstRect.y = DstY;
+       dstRect.w = -1; dstRect.h = -1;
        
        SDL_BlitSurface(tmp, NULL, gScreen, &dstRect);
+       //SDL_BlitSurface(tmp, NULL, gScreen, NULL);
        
        SDL_FreeSurface(tmp);
+//     SDL_Flip(gScreen);
 }
 
 void UI_BlitFramebuffer(int DstX, int DstY, int SrcX, int SrcY, int W, int H)
@@ -182,10 +191,12 @@ void UI_FillBitmap(int X, int Y, int W, int H, Uint32 Value)
        dstRect.x = X;  dstRect.y = Y;
        dstRect.w = W;  dstRect.h = H;
        
+//     printf("UI_FillBitmap: gScreen = %p\n", gScreen);
        SDL_FillRect(gScreen, &dstRect, Value);
 }
 
 void UI_Redraw(void)
 {
-       // No-Op, we're not using double buffering
+       // TODO: Keep track of changed rectangle
+       SDL_UpdateRect(gScreen, 0, 0, giUI_Width, giUI_Height);
 }
index 5a94e6d..91caeff 100644 (file)
@@ -2,11 +2,11 @@
  * Acess2 VFS
  * - AllocHandle, GetHandle
  */
-#define DEBUG  0
+#define DEBUG  1
 #include <acess.h>
-#include "vfs.h"
-#include "vfs_int.h"
-#include "vfs_ext.h"
+#include <vfs.h>
+#include <vfs_int.h>
+#include <vfs_ext.h>
 
 // === CONSTANTS ===
 #define MAX_KERNEL_FILES       128
@@ -32,6 +32,59 @@ tUserHandles *gpUserHandles = NULL;
 tVFS_Handle    gaKernelHandles[MAX_KERNEL_FILES];
 
 // === CODE ===
+tUserHandles *VFS_int_GetUserHandles(int PID, int bCreate)
+{
+       tUserHandles    *ent, *prev = NULL;
+       for( ent = gpUserHandles; ent; prev = ent, ent = ent->Next ) {
+               if( ent->PID == PID ) {
+                       Log_Warning("VFS", "Process %i already has a handle list", PID);
+                       return ent;
+               }
+               if( ent->PID > PID )    break;
+       }
+       
+       if(!bCreate)
+               return NULL;
+       
+       ent = calloc( 1, sizeof(tUserHandles) );
+       ent->PID = PID;
+       if( prev ) {
+               ent->Next = prev->Next;
+               prev->Next = ent;
+       }
+       else {
+               ent->Next = gpUserHandles;
+               gpUserHandles = ent;
+       }
+       Log_Notice("VFS", "Created handle list for process %i", PID);
+       return ent;
+}
+
+/**
+ * \brief Clone the handle list of the current process into another
+ */
+void VFS_CloneHandleList(int PID)
+{
+       tUserHandles    *ent;
+       tUserHandles    *cur;
+        int    i;
+       
+       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);
+       
+       memcpy(ent->Handles, cur->Handles, CFGINT(CFG_VFS_MAXFILES)*sizeof(tVFS_Handle));
+       
+       for( i = 0; i < CFGINT(CFG_VFS_MAXFILES); i ++ )
+       {
+               if(!cur->Handles[i].Node)       continue;
+               
+               if(ent->Handles[i].Node->Reference)
+                       ent->Handles[i].Node->Reference(ent->Handles[i].Node);
+       }
+}
+
 /**
  * \fn tVFS_Handle *VFS_GetHandle(int FD)
  * \brief Gets a pointer to the handle information structure
@@ -42,32 +95,42 @@ tVFS_Handle *VFS_GetHandle(int FD)
        
        //Log_Debug("VFS", "VFS_GetHandle: (FD=0x%x)", FD);
        
-       if(FD < 0)      return NULL;
+       if(FD < 0) {
+               LOG("FD (%i) < 0, RETURN NULL", FD);
+               return NULL;
+       }
        
        if(FD & VFS_KERNEL_FLAG) {
                FD &= (VFS_KERNEL_FLAG - 1);
-               if(FD >= MAX_KERNEL_FILES)      return NULL;
+               if(FD >= MAX_KERNEL_FILES) {
+                       LOG("FD (%i) > MAX_KERNEL_FILES (%i), RETURN NULL", FD, MAX_KERNEL_FILES);
+                       return NULL;
+               }
                h = &gaKernelHandles[ FD ];
        }
-       else {
+       else
+       {
                tUserHandles    *ent;
-                int    pid = Server_GetClientID();
-               for( ent = gpUserHandles; ent; ent = ent->Next ) {
-                       if( ent->PID == pid )   break;
-                       if( ent->PID > pid ) {
-                               Log_Error("VFS", "PID %i does not have a handle list", pid);
-                               return NULL;
-                       }
+                int    pid = Threads_GetPID();
+               
+               ent = VFS_int_GetUserHandles(pid, 0);
+               if(!ent) {
+                       Log_Error("VFS", "Client %i does not have a handle list (>)", pid);
+                       return NULL;
                }
-               if( !ent ) {
-                       Log_Error("VFS", "PID %i does not have a handle list", pid);
+               
+               if(FD >= CFGINT(CFG_VFS_MAXFILES)) {
+                       LOG("FD (%i) > Limit (%i), RETURN NULL", FD, CFGINT(CFG_VFS_MAXFILES));
                        return NULL;
                }
-               if(FD >= CFGINT(CFG_VFS_MAXFILES))      return NULL;
                h = &ent->Handles[ FD ];
+               LOG("FD (%i) -> %p (Mode:0x%x,Node:%p)", FD, h, h->Mode, h->Node);
        }
        
-       if(h->Node == NULL)     return NULL;
+       if(h->Node == NULL) {
+               LOG("FD (%i) Unused", FD);
+               return NULL;
+       }
        //Log_Debug("VFS", "VFS_GetHandle: RETURN %p", h);
        return h;
 }
@@ -79,24 +142,9 @@ int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode)
        // Check for a user open
        if(bIsUser)
        {
-               tUserHandles    *ent, *prev = NULL;
-                int    pid = Server_GetClientID();
-               for( ent = gpUserHandles; ent; prev = ent, ent = ent->Next ) {
-                       if( ent->PID == pid )   break;
-                       if( ent->PID > pid )    break;
-               }
-               if( !ent || ent->PID > pid ) {
-                       ent = calloc( 1, sizeof(tUserHandles) );
-                       ent->PID = pid;
-                       if( prev ) {
-                               ent->Next = prev->Next;
-                               prev->Next = ent;
-                       }
-                       else {
-                               ent->Next = gpUserHandles;
-                               gpUserHandles = ent;
-                       }
-               }
+               tUserHandles    *ent;
+               // Find the PID's handle list
+               ent = VFS_int_GetUserHandles(Threads_GetPID(), 1);
                // Get a handle
                for(i=0;i<CFGINT(CFG_VFS_MAXFILES);i++)
                {
index 4645b95..f3903fb 100644 (file)
@@ -4,6 +4,7 @@
  * Video Driver
  */
 #define VERSION        ((0<<8)|10)
+#define DEBUG  0
 #include <acess.h>
 #include <vfs.h>
 #include <fs_devfs.h>
@@ -90,6 +91,8 @@ Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
                
                // Sanity Check
                if( Offset > (Uint64)(heightInChars*widthInChars) ) {
+                       Log_Notice("Video", "Offset (%i) > %i*%i (%i)", Offset,
+                               heightInChars, widthInChars, heightInChars*widthInChars);
                        LEAVE('i', 0);
                        return 0;
                }
@@ -106,21 +109,36 @@ Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
                        Log_Notice("Video", "Clipping write size to %i characters", (int)Length);
                }
                
+//             Log_Debug("Video", "(%i,%i) %i chars", x, y, (int)Length);
+               
                // Print characters
                for( i = 0; i < (int)Length; i++ )
                {
-                       VT_Font_Render(
-                               chars->Ch,
-                               //dest + x*giVT_CharWidth, pitch,
-                               tmpBuf, giVT_CharWidth,
-                               VT_Colour12to24(chars->BGCol),
-                               VT_Colour12to24(chars->FGCol)
-                               );
-                       UI_BlitBitmap(
-                               x*giVT_CharWidth, y*giVT_CharHeight,
-                               giVT_CharWidth, giVT_CharHeight,
-                               tmpBuf
-                               );
+                       if( chars->Ch )
+                       {
+//                             Log_Debug("Video", "Render Char 0x%x in 0x%03x:%03x",
+//                                     chars->Ch, chars->FGCol, chars->BGCol);
+                               memset(tmpBuf, 0xFF, giVT_CharWidth*giVT_CharHeight*4);
+                               VT_Font_Render(
+                                       chars->Ch,
+                                       tmpBuf, 32, giVT_CharWidth*4,
+                                       VT_Colour12to24(chars->BGCol),
+                                       VT_Colour12to24(chars->FGCol)
+                                       );
+                               UI_BlitBitmap(
+                                       x*giVT_CharWidth, y*giVT_CharHeight,
+                                       giVT_CharWidth, giVT_CharHeight,
+                                       tmpBuf
+                                       );
+                       }
+                       else
+                       {
+                               UI_FillBitmap(
+                                       x*giVT_CharWidth, y*giVT_CharHeight,
+                                       giVT_CharWidth, giVT_CharHeight,
+                                       VT_Colour12to24(chars->BGCol)
+                                       );
+                       }
                        
                        chars ++;
                        x ++;
@@ -146,7 +164,6 @@ Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
                }
                
                LOG("buffer = %p", Buffer);
-               LOG("Updating Framebuffer (%p to %p)", destBuf, destBuf + (Uint)Length);
                
                startX = Offset % giUI_Width;
                startY = Offset / giUI_Width;
@@ -211,7 +228,7 @@ Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
        return Length;
 }
 
-const char * const csaVIDEO_IOCTLS[] = {DRV_IOCTLNAMES, DRV_VIDEO_IOCTLNAMES, NULL};
+const char * csaVIDEO_IOCTLS[] = {DRV_IOCTLNAMES, DRV_VIDEO_IOCTLNAMES, NULL};
 /**
  * \brief Handle messages to the device
  */
index 4fb6ae2..f7543fd 100644 (file)
@@ -19,6 +19,9 @@ endif
 
 CFLAGS += -Wall -Werror -g -m32
 
+DEPFILES  = $(filter %.o.$(PLATFORM),$(OBJ))
+DEPFILES := $(DEPFILES:%.o.$(PLATFORM)=%.d.$(PLATFORM))
+
 .PHONY: all clean
 
 all: $(BIN)
@@ -31,9 +34,12 @@ $(BIN): link.ld.$(PLATFORM) $(OBJ)
        $(CC) -g -o $@ $(OBJ) -m32 -Wl,-T,link.ld.$(PLATFORM)
 
 %.o.$(PLATFORM): %.c
-       $(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS)
+       @echo [CC] -o $@
+       @$(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS)
+       @$(CC) -M $(CPPFLAGS) -MT $@ -o $*.d.$(PLATFORM) $<
 
 # Modify the default makefile to put the executable at 1MB instead
 link.ld.lin:
-       $(LD) --verbose | awk '{ if( substr($$0,0,5) == "====="){ bPrint = !bPrint; } else { if(bPrint){ print $$0;} } }' | sed 's/\b0x0[08][0-9]*\b/0x00100000/g' > $@
+       @echo Making Linker Script ($@)
+       @$(LD) --verbose | awk '{ if( substr($$0,0,5) == "====="){ bPrint = !bPrint; } else { if(bPrint){ print $$0;} } }' | sed 's/\b0x0[08][0-9]*\b/0x00100000/g' > $@
 
index 0ce9fac..d3dee99 100644 (file)
@@ -6,7 +6,7 @@
 #include <stdio.h>
 #include <string.h>
 
-#define LIBRARY_PATH   "../Usermode/Output/i386/Libs"
+#define LIBRARY_PATH   "$$$$../Usermode/Output/i386/Libs"
 
 // === TYPES ===
 typedef struct sBinary {
@@ -18,7 +18,7 @@ typedef struct sBinary {
 }      tBinary;
 
 // === IMPORTS ===
-extern void    *Elf_Load(FILE *FP);
+extern void    *Elf_Load(int fd);
 extern uintptr_t       Elf_Relocate(void *Base);
 extern int     Elf_GetSymbol(void *Base, char *Name, uintptr_t *ret);
 extern int     ciNumBuiltinSymbols;
@@ -43,7 +43,7 @@ char *Binary_LocateLibrary(const char *Name)
 {
        char    *envPath = getenv("ACESS_LIBRARY_PATH");
         int    nameLen = strlen(Name);
-       FILE    *fp;
+        int    fd;
        
        if( strcmp(Name, "libld-acess.so") == 0 ) {
                return strdup("libld-acess.so");
@@ -59,9 +59,9 @@ char *Binary_LocateLibrary(const char *Name)
                strcat(tmp, "/");
                strcat(tmp, Name);
                
-               fp = fopen(tmp, "r");
-               if(fp) {
-                       fclose(fp);
+               fd = acess_open(tmp, 4);        // OPENFLAG_EXEC
+               if(fd != -1) {
+                       acess_close(fd);
                        return strdup(tmp);
                }
        }               
@@ -74,16 +74,20 @@ char *Binary_LocateLibrary(const char *Name)
                strcat(tmp, "/");
                strcat(tmp, Name);
                
+               #if DEBUG
                printf("Binary_LocateLibrary: tmp = '%s'\n", tmp);
+               #endif
 
-               fp = fopen(tmp, "r");
-               if(fp) {
-                       fclose(fp);
+               fd = acess_open(tmp, 4);        // OPENFLAG_EXEC
+               if(fd != -1) {
+                       acess_close(fd);
                        return strdup(tmp);
                }
        }               
 
+       #if DEBUG
        fprintf(stderr, "Unable to locate library '%s'\n", Name);
+       #endif
 
        return NULL;
 }
@@ -96,7 +100,9 @@ void *Binary_LoadLibrary(const char *Name)
 
        // Find File
        path = Binary_LocateLibrary(Name);
+       #if DEBUG
        printf("Binary_LoadLibrary: path = '%s'\n", path);
+       #endif
        if( !path ) {
                return NULL;
        }
@@ -104,10 +110,14 @@ void *Binary_LoadLibrary(const char *Name)
        ret = Binary_Load(path, (uintptr_t*)&entry);
        free(path);
        
+       #if DEBUG
        printf("Binary_LoadLibrary: ret = %p, entry = %p\n", ret, entry);
+       #endif
        if( entry ) {
                char    *argv[] = {NULL};
+               #if DEBUG
                printf("Calling '%s' entry point %p\n", Name, entry);
+               #endif
                entry(0, argv, NULL);
        }
 
@@ -116,8 +126,8 @@ void *Binary_LoadLibrary(const char *Name)
 
 void *Binary_Load(const char *Filename, uintptr_t *EntryPoint)
 {
-       FILE    *fp;
-       uint32_t        dword;
+        int    fd;
+       uint32_t        dword = 0xFA17FA17;
        void    *ret;
        uintptr_t       entry = 0;
        tBinFmt *fmt;
@@ -138,36 +148,43 @@ void *Binary_Load(const char *Filename, uintptr_t *EntryPoint)
                }
        }
 
-       fp = fopen(Filename, "r");
-       if( !fp ) {
+       fd = acess_open(Filename, 2|1); // Execute and Read
+       if( fd == -1 ) {
                // TODO: Handle libary directories
                perror("Opening binary");
                return NULL;
        }
 
-       fread(&dword, 1, 4, fp);
-       fseek(fp, 0, SEEK_SET);
+       acess_read(fd, 4, &dword);
+       acess_seek(fd, 0, ACESS_SEEK_SET);
        
        if( memcmp(&dword, "\x7F""ELF", 4) == 0 ) {
                fmt = &gElf_FormatDef;
        }
        else {
-               fclose(fp);
+               fprintf(stderr, "Unknown executable format (0x%08x)\n", dword);
+               acess_close(fd);
                return NULL;
        }
        
-       printf("fmt->Load(%p)...\n", fp);
-       ret = fmt->Load(fp);
-       printf("fmt->Load(%p): %p\n", fp, ret);
+       #if DEBUG
+       printf("fmt->Load(%i)...\n", fd);
+       #endif
+       ret = fmt->Load(fd);
+       acess_close(fd);
+       #if DEBUG
+       printf("fmt->Load(%p): %p\n", fd, ret);
+       #endif
        if( !ret ) {
-               fclose(fp);
                return NULL;
        }
        
        Binary_AddToList(Filename, ret, fmt);
 
        entry = fmt->Relocate(ret);
+       #if DEBUG
        printf("fmt->Relocate(%p): %p\n", ret, (void*)entry);
+       #endif
        if( !entry ) {
                // TODO: Clean up
                return NULL;
@@ -176,8 +193,6 @@ void *Binary_Load(const char *Filename, uintptr_t *EntryPoint)
        if( EntryPoint )
                *EntryPoint = entry;
 
-       fclose(fp);
-
        Binary_SetReadyToUse(ret);
 
        return ret;
index 4667acb..b544a45 100644 (file)
@@ -18,6 +18,15 @@ extern uintptr_t     FindFreeRange(size_t ByteCount, int MaxBits);
 extern void    Warning(const char *Format, ...);
 extern void    Notice(const char *Format, ...);
 
+#define ACESS_SEEK_CUR 0
+#define ACESS_SEEK_SET 1
+#define ACESS_SEEK_END -1
+
+extern int     acess_open(const char *Path, int Flags);
+extern void    acess_close(int FD);
+extern size_t  acess_read(int FD, size_t Bytes, void *Dest);
+extern int     acess_seek(int FD, int64_t Offset, int Dir);
+
 typedef struct {
        char    *Name;
        void    *Value;
@@ -26,7 +35,7 @@ typedef struct {
 typedef struct sBinFmt {
        struct sBinFmt  *Next;
        char    *Name;
-       void    *(*Load)(FILE *fp);
+       void    *(*Load)(int fd);
        uintptr_t       (*Relocate)(void *base);
         int    (*GetSymbol)(void*,char*,uintptr_t*);
 }      tBinFmt;
index a79b591..b99f190 100644 (file)
 #endif\r
 \r
 // === PROTOTYPES ===\r
-void   *Elf_Load(FILE *FP);\r
+void   *Elf_Load(int FD);\r
 uintptr_t      Elf_Relocate(void *Base);\r
  int   Elf_GetSymbol(void *Base, char *Name, uintptr_t *ret);\r
  int   Elf_Int_DoRelocate(uint32_t r_info, uint32_t *ptr, uint32_t addend, Elf32_Sym *symtab, void *Base);\r
 uint32_t       Elf_Int_HashString(char *str);\r
 \r
 // === CODE ===\r
-void *Elf_Load(FILE *FP)\r
+void *Elf_Load(int FD)\r
 {\r
        Elf32_Ehdr      hdr;\r
        Elf32_Phdr      *phtab;\r
@@ -46,10 +46,10 @@ void *Elf_Load(FILE *FP)
        uint32_t        addr;\r
        uint32_t        baseDiff = 0;\r
        \r
-       ENTER("pFP", FP);\r
+       ENTER("iFD", FD);\r
        \r
        // Read ELF Header\r
-       fread(&hdr, sizeof(hdr), 1, FP);\r
+       acess_read(FD, sizeof(hdr), &hdr);\r
        \r
        // Check the file type\r
        if(hdr.ident[0] != 0x7F || hdr.ident[1] != 'E' || hdr.ident[2] != 'L' || hdr.ident[3] != 'F') {\r
@@ -74,8 +74,8 @@ void *Elf_Load(FILE *FP)
                return NULL;\r
        }\r
        LOG("hdr.phoff = 0x%08x\n", hdr.phoff);\r
-       fseek(FP, hdr.phoff, SEEK_SET);\r
-       fread(phtab, sizeof(Elf32_Phdr), hdr.phentcount, FP);\r
+       acess_seek(FD, hdr.phoff, ACESS_SEEK_SET);\r
+       acess_read(FD, sizeof(Elf32_Phdr) * hdr.phentcount, phtab);\r
        \r
        // Count Pages\r
        iPageCount = 0;\r
@@ -143,8 +143,8 @@ void *Elf_Load(FILE *FP)
                        char *tmp;\r
                        //if(ret->Interpreter)  continue;\r
                        tmp = malloc(phtab[i].FileSize);\r
-                       fseek(FP, phtab[i].Offset, SEEK_SET);\r
-                       fread(tmp, phtab[i].FileSize, 1, FP);\r
+                       acess_seek(FD, phtab[i].Offset, ACESS_SEEK_SET);\r
+                       acess_read(FD, phtab[i].FileSize, tmp);\r
                        //ret->Interpreter = Binary_RegInterp(tmp);\r
                        LOG("Interpreter '%s'\n", tmp);\r
                        free(tmp);\r
@@ -165,8 +165,8 @@ void *Elf_Load(FILE *FP)
                        return NULL;\r
                }\r
                \r
-               fseek(FP, phtab[i].Offset, SEEK_SET);\r
-               fread( PTRMK(void, addr), phtab[i].FileSize, 1, FP );\r
+               acess_seek(FD, phtab[i].Offset, ACESS_SEEK_SET);\r
+               acess_read(FD, phtab[i].FileSize, PTRMK(void, addr) );\r
                memset( PTRMK(char, addr) + phtab[i].FileSize, 0, phtab[i].MemSize - phtab[i].FileSize );\r
        }\r
        \r
index b2a8660..852b398 100644 (file)
@@ -4,6 +4,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <string.h>
 
 // === CODE ===
 int main(int argc, char *argv[], char **envp)
@@ -11,12 +12,32 @@ int main(int argc, char *argv[], char **envp)
         int    i;
         int    appArgc;
        char    **appArgv;
-       char    *appPath;
+       char    *appPath = NULL;
         int    (*appMain)(int, char *[], char **);
        void    *base;
        
+        int    syscall_handle = -1;
+       
        for( i = 1; i < argc; i ++ )
        {
+               if(strcmp(argv[i], "--key") == 0) {
+                       syscall_handle = atoi(argv[++i]);
+                       continue ;
+               }
+               
+               if(strcmp(argv[i], "--binary") == 0) {
+                       appPath = argv[++i];
+                       continue ;
+               }
+               
+               if(strcmp(argv[i], "--open") == 0) {
+                       if( acess_open(argv[++i], 6) == -1 ) {  // Read/Write
+                               fprintf(stderr, "Unable to open '%s'\n", argv[i]);
+                               exit(1);
+                       }
+                       continue ;
+               }
+               
                if( argv[i][0] != '-' ) break;
        }
 
@@ -25,7 +46,8 @@ int main(int argc, char *argv[], char **envp)
                return 1;
        }
        
-       appPath = argv[i];
+       if( !appPath )
+               appPath = argv[i];
 
        appArgc = argc - i;
        appArgv = &argv[i];
@@ -47,7 +69,6 @@ int main(int argc, char *argv[], char **envp)
                "push %2;\n\t"
                "jmp *%3;\n\t"
                : : "r" (envp), "r" (appArgv), "r" (appArgc), "r" (appMain) );
-       //return appMain(appArgc, appArgv, envp);
        return -1;
 }
 
index c5e89ef..75565f1 100644 (file)
@@ -89,6 +89,7 @@ int _InitSyscalls()
                #endif
                exit(0);
        }
+       giSyscall_ClientID = gSocket;   // A bit of a hack really :(
        #endif
        
        #if 0
@@ -130,7 +131,7 @@ int _InitSyscalls()
        return 0;
 }
 
-int SendRequest(tRequestHeader *Request, int RequestSize)
+int SendRequest(tRequestHeader *Request, int RequestSize, int ResponseSize)
 {
        if( gSocket == INVALID_SOCKET )
        {
@@ -153,38 +154,38 @@ int SendRequest(tRequestHeader *Request, int RequestSize)
        {
                 int    i;
                char    *data = (char*)&Request->Params[Request->NParams];
-               printf("Request #%i\n", Request->CallID);
+               printf("Request #%i (%s) -", Request->CallID, casSYSCALL_NAMES[Request->CallID]);
                for( i = 0; i < Request->NParams; i ++ )
                {
-                       printf("%i: ", i);
                        switch(Request->Params[i].Type)
                        {
                        case ARG_TYPE_INT32:
-                               printf("INT32 %x", *(uint32_t*)data);
+                               printf(" 0x%08x", *(uint32_t*)data);
                                data += sizeof(uint32_t);
                                break;
                        case ARG_TYPE_INT64:
-                               printf("INT64 %llx", *(uint64_t*)data);
+                               printf(" 0x%016llx", *(uint64_t*)data);
                                data += sizeof(uint64_t);
                                break;
                        case ARG_TYPE_STRING:
-                               printf("STRING '%s'", (char*)data);
+                               printf(" '%s'", (char*)data);
                                data += Request->Params[i].Length;
                                break;
                        case ARG_TYPE_DATA:
-                               printf("DATA %i %p", Request->Params[i].Length, (char*)data);
-                               data += Request->Params[i].Length;
+                               printf(" %p:0x%x", (char*)data, Request->Params[i].Length);
+                               if( !(Request->Params[i].Flags & ARG_FLAG_ZEROED) )
+                                       data += Request->Params[i].Length;
                                break;
                        }
-                       printf("\n");
                }
+               printf("\n");
        }
        
        // Send it off
        SendData(Request, RequestSize);
        
        // Wait for a response (no timeout)
-       return ReadData(Request, RequestSize, 0);
+       return ReadData(Request, ResponseSize, 0);
 }
 
 void SendData(void *Data, int Length)
index b33a80f..f31a633 100644 (file)
@@ -10,6 +10,6 @@
 
 #include "../syscalls.h"
 
-extern int     SendRequest(tRequestHeader *Request, int RequestSize);
+extern int     SendRequest(tRequestHeader *Request, int RequestSize, int ResponseSize);
 
 #endif
index 02a59b9..2a63622 100644 (file)
@@ -1,5 +1,6 @@
 /*
  */
+#define DONT_INCLUDE_SYSCALL_NAMES 1
 #include "../../Usermode/include/acess/sys.h"
 #include "common.h"
 #include <stdio.h>
@@ -7,12 +8,22 @@
 #include <stdint.h>
 #include <stdarg.h>
 #include <string.h>
+#include <stddef.h>
 #include "request.h"
 #include "../syscalls.h"
 
+#define DEBUG(x...)    printf(x)
+
+#define NATIVE_FILE_MASK       0x40000000
+#define        MAX_FPS 16
+
 // === Types ===
 
 // === IMPORTS ===
+extern int     giSyscall_ClientID;     // Needed for execve
+
+// === GLOBALS ===
+FILE   *gaSyscall_LocalFPs[MAX_FPS];
 
 // === CODE ===
 const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const char *ArgTypes, va_list *Args)
@@ -53,7 +64,6 @@ const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const
                }
                
                val32 = va_arg(*Args, uint32_t);
-               printf("val32 = 0x%x\n", val32);
                
                Dest->Type = ARG_TYPE_INT32;
                Dest->Length = sizeof(uint32_t);
@@ -71,7 +81,6 @@ const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const
                }
                
                val64 = va_arg(*Args, uint64_t);
-               printf("val64 = 0x%llx\n", val64);
                
                Dest->Type = ARG_TYPE_INT64;
                Dest->Length = sizeof(uint64_t);
@@ -88,7 +97,6 @@ const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const
                }
                
                str = va_arg(*Args, char*);
-               printf("str = %p '%s'\n", str, str);
                
                Dest->Type = ARG_TYPE_STRING;
                Dest->Length = strlen(str) + 1;
@@ -104,8 +112,6 @@ const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const
                len = va_arg(*Args, int);
                str = va_arg(*Args, char*);
                
-               printf("len = %i, str = %p\n", len, str);
-               
                // Save the pointer for later
                if( PtrDest )   *PtrDest = str;
                
@@ -159,6 +165,11 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...)
        uint64_t        retValue;
         int    i;
        
+       // DEBUG!
+//     printf("&tRequestHeader->Params = %i\n", offsetof(tRequestHeader, Params));
+//     printf("&tRequestValue->Flags = %i\n", offsetof(tRequestValue, Flags));
+//     printf("&tRequestValue->Length = %i\n", offsetof(tRequestValue, Length));
+       
        // Get data size
        va_start(args, ArgTypes);
        str = ArgTypes;
@@ -219,7 +230,7 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...)
        va_end(args);
        
        // Send syscall request
-       if( SendRequest(req, dataLength) < 0 ) {
+       if( SendRequest(req, dataLength, retLength) < 0 ) {
                fprintf(stderr, "syscalls.c: SendRequest failed (SyscallID = %i)\n", SyscallID);
                exit(127);
        }
@@ -227,7 +238,7 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...)
        // Parse return value
        dataPtr = &req->Params[req->NParams];
        retValue = 0;
-       if( req->NParams > 1 )
+       if( req->NParams >= 1 )
        {
                switch(req->Params[0].Type)
                {
@@ -243,94 +254,241 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...)
        }
        
        // Write changes to buffers
-       va_start(args, ArgTypes);
+       retCount = 0;
        for( i = 1; i < req->NParams; i ++ )
        {
-               memcpy( retPtrs[i-1], dataPtr, req->Params[i].Length );
+               #if 0
+                int     j;
+               printf("Return Data %i: (%i)", i, req->Params[i].Length);
+               for( j = 0; j < req->Params[i].Length; j ++ )
+                       printf(" %02x", ((uint8_t*)dataPtr)[j]);
+               printf("\n");
+               #endif
+               memcpy( retPtrs[retCount++], dataPtr, req->Params[i].Length );
                dataPtr += req->Params[i].Length;
        }
-       va_end(args);
        
        free( req );
+       free( retPtrs );
        
-       return 0;
+       printf("Return %llx\n", retValue);
+       
+       return retValue;
 }
 
 // --- VFS Calls
-int open(const char *Path, int Flags) {
+int acess_open(const char *Path, int Flags)
+{
+       if( strncmp(Path, "$$$$", 4) == 0 )
+       {
+                int    ret;
+               for(ret = 0; ret < MAX_FPS && gaSyscall_LocalFPs[ret]; ret ++ ) ;
+               if(ret == MAX_FPS)      return -1;
+               // TODO: Handle directories
+               gaSyscall_LocalFPs[ret] = fopen(&Path[4], "r+");
+               if(!gaSyscall_LocalFPs[ret])    return -1;
+               return ret|NATIVE_FILE_MASK;
+       }
+       DEBUG("open(\"%s\", 0x%x)\n", Path, Flags);
        return _Syscall(SYS_OPEN, ">s >i", Path, Flags);
 }
 
-void close(int FD) {
+void acess_close(int FD) {
+       if(FD & NATIVE_FILE_MASK) {
+               fclose( gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)] );
+               gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)] = NULL;
+               return ;
+       }
+       DEBUG("close(%i)\n", FD);
        _Syscall(SYS_CLOSE, ">i", FD);
 }
 
-int reopen(int FD, const char *Path, int Flags) {
+int acess_reopen(int FD, const char *Path, int Flags) {
+       DEBUG("reopen(0x%x, \"%s\", 0x%x)\n", FD, Path, Flags);
        return _Syscall(SYS_REOPEN, ">i >s >i", FD, Path, Flags);
 }
 
-size_t read(int FD, size_t Bytes, void *Dest) {
-       return _Syscall(SYS_READ, "<i >i >i <d", FD, Bytes, Bytes, Dest);
+size_t acess_read(int FD, size_t Bytes, void *Dest) {
+       if(FD & NATIVE_FILE_MASK)
+               return fread( Dest, Bytes, 1, gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)] );
+       DEBUG("read(0x%x, 0x%x, *%p)\n", FD, Bytes, Dest);
+       return _Syscall(SYS_READ, ">i >i <d", FD, Bytes, Bytes, Dest);
 }
 
-size_t write(int FD, size_t Bytes, void *Src) {
+size_t acess_write(int FD, size_t Bytes, void *Src) {
+       if(FD & NATIVE_FILE_MASK)
+               return fwrite( Src, Bytes, 1, gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)] );
+       DEBUG("write(0x%x, 0x%x, %p(\"%.*s\"))\n", FD, Bytes, Src, Bytes, (char*)Src);
        return _Syscall(SYS_WRITE, ">i >i >d", FD, Bytes, Bytes, Src);
 }
 
-int seek(int FD, int64_t Ofs, int Dir) {
+int acess_seek(int FD, int64_t Ofs, int Dir) {
+       if(FD & NATIVE_FILE_MASK) {
+               switch(Dir) {
+               case ACESS_SEEK_SET:    Dir = SEEK_SET; break;
+               default:
+               case ACESS_SEEK_CUR:    Dir = SEEK_CUR; break;
+               case ACESS_SEEK_END:    Dir = SEEK_END; break;
+               }
+               return fseek( gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)], Ofs, Dir );
+       }
+       DEBUG("seek(0x%x, 0x%llx, %i)\n", FD, Ofs, Dir);
        return _Syscall(SYS_SEEK, ">i >I >i", FD, Ofs, Dir);
 }
 
-uint64_t tell(int FD) {
+uint64_t acess_tell(int FD) {
+       if(FD & NATIVE_FILE_MASK)
+               return ftell( gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)] );
        return _Syscall(SYS_TELL, ">i", FD);
 }
 
-int ioctl(int fd, int id, void *data) {
+int acess_ioctl(int fd, int id, void *data) {
        // NOTE: 1024 byte size is a hack
        return _Syscall(SYS_IOCTL, ">i >i ?d", fd, id, 1024, data);
 }
-int finfo(int fd, t_sysFInfo *info, int maxacls) {
+int acess_finfo(int fd, t_sysFInfo *info, int maxacls) {
        return _Syscall(SYS_FINFO, ">i <d >i",
                fd,
                sizeof(t_sysFInfo)+maxacls*sizeof(t_sysACL), info,
                maxacls);
 }
 
-int readdir(int fd, char *dest) {
+int acess_readdir(int fd, char *dest) {
        return _Syscall(SYS_READDIR, ">i <d", fd, 256, dest);
 }
 
-int _SysOpenChild(int fd, char *name, int flags) {
+int acess__SysOpenChild(int fd, char *name, int flags) {
        return _Syscall(SYS_OPENCHILD, ">i >s >i", fd, name, flags);
 }
 
-int _SysGetACL(int fd, t_sysACL *dest) {
+int acess__SysGetACL(int fd, t_sysACL *dest) {
        return _Syscall(SYS_GETACL, "<i >i <d", fd, sizeof(t_sysACL), dest);
 }
 
-int _SysMount(const char *Device, const char *Directory, const char *Type, const char *Options) {
+int acess__SysMount(const char *Device, const char *Directory, const char *Type, const char *Options) {
        return _Syscall(SYS_MOUNT, ">s >s >s >s", Device, Directory, Type, Options);
 }
 
 
 // --- Error Handler
-int    _SysSetFaultHandler(int (*Handler)(int)) {
+int    acess__SysSetFaultHandler(int (*Handler)(int)) {
        return 0;
 }
 
 // --- Memory Management ---
-uint64_t _SysAllocate(uint vaddr)
+uint64_t acess__SysAllocate(uint vaddr)
 {
        if( AllocateMemory(vaddr, 0x1000) == -1 )       // Allocate a page
                return 0;
+               
        return vaddr;   // Just ignore the need for paddrs :)
 }
 
+// --- Process Management ---
+int acess_clone(int flags, void *stack)
+{
+       extern int fork(void);
+       if(flags & CLONE_VM) {
+                int    ret, newID, kernel_tid=0;
+               printf("fork()\n");
+               
+               newID = _Syscall(SYS_FORK, "<i", &kernel_tid);
+               ret = fork();
+               if(ret < 0)     return ret;
+               
+               if(ret == 0)
+               {
+                       giSyscall_ClientID = newID;
+                       return 0;
+               }
+               
+               // TODO: Return the acess TID instead
+               return kernel_tid;
+       }
+       else
+       {
+               fprintf(stderr, "ERROR: Threads currently unsupported\n");
+               exit(-1);
+       }
+}
+
+int acess_execve(char *path, char **argv, char **envp)
+{
+        int    i, argc;
+       
+       printf("acess_execve: (path='%s', argv=%p, envp=%p)\n", path, argv, envp);
+       
+       // Get argument count
+       for( argc = 0; argv[argc]; argc ++ ) ;
+       printf(" acess_execve: argc = %i\n", argc);
+       
+       char    *new_argv[5+argc+1];
+       char    key[11];
+       sprintf(key, "%i", giSyscall_ClientID);
+       new_argv[0] = "ld-acess";       // TODO: Get path to ld-acess executable
+       new_argv[1] = "--key";  // Set socket/client ID for Request.c
+       new_argv[2] = key;
+       new_argv[3] = "--binary";       // Set the binary path (instead of using argv[0])
+       new_argv[4] = path;
+       for( i = 0; i < argc; i ++ )    new_argv[5+i] = argv[i];
+       new_argv[5+i] = NULL;
+       
+       #if 1
+       argc += 5;
+       for( i = 0; i < argc; i ++ )
+               printf("\"%s\" ", new_argv[i]);
+       printf("\n");
+       #endif
+       
+       // Call actual execve
+       return execve("./ld-acess", new_argv, envp);
+}
+
+void acess_sleep(void)
+{
+       _Syscall(SYS_SLEEP, "");
+}
+
+int acess_waittid(int TID, int *ExitStatus)
+{
+       return _Syscall(SYS_WAITTID, ">i <i", TID, ExitStatus);
+}
+
+int acess_setuid(int ID)
+{
+       return _Syscall(SYS_SETUID, ">i", ID);
+}
+
+int acess_setgid(int ID)
+{
+       return _Syscall(SYS_SETGID, ">i", ID);
+}
+
+// --- Logging
+void acess__SysDebug(const char *Format, ...)
+{
+       va_list args;
+       
+       va_start(args, Format);
+       
+       printf("[_SysDebug] ");
+       vprintf(Format, args);
+       printf("\n");
+       
+       va_end(args);
+}
+
+void acess__exit(int Status)
+{
+       _Syscall(SYS_EXIT, ">i", Status);
+       exit(Status);
+}
+
 
 // === Symbol List ===
-#define DEFSYM(name)   {#name, name}
+#define DEFSYM(name)   {#name, acess_##name}
 const tSym     caBuiltinSymbols[] = {
-       {"_exit", exit},
+       DEFSYM(_exit),
        
        DEFSYM(open),
        DEFSYM(close),
@@ -346,9 +504,17 @@ const tSym caBuiltinSymbols[] = {
        DEFSYM(_SysGetACL),
        DEFSYM(_SysMount),
        
-       DEFSYM(_SysAllocate),
+       DEFSYM(clone),
+       DEFSYM(execve),
+       DEFSYM(sleep),
+       
+       DEFSYM(waittid),
+       DEFSYM(setuid),
+       DEFSYM(setgid),
        
-       {"_SysSetFaultHandler", _SysSetFaultHandler}
+       DEFSYM(_SysAllocate),
+       DEFSYM(_SysDebug),
+       DEFSYM(_SysSetFaultHandler)
 };
 
 const int      ciNumBuiltinSymbols = sizeof(caBuiltinSymbols)/sizeof(caBuiltinSymbols[0]);
index b4d211c..158a6cc 100644 (file)
@@ -17,7 +17,7 @@
 typedef struct sRequestValue {
        /// \see eArgumentTypes
        uint16_t        Type;
-        uint8_t        Flags;
+       uint16_t        Flags;
        uint16_t        Length;
 }      tRequestValue;
 
@@ -31,6 +31,9 @@ typedef struct sRequestHeader {
 
 enum eSyscalls {
        SYS_NULL,
+       
+       SYS_EXIT,
+       
        SYS_OPEN,
        SYS_CLOSE,
        SYS_READ,
@@ -44,9 +47,43 @@ enum eSyscalls {
        SYS_GETACL,
        SYS_MOUNT,
        SYS_REOPEN,
+       
+       SYS_WAITTID,
+       SYS_SETUID,
+       SYS_SETGID,
+       
+       // IPC
+       SYS_SLEEP,
+       SYS_FORK,
+       
        N_SYSCALLS
 };
 
+#ifndef DONT_INCLUDE_SYSCALL_NAMES
+static const char * casSYSCALL_NAMES[] = {
+       "SYS_NULL",
+       
+       "SYS_EXIT",
+       
+       "SYS_OPEN",
+       "SYS_CLOSE",
+       "SYS_READ",
+       "SYS_WRITE",
+       "SYS_SEEK",
+       "SYS_TELL",
+       "SYS_IOCTL",
+       "SYS_FINFO",
+       "SYS_READDIR",
+       "SYS_OPENCHILD",
+       "SYS_GETACL",
+       "SYS_MOUNT",
+       "SYS_REOPEN",
+       
+       // IPC
+       "SYS_SLEEP"
+};
+#endif
+
 enum eArgumentTypes {
        ARG_TYPE_VOID,
        ARG_TYPE_INT32,

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