tClient gaServer_Clients[MAX_CLIENTS];
// === CODE ===
+int Server_GetClientID(void)
+{
+ int i;
+ Uint32 thisId = SDL_ThreadID();
+
+ for( i = 0; i < MAX_CLIENTS; i ++ )
+ {
+ if( SDL_GetThreadID(gaServer_Clients[i].WorkerThread) == thisId )
+ return gaServer_Clients[i].ClientID;
+ }
+
+ fprintf(stderr, "ERROR: Server_GetClientID - Thread is not allocated\n");
+
+ return 0;
+}
+
tClient *Server_GetClient(int ClientID)
{
tClient *ret = NULL;
{
tClient *Client = ClientPtr;
tRequestHeader *retHeader;
+ tRequestHeader errorHeader;
int retSize = 0;
int sentSize;
for( ;; )
{
// Wait for something to do
- while( !Client->CurrentRequest ) ;
+ while( Client->CurrentRequest == NULL )
+ SDL_CondWait(Client->WaitFlag, Client->Mutex);
+
+ printf("Worker for %i, Job: %p\n", 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");
+ errorHeader.CallID = Client->CurrentRequest->CallID;
+ errorHeader.NParams = 0;
+ retHeader = &errorHeader;
+ retSize = sizeof(errorHeader);
}
+ // Set ID
+ retHeader->ClientID = Client->ClientID;
+
+ // Mark the thread as ready for another job
+ Client->CurrentRequest = 0;
+
+ printf("Sending %i to %x:%i\n",
+ retSize, ntohl(Client->ClientAddr.sin_addr.s_addr),
+ ntohs(Client->ClientAddr.sin_port)
+ );
+
// Return the data
sentSize = sendto(gSocket, retHeader, retSize, 0,
(struct sockaddr*)&Client->ClientAddr, sizeof(Client->ClientAddr)
}
// Free allocated header
- free( retHeader );
-
- Client->CurrentRequest = 0;
-
- // Wait for something else
- SDL_CondWait(Client->WaitFlag, Client->Mutex);
+ if( retHeader != &errorHeader )
+ free( retHeader );
}
#endif
}
continue;
}
+ printf("client = %p, ClientID = %i\n", client, client->ClientID);
+
client->CurrentRequest = req;
SDL_CondSignal(client->WaitFlag);
#endif
#include "../syscalls.h"
// === TYPES ===
-typedef int (*tSyscallHandler)(const char *Format, void *Args);
+typedef int (*tSyscallHandler)(const char *Format, void *Args, int *Sizes);
// === MACROS ===
-#define SYSCALL3(_name, _call, _fmtstr, _t1, _t2, _t3) int _name(const char *fmt,void*args){\
- _t1 a1;_t2 a2;_t3 a3;\
- if(strcmp(fmt,_fmtstr)!=0)return 0;\
- a1 = *(_t1*)args;args+=sizeof(_t1);\
- a2 = *(_t2*)args;args+=sizeof(_t2);\
- a3 = *(_t3*)args;args+=sizeof(_t3);\
- return _call(a1,a2,a3);\
+#define SYSCALL3(_name, _fmtstr, _t0, _t1, _t2, _call) int _name(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);\
+ a1 = *(_t1*)Args;Args+=sizeof(_t1);\
+ a2 = *(_t2*)Args;Args+=sizeof(_t2);\
+ _call\
}
-#define SYSCALL2(_name, _call, _fmtstr, _t1, _t2) int _name(const char *fmt,void*args){\
- _t1 a1;_t2 a2;\
- if(strcmp(fmt,_fmtstr)!=0)return 0;\
- a1 = *(_t1*)args;args+=sizeof(_t1);\
- a2 = *(_t2*)args;args+=sizeof(_t2);\
- return _call(a1,a2);\
+#define SYSCALL2(_name, _fmtstr, _t0, _t1, _call) int _name(const char*Fmt,void*Args,int*Sizes){\
+ _t0 a0;_t1 a1;\
+ if(strcmp(Fmt,_fmtstr)!=0)return 0;\
+ a0 = *(_t0*)Args;Args+=sizeof(_t0);\
+ a1 = *(_t1*)Args;Args+=sizeof(_t1);\
+ _call;\
}
-#define SYSCALL1V(_name, _call, _fmtstr, _t1) int _name(const char *fmt, void*args){\
- _t1 a1;\
- if(strcmp(fmt,_fmtstr)!=0)return 0;\
- a1 = *(_t1*)args;args+=sizeof(_t1);\
- _call(a1);\
- return 0;\
+#define SYSCALL1(_name, _fmtstr, _t0, _call) int _name(const char*Fmt, void*Args,int*Sizes){\
+ _t0 a0;\
+ if(strcmp(Fmt,_fmtstr)!=0)return 0;\
+ a0 = *(_t0*)Args;Args+=sizeof(_t0);\
+ _call;\
}
// === CODE ===
-int Syscall_Null(const char *Format, void *Args)
+int Syscall_Null(const char *Format, void *Args, int *Sizes)
{
return 0;
}
-SYSCALL2(Syscall_Open, VFS_Open, "si", const char *, int);
-SYSCALL1V(Syscall_Close, VFS_Close, "i", int);
-SYSCALL3(Syscall_Read, VFS_Read, "iid", int, int, void *);
-SYSCALL3(Syscall_Write, VFS_Write, "iid", int, int, const void *);
+SYSCALL2(Syscall_Open, "si", const char *, int,
+ return VFS_Open(a0, a1|VFS_OPENFLAG_USER);
+);
+SYSCALL1(Syscall_Close, "i", int,
+ VFS_Close(a0);
+ return 0;
+);
+SYSCALL3(Syscall_Read, "iid", int, int, void *,
+ if( Sizes[2] <= a1 )
+ return -1;
+ return VFS_Read(a0, a1, a2);
+);
+SYSCALL3(Syscall_Write, "iid", int, int, const void *,
+ if( Sizes[2] <= a1 )
+ return -1;
+ return VFS_Write(a0, a1, a2);
+);
+SYSCALL3(Syscall_Seek, "iIi", int, int64_t, int,
+ return VFS_Seek(a0, a1, a2);
+);
+SYSCALL1(Syscall_Tell, "i", int,
+ return VFS_Tell(a0);
+);
+SYSCALL3(Syscall_IOCtl, "iid", int, int, void *,
+ return VFS_IOCtl(a0, a1, a2);
+);
+SYSCALL3(Syscall_FInfo, "idi", int, void *, int,
+ if( Sizes[1] < sizeof(tFInfo)+a2*sizeof(tVFS_ACL))
+ return -1;
+ return VFS_FInfo(a0, a1, a2);
+);
const tSyscallHandler caSyscalls[] = {
Syscall_Open,
Syscall_Close,
Syscall_Read,
- Syscall_Write
+ Syscall_Write,
+ Syscall_Seek,
+ Syscall_Tell,
+ Syscall_IOCtl,
+ Syscall_FInfo
};
const int ciNumSyscalls = sizeof(caSyscalls)/sizeof(caSyscalls[0]);
/**
tRequestHeader *ret;
int retValueCount = 1;
int retDataLen = sizeof(Uint64);
- void *mallocdData[Request->NParams];
+ void *returnData[Request->NParams];
+ int argSizes[Request->NParams];
// Sanity check
- if( Request->CallID > ciNumSyscalls ) {
+ if( Request->CallID >= ciNumSyscalls ) {
+ Log_Notice("Syscalls", "Unknown syscall number %i", Request->CallID);
return NULL;
}
// Get size of argument list
for( i = 0; i < Request->NParams; i ++ )
{
+ argSizes[i] = Request->Params[i].Length;
switch(Request->Params[i].Type)
{
case ARG_TYPE_VOID:
return NULL; // ERROR!
}
}
+ formatString[i] = '\0';
+
+ Log_Debug("Syscalls", "Request %i '%s'", Request->CallID, formatString);
{
char argListData[argListLen];
// Build argument list
for( i = 0; i < Request->NParams; i ++ )
{
+ returnData[i] = NULL;
switch(Request->Params[i].Type)
{
case ARG_TYPE_VOID:
break;
case ARG_TYPE_INT32:
+ Log_Debug("Syscalls", "Arg %i: 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);
*(Uint64*)&argListData[argListLen] = *(Uint64*)inData;
argListLen += sizeof(Uint64);
inData += sizeof(Uint64);
break;
case ARG_TYPE_STRING:
- *(void**)&argListData[argListLen] = *(void**)inData;
+ Log_Debug("Syscalls", "Arg %i: '%s'", i, (char*)inData);
+ *(char**)&argListData[argListLen] = (char*)inData;
argListLen += sizeof(void*);
inData += Request->Params[i].Length;
break;
if( Request->Params[i].Flags & ARG_FLAG_ZEROED )
{
// Allocate and zero the buffer
- mallocdData[i] = calloc(1, Request->Params[i].Length);
- *(void**)&argListData[argListLen] = mallocdData[i];
+ returnData[i] = calloc(1, Request->Params[i].Length);
+ Log_Debug("Syscalls", "Arg %i: %i %p", i,
+ Request->Params[i].Length, returnData[i]);
+ *(void**)&argListData[argListLen] = returnData[i];
argListLen += sizeof(void*);
}
else
{
+ returnData[i] = (void*)inData;
+ Log_Debug("Syscalls", "Arg %i: %i %p", i,
+ Request->Params[i].Length, returnData[i]);
*(void**)&argListData[argListLen] = (void*)inData;
argListLen += sizeof(void*);
inData += Request->Params[i].Length;
}
}
- retVal = caSyscalls[Request->CallID](formatString, argListData);
+ retVal = caSyscalls[Request->CallID](formatString, argListData, argSizes);
}
// Allocate the return
ret->ClientID = Request->ClientID;
ret->CallID = Request->CallID;
ret->NParams = retValueCount;
- inData = &ret->Params[ ret->NParams ];
+ inData = (char*)&ret->Params[ ret->NParams ];
// Static Uint64 return value
ret->Params[0].Type = ARG_TYPE_INT64;
*(Uint64*)inData = retVal;
inData += sizeof(Uint64);
+ Log_Debug("Syscalls", "Return 0x%llx", retVal);
+
for( i = 0; i < Request->NParams; i ++ )
{
if( Request->Params[i].Type != ARG_TYPE_DATA ) continue;
ret->Params[1 + i].Flags = 0;
ret->Params[1 + i].Length = Request->Params[i].Length;
- memcpy(inData, mallocdData[i], Request->Params[i].Length);
+ memcpy(inData, returnData[i], Request->Params[i].Length);
inData += Request->Params[i].Length;
- free( mallocdData[i] ); // Free temp buffer from above
+ if( Request->Params[i].Flags & ARG_FLAG_ZEROED )
+ free( returnData[i] ); // Free temp buffer from above
}
+ *ReturnLength = sizeof(tRequestHeader)
+ + retValueCount * sizeof(tRequestValue)
+ + retDataLen;
+
return ret;
}
#undef CLONE_VM // Such a hack
#include <acess.h>
#include <unistd.h>
+#include <sys/types.h>
#include <stdint.h>
#include "/usr/include/signal.h"
tUID Threads_GetUID() { return gpCurrentThread->UID; }
tGID Threads_GetGID() { return gpCurrentThread->GID; }
tTID Threads_GetTID() { return gpCurrentThread->TID; }
-tPID Threads_GetPID() { return gpCurrentThread->PID; }
+tPID Threads_GetPID() {
+ return SDL_ThreadID();
+ //return gpCurrentThread->PID;
+}
Uint *Threads_GetCfgPtr(int Index)
{
acess_sym = UI_GetAcessKeyFromSDL(event.key.keysym.sym,
event.key.keysym.unicode);
- //if( gUI_KeyboardCallback )
- // gUI_KeyboardCallback(0x80000000|acess_sym);
+ if( gUI_KeyboardCallback )
+ gUI_KeyboardCallback(0x80000000|acess_sym);
break;
default:
#define MAX_KERNEL_FILES 128
#define MAX_USER_FILES 64
+// === IMPORTS ===
+extern int Server_GetClientID(void);
+
// === PROTOTYPES ===
tVFS_Handle *VFS_GetHandle(int FD);
int VFS_AllocHandle(int FD, tVFS_Node *Node, int Mode);
+// === Types ===
typedef struct sUserHandles
{
struct sUserHandles *Next;
}
else {
tUserHandles *ent;
- int pid = Threads_GetPID();
+ int pid = Server_GetClientID();
for( ent = gpUserHandles; ent; ent = ent->Next ) {
if( ent->PID == pid ) break;
if( ent->PID > pid ) {
return NULL;
}
}
+ if( !ent ) {
+ Log_Error("VFS", "PID %i does not have a handle list", pid);
+ return NULL;
+ }
if(FD >= CFGINT(CFG_VFS_MAXFILES)) return NULL;
h = &ent->Handles[ FD ];
}
// Check for a user open
if(bIsUser)
{
- tUserHandles *ent, *prev;
- int pid = Threads_GetPID();
+ 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->PID > pid ) {
+ if( !ent || ent->PID > pid ) {
ent = calloc( 1, sizeof(tUserHandles) );
+ ent->PID = pid;
if( prev ) {
ent->Next = prev->Next;
prev->Next = ent;
printf("\n");
}
#endif
+ {
+ int i;
+ char *data = (char*)&Request->Params[Request->NParams];
+ printf("Request #%i\n", 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);
+ data += sizeof(uint32_t);
+ break;
+ case ARG_TYPE_INT64:
+ printf("INT64 %llx", *(uint64_t*)data);
+ data += sizeof(uint64_t);
+ break;
+ case ARG_TYPE_STRING:
+ printf("STRING '%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;
+ break;
+ }
+ printf("\n");
+ }
+ }
// Send it off
SendData(Request, RequestSize);
// Wait for a response (no timeout)
- return ReadData(Request, RequestSize, -1);
+ return ReadData(Request, RequestSize, 0);
}
void SendData(void *Data, int Length)
int ret;
fd_set fds;
struct timeval tv;
+ struct timeval *timeoutPtr;
FD_ZERO(&fds);
FD_SET(gSocket, &fds);
- tv.tv_sec = Timeout;
- tv.tv_usec = 0;
+ if( Timeout ) {
+ tv.tv_sec = Timeout;
+ tv.tv_usec = 0;
+ timeoutPtr = &tv;
+ }
+ else {
+ timeoutPtr = NULL;
+ }
- ret = select(1, &fds, NULL, NULL, &tv);
+ ret = select(gSocket+1, &fds, NULL, NULL, timeoutPtr);
if( ret == -1 ) {
perror("ReadData - select");
exit(-1);
exit(-1);
}
+ printf("%i bytes read from socket\n", ret);
+
return ret;
}
// === IMPORTS ===
// === CODE ===
-const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const char *ArgTypes, va_list Args)
+const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const char *ArgTypes, va_list *Args)
{
uint64_t val64;
uint32_t val32;
return NULL;
}
- val32 = va_arg(Args, uint32_t);
+ val32 = va_arg(*Args, uint32_t);
+ printf("val32 = 0x%x\n", val32);
Dest->Type = ARG_TYPE_INT32;
Dest->Length = sizeof(uint32_t);
return NULL;
}
- val64 = va_arg(Args, uint64_t);
+ val64 = va_arg(*Args, uint64_t);
+ printf("val64 = 0x%llx\n", val64);
Dest->Type = ARG_TYPE_INT64;
Dest->Length = sizeof(uint64_t);
return NULL;
}
- str = va_arg(Args, char*);
+ str = va_arg(*Args, char*);
+ printf("str = %p '%s'\n", str, str);
Dest->Type = ARG_TYPE_STRING;
Dest->Length = strlen(str) + 1;
break;
// Data (special handling)
case 'd':
- len = va_arg(Args, int);
- str = va_arg(Args, char*);
+ 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;
// Create parameter block
- Dest->Type = ARG_TYPE_INT64;
- Dest->Length = sizeof(uint64_t);
+ Dest->Type = ARG_TYPE_DATA;
+ Dest->Length = len;
Dest->Flags = 0;
if( direction & 2 )
Dest->Flags |= ARG_FLAG_RETURN;
{
tRequestValue tmpVal;
- str = ReadEntry(&tmpVal, NULL, NULL, str, args);
+ str = ReadEntry(&tmpVal, NULL, NULL, str, &args);
if( !str ) {
fprintf(stderr, "syscalls.c: ReadEntry failed (SyscallID = %i)\n", SyscallID);
exit(127);
retCount = 0;
while(*str)
{
- str = ReadEntry(&req->Params[paramCount], dataPtr, &retPtrs[retCount], str, args);
+ str = ReadEntry(&req->Params[paramCount], dataPtr, &retPtrs[retCount], str, &args);
if( !str ) break;
if( !(req->Params[paramCount].Flags & ARG_FLAG_ZEROED) )
va_end(args);
// Send syscall request
- if( SendRequest(req, dataLength) ) {
+ if( SendRequest(req, dataLength) < 0 ) {
fprintf(stderr, "syscalls.c: SendRequest failed (SyscallID = %i)\n", SyscallID);
exit(127);
}
}
int ioctl(int fd, int id, void *data) {
- int ret = 0;
// NOTE: 1024 byte size is a hack
- _Syscall(SYS_IOCTL, "<i >i >i ?d", &ret, fd, id, 1024, data);
- return ret;
+ return _Syscall(SYS_IOCTL, ">i >i ?d", fd, id, 1024, data);
}
int finfo(int fd, t_sysFInfo *info, int maxacls) {
- int ret = 0;
- _Syscall(SYS_FINFO, "<i >i <d >i",
- &ret, fd,
+ return _Syscall(SYS_FINFO, ">i <d >i",
+ fd,
sizeof(t_sysFInfo)+maxacls*sizeof(t_sysACL), info,
maxacls);
- return ret;
}
int readdir(int fd, char *dest) {
- int ret = 0;
- _Syscall(SYS_READDIR, "<i >i <d", &ret, fd, 256, dest);
- return ret;
+ return _Syscall(SYS_READDIR, ">i <d", fd, 256, dest);
}
int _SysOpenChild(int fd, char *name, int flags) {
- int ret = 0;
- _Syscall(SYS_OPENCHILD, "<i >i >s >i", &ret, fd, name, flags);
- return ret;
+ return _Syscall(SYS_OPENCHILD, ">i >s >i", fd, name, flags);
}
int _SysGetACL(int fd, t_sysACL *dest) {
- int ret = 0;
- _Syscall(SYS_GETACL, "<i >i <d", &ret, fd, sizeof(t_sysACL), dest);
- return ret;
+ 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 ret = 0;
- _Syscall(SYS_MOUNT, "<i >s >s >s >s", &ret, Device, Directory, Type, Options);
- return ret;
+ return _Syscall(SYS_MOUNT, ">s >s >s >s", Device, Directory, Type, Options);
}
#endif
ent->Time = now();
strncpy(ent->Ident, Ident, 8);
+ ent->Ident[8] = '\0';
ent->Level = Level;
ent->Length = len;
vsnprintf( ent->Data, len+1, Format, Args );