3 #define DONT_INCLUDE_SYSCALL_NAMES 1
13 # include <spawn.h> // posix_spawn
18 #define assert(cnd) do{ \
20 fprintf(stderr, "%s:%i - assert failed - " #cnd"\n", __FILE__, __LINE__);\
30 extern int gbSyscallDebugEnabled;
33 FILE *gaSyscall_LocalFPs[MAX_FPS];
36 const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const char *ArgTypes, va_list *Args)
40 int direction = 0; // 0: Invalid, 1: Out, 2: In, 3: Out
45 while(*ArgTypes && *ArgTypes == ' ') ArgTypes ++;
46 if( *ArgTypes == '\0' ) return ArgTypes;
48 // DEBUG("ArgTypes = '%s'", ArgTypes);
53 default: // Defaults to output
54 case '>': direction = 1; break;
55 case '<': direction = 2; break;
56 case '?': direction = 3; break;
61 while(*ArgTypes && *ArgTypes == ' ') ArgTypes ++;
62 if( *ArgTypes == '\0' ) return ArgTypes;
70 if( direction != 1 ) {
71 Warning("ReadEntry: Recieving an integer is not defined");
75 val32 = va_arg(*Args, uint32_t);
77 Dest->Type = ARG_TYPE_INT32;
78 Dest->Length = sizeof(uint32_t);
82 *(uint32_t*)DataDest = val32;
87 if( direction != 1 ) {
88 fprintf(stderr, "ReadEntry: Recieving an integer is not defined\n");
92 val64 = va_arg(*Args, uint64_t);
94 Dest->Type = ARG_TYPE_INT64;
95 Dest->Length = sizeof(uint64_t);
98 *(uint64_t*)DataDest = val64;
102 // Input string makes no sense!
103 if( direction != 1 ) {
104 fprintf(stderr, "ReadEntry: Recieving a string is not defined\n");
108 str = va_arg(*Args, char*);
110 Dest->Type = ARG_TYPE_STRING;
111 Dest->Length = strlen(str) + 1;
116 memcpy(DataDest, str, Dest->Length);
119 // Data (special handling)
121 len = va_arg(*Args, size_t);
122 str = va_arg(*Args, char*);
124 // Save the pointer for later
125 if( PtrDest ) *PtrDest = str;
127 // Create parameter block
128 Dest->Type = ARG_TYPE_DATA;
129 Dest->Length = str ? len : 0;
132 Dest->Flags |= ARG_FLAG_RETURN;
137 if( DataDest && str )
138 memcpy(DataDest, str, len);
141 Dest->Flags |= ARG_FLAG_ZEROED;
155 * Whitespace is ignored
156 * >i: Input Integer (32-bits)
157 * >I: Input Long Integer (64-bits)
159 * >d: Input Buffer (Preceded by valid size)
160 * <I: Output long integer
161 * <d: Output Buffer (Preceded by valid size)
162 * ?d: Bi-directional buffer (Preceded by valid size), buffer contents
165 uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...)
168 int paramCount, dataLength;
169 int retCount = 2, retLength = sizeof(uint64_t) + sizeof(uint32_t);
170 void **retPtrs; // Pointers to return buffers
177 // printf("&tRequestHeader->Params = %i\n", offsetof(tRequestHeader, Params));
178 // printf("&tRequestValue->Flags = %i\n", offsetof(tRequestValue, Flags));
179 // printf("&tRequestValue->Length = %i\n", offsetof(tRequestValue, Length));
182 va_start(args, ArgTypes);
188 tRequestValue tmpVal;
190 str = ReadEntry(&tmpVal, NULL, NULL, str, &args);
192 fprintf(stderr, "syscalls.c: ReadEntry failed (SyscallID = %i)\n", SyscallID);
196 if( !(tmpVal.Flags & ARG_FLAG_ZEROED) )
197 dataLength += tmpVal.Length;
199 if( tmpVal.Flags & ARG_FLAG_RETURN ) {
200 retLength += tmpVal.Length;
206 dataLength += sizeof(tRequestHeader) + paramCount*sizeof(tRequestValue);
207 retLength += sizeof(tRequestHeader) + retCount*sizeof(tRequestValue);
210 retPtrs = malloc( sizeof(void*) * (retCount+1) );
211 if( dataLength > retLength)
212 req = malloc( dataLength );
214 req = malloc( retLength );
215 req->ClientID = 0; //< Filled later
216 req->CallID = SyscallID;
217 req->NParams = paramCount;
218 req->MessageLength = dataLength;
219 dataPtr = &req->Params[paramCount];
221 // Fill `output` and `input`
222 va_start(args, ArgTypes);
224 // - re-zero so they can be used as indicies
229 str = ReadEntry(&req->Params[paramCount], dataPtr, &retPtrs[retCount], str, &args);
232 if( !(req->Params[paramCount].Flags & ARG_FLAG_ZEROED) )
233 dataPtr += req->Params[paramCount].Length;
234 if( req->Params[paramCount].Flags & ARG_FLAG_RETURN )
241 // --- Send syscall request
242 if( SendRequest(req, dataLength, retLength) < 0 ) {
243 fprintf(stderr, "syscalls.c: SendRequest failed (SyscallID = %i)\n", SyscallID);
247 if( !(req->NParams >= 2) ) {
248 fprintf(stderr, "syscalls.c: Too few return params (%i)", req->NParams);
251 dataPtr = (void*)&req->Params[req->NParams];
253 assert(req->Params[0].Type == ARG_TYPE_INT64);
254 assert(req->Params[0].Length == sizeof(uint64_t));
255 retValue = *(uint64_t*)dataPtr;
256 dataPtr += sizeof(uint64_t);
258 assert(req->Params[1].Type == ARG_TYPE_INT32);
259 assert(req->Params[1].Length == sizeof(uint32_t));
260 acess__errno = *(uint32_t*)dataPtr;
261 dataPtr += sizeof(uint32_t);
263 // Write changes to buffers
264 if( req->NParams - 2 != retCount ) {
265 fprintf(stderr, "syscalls.c: Return count inbalance (%i - 1 != exp %i) [Call %i]\n",
266 req->NParams, retCount, SyscallID);
270 for( unsigned int i = 2; i < req->NParams; i ++ )
274 printf("Return Data %i: (%i)", i, req->Params[i].Length);
275 for( j = 0; j < req->Params[i].Length; j ++ )
276 printf(" %02x", ((uint8_t*)dataPtr)[j]);
279 assert( req->Params[i].Type == ARG_TYPE_DATA );
280 memcpy( retPtrs[retCount++], dataPtr, req->Params[i].Length );
281 dataPtr += req->Params[i].Length;
287 if( gbSyscallDebugEnabled ) {
288 SYSTRACE(": %i 0x%llx", SyscallID, retValue);
294 int native_int_getfd(void)
296 for(int ret = 0; ret < MAX_FPS; ret ++ )
297 if( gaSyscall_LocalFPs[ret] == NULL )
302 int native_open(const char *Path, int Flags)
304 int ret = native_int_getfd();
305 if(ret == -1) return -1;
306 // TODO: Handle directories
307 gaSyscall_LocalFPs[ret] = fopen(Path, "r+");
308 if(!gaSyscall_LocalFPs[ret]) return -1;
312 int native_shm(const char *Tag, int Flags)
314 // int ret = native_int_getfd();
315 //if(ret == -1) return -1;
316 //if( strcmp(Tag, "anon") == 0 )
317 // path = "/AcessNative/anon/RAND";
318 // FD = shm_open(path, O_RDWD);
321 // path = "/Acessnative/named/<TAG>";
322 // int FD = shm_open(path, O_RDWD);
324 //gaSyscall_LocalFPs[ret] =
328 void native_close(int FD)
330 fclose( gaSyscall_LocalFPs[FD] );
331 gaSyscall_LocalFPs[FD] = NULL;
334 size_t native_read(int FD, void *Dest, size_t Bytes)
336 return fread( Dest, Bytes, 1, gaSyscall_LocalFPs[FD] );
339 size_t native_write(int FD, const void *Src, size_t Bytes)
341 return fwrite( Src, Bytes, 1, gaSyscall_LocalFPs[FD] );
344 int native_seek(int FD, int64_t Ofs, int Dir)
347 return fseek( gaSyscall_LocalFPs[FD], Ofs, SEEK_CUR );
349 return fseek( gaSyscall_LocalFPs[FD], Ofs, SEEK_SET );
351 return fseek( gaSyscall_LocalFPs[FD], Ofs, SEEK_END );
354 uint64_t native_tell(int FD)
356 return ftell( gaSyscall_LocalFPs[FD] );
359 int native_execve(const char *filename, const char *const argv[], const char *const envp[])
362 ret = execve(filename, (void*)argv, (void*)envp);
363 perror("native_execve");
367 int native_spawn(const char *filename, const char *const argv[], const char *const envp[])
371 fprintf(stderr, "native_spawn('%s')\n", filename);
374 rv = _spawnve(_P_NOWAIT, filename, argv, envp);
376 rv = posix_spawn(NULL, filename, NULL, NULL, (void*)argv, (void*)envp);
380 perror("native_spawn");
386 int64_t native_timestamp(void)
389 gettimeofday(&tv, NULL);
390 return tv.tv_sec*1000 + tv.tv_usec / 1000;