3 * - Acess kernel emulation on another OS using SDL and UDP
8 #include "../syscalls.h"
11 typedef int (*tSyscallHandler)(const char *Format, void *Args);
14 #define SYSCALL3(_name, _call, _fmtstr, _t1, _t2, _t3) int _name(const char *fmt,void*args){\
15 _t1 a1;_t2 a2;_t3 a3;\
16 if(strcmp(fmt,_fmtstr)!=0)return 0;\
17 a1 = *(_t1*)args;args+=sizeof(_t1);\
18 a2 = *(_t2*)args;args+=sizeof(_t2);\
19 a3 = *(_t3*)args;args+=sizeof(_t3);\
20 return _call(a1,a2,a3);\
23 #define SYSCALL2(_name, _call, _fmtstr, _t1, _t2) int _name(const char *fmt,void*args){\
25 if(strcmp(fmt,_fmtstr)!=0)return 0;\
26 a1 = *(_t1*)args;args+=sizeof(_t1);\
27 a2 = *(_t2*)args;args+=sizeof(_t2);\
31 #define SYSCALL1V(_name, _call, _fmtstr, _t1) int _name(const char *fmt, void*args){\
33 if(strcmp(fmt,_fmtstr)!=0)return 0;\
34 a1 = *(_t1*)args;args+=sizeof(_t1);\
40 int Syscall_Null(const char *Format, void *Args)
45 SYSCALL2(Syscall_Open, VFS_Open, "si", const char *, int);
46 SYSCALL1V(Syscall_Close, VFS_Close, "i", int);
47 SYSCALL3(Syscall_Read, VFS_Read, "iid", int, int, void *);
48 SYSCALL3(Syscall_Write, VFS_Write, "iid", int, int, const void *);
51 const tSyscallHandler caSyscalls[] = {
58 const int ciNumSyscalls = sizeof(caSyscalls)/sizeof(caSyscalls[0]);
60 * \brief Recieve a syscall structure from the server code
62 tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
64 char formatString[Request->NParams+1];
65 char *inData = (char*)&Request->Params[Request->NParams];
69 int retValueCount = 1;
70 int retDataLen = sizeof(Uint64);
71 void *mallocdData[Request->NParams];
74 if( Request->CallID > ciNumSyscalls ) {
78 // Get size of argument list
79 for( i = 0; i < Request->NParams; i ++ )
81 switch(Request->Params[i].Type)
84 formatString[i] = '-';
87 formatString[i] = 'i';
88 argListLen += sizeof(Uint32);
91 formatString[i] = 'I';
92 argListLen += sizeof(Uint64);
95 formatString[i] = 'd';
96 argListLen += sizeof(void*);
99 formatString[i] = 's';
100 argListLen += sizeof(char*);
103 return NULL; // ERROR!
108 char argListData[argListLen];
110 // Build argument list
111 for( i = 0; i < Request->NParams; i ++ )
113 switch(Request->Params[i].Type)
118 *(Uint32*)&argListData[argListLen] = *(Uint32*)inData;
119 argListLen += sizeof(Uint32);
120 inData += sizeof(Uint32);
123 *(Uint64*)&argListData[argListLen] = *(Uint64*)inData;
124 argListLen += sizeof(Uint64);
125 inData += sizeof(Uint64);
127 case ARG_TYPE_STRING:
128 *(void**)&argListData[argListLen] = *(void**)inData;
129 argListLen += sizeof(void*);
130 inData += Request->Params[i].Length;
133 // Data gets special handling, because only it can be returned to the user
134 // (ARG_TYPE_DATA is a pointer)
136 // Prepare the return values
137 if( Request->Params[i].Flags & ARG_FLAG_RETURN )
139 retDataLen += Request->Params[i].Length;
143 // Check for non-resident data
144 if( Request->Params[i].Flags & ARG_FLAG_ZEROED )
146 // Allocate and zero the buffer
147 mallocdData[i] = calloc(1, Request->Params[i].Length);
148 *(void**)&argListData[argListLen] = mallocdData[i];
149 argListLen += sizeof(void*);
153 *(void**)&argListData[argListLen] = (void*)inData;
154 argListLen += sizeof(void*);
155 inData += Request->Params[i].Length;
161 retVal = caSyscalls[Request->CallID](formatString, argListData);
164 // Allocate the return
165 ret = malloc(sizeof(tRequestHeader) + retValueCount * sizeof(tRequestValue)
167 ret->ClientID = Request->ClientID;
168 ret->CallID = Request->CallID;
169 ret->NParams = retValueCount;
170 inData = &ret->Params[ ret->NParams ];
172 // Static Uint64 return value
173 ret->Params[0].Type = ARG_TYPE_INT64;
174 ret->Params[0].Flags = 0;
175 ret->Params[0].Length = sizeof(Uint64);
176 *(Uint64*)inData = retVal;
177 inData += sizeof(Uint64);
179 for( i = 0; i < Request->NParams; i ++ )
181 if( Request->Params[i].Type != ARG_TYPE_DATA ) continue;
182 if( !(Request->Params[i].Flags & ARG_FLAG_RETURN) ) continue;
184 ret->Params[1 + i].Type = Request->Params[i].Type;
185 ret->Params[1 + i].Flags = 0;
186 ret->Params[1 + i].Length = Request->Params[i].Length;
188 memcpy(inData, mallocdData[i], Request->Params[i].Length);
189 inData += Request->Params[i].Length;
191 free( mallocdData[i] ); // Free temp buffer from above