2 Copyright (C) 2008 Mathias Gottschlag
4 Permission is hereby granted, free of charge, to any person obtaining a copy of
5 this software and associated documentation files (the "Software"), to deal in the
6 Software without restriction, including without limitation the rights to use,
7 copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
8 Software, and to permit persons to whom the Software is furnished to do so,
9 subject to the following conditions:
11 The above copyright notice and this permission notice shall be included in all
12 copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
15 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
16 PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
17 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
18 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
19 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 #include "sys/syscall.h"
29 #include "net/socket.h"
33 void *sysMapUserMemory(KeThread
*thread
, uintptr_t addr
, uint32_t size
, uint32_t writeable
)
35 KeProcess
*process
= thread
->process
;
36 uint32_t pageoffset
= addr
& 0xFFF;
37 uint32_t pagecount
= (size
+ pageoffset
+ 0xFFF) / 0x1000;
40 for (i
= 0; i
< pagecount
; i
++)
43 if (!mmGetPhysAddress(&process
->memory
, (addr
& ~0xFFF) + i
* 0x1000))
45 kePrint("No memory at %x\n", (addr
& ~0xFFF) + i
* 0x1000);
50 uintptr_t vaddr
= mmFindFreeKernelPages(MM_MAX_KERNEL_PAGE
, MM_MIN_KERNEL_PAGE
,
51 1, pagecount
* 0x1000);
54 kePrint("Could not allocate %d bytes.\n", pagecount
* 0x1000);
57 for (i
= 0; i
< pagecount
; i
++)
59 uintptr_t paddr
= mmGetPhysAddress(&process
->memory
, (addr
& ~0xFFF) + i
* 0x1000);
60 mmMapKernelMemory(paddr
, vaddr
+ i
* 0x1000,
61 MM_MAP_READ
| MM_MAP_WRITE
);
63 return (void*)(vaddr
+ pageoffset
);
66 void sysUnmapUserMemory(void *data
, uint32_t size
)
68 uintptr_t addr
= (uintptr_t)data
;
69 uint32_t pageoffset
= addr
& 0xFFF;
70 uint32_t pagecount
= (size
+ pageoffset
+ 0xFFF) / 0x1000;
72 for (i
= 0; i
< pagecount
; i
++)
74 mmMapKernelMemory(0, addr
+ i
* 0x1000, 0);
78 int sysCreateFileDescriptor(KeProcess
*process
, FsFileHandle
*fh
)
80 // Search for empty fds
83 for (i
= 3; i
< process
->fdcount
; i
++)
85 if (process
->fd
[i
] == 0)
93 process
->fd
= realloc(process
->fd
, (process
->fdcount
+ 1) * sizeof(FsFileHandle
*));
94 fd
= process
->fdcount
;
101 void sysOpen(KeThread
*thread
, uintptr_t *param1
, uintptr_t *param2
,
102 uintptr_t *param3
, uintptr_t *param4
, uintptr_t *param5
)
104 KeProcess
*process
= thread
->process
;
105 keSetExecutionLevel(KE_LEVEL_NORMAL
);
106 // TODO: Can be crashed easily
107 char *filename
= strdup((char*)*param1
);
108 if (strlen(filename
) == 0)
111 keSetExecutionLevel(KE_LEVEL_HIGH
);
114 if (filename
[0] != '/')
117 char *tmp
= malloc(strlen(filename
) + 1 + strlen(process
->cwd
));
118 strcpy(tmp
, process
->cwd
);
119 strcpy(tmp
+ strlen(process
->cwd
), filename
);
123 kePrint("Opening %s\n", filename
);
125 if (*param2
& 1) mode
|= FS_OPEN_CREATE
;
126 if (*param2
& 0x200) mode
|= FS_OPEN_READ
;
127 if (*param2
& 0x400) mode
|= FS_OPEN_RW
;
128 if (*param2
& 0x800) mode
|= FS_OPEN_WRITE
;
129 FsFileHandle
*file
= fsOpen(filename
, mode
);
133 keSetExecutionLevel(KE_LEVEL_HIGH
);
137 keSetExecutionLevel(KE_LEVEL_HIGH
);
138 keLockSpinlock(&process
->lock
);
141 for (i
= 3; i
< process
->fdcount
; i
++)
143 if (process
->fd
[i
] == 0)
150 process
->fd
= realloc(process
->fd
, (process
->fdcount
+ 1) * sizeof(FsFileHandle
*));
151 fd
= process
->fdcount
;
154 process
->fd
[fd
] = file
;
156 keUnlockSpinlock(&process
->lock
);
157 kePrint("Opened %s as %d\n", filename
, fd
);
162 void sysFork(KeThread
*thread
, uintptr_t *param1
, uintptr_t *param2
,
163 uintptr_t *param3
, uintptr_t *param4
, uintptr_t *param5
)
165 uintptr_t current_stack
= thread
->kernelstack
;
166 KeProcess
*process
= thread
->process
;
167 keSetExecutionLevel(KE_LEVEL_NORMAL
);
168 // Create new process
169 KeProcess
*newprocess
= keCreateProcess();
170 keSetExecutionLevel(KE_LEVEL_HIGH
);
171 keLockSpinlock(mmGetMemoryLock());
172 if (mmCloneAddressSpace(&newprocess
->memory
, &process
->memory
))
174 keUnlockSpinlock(mmGetMemoryLock());
175 keSetExecutionLevel(KE_LEVEL_NORMAL
);
176 keDestroyProcess(newprocess
);
177 keSetExecutionLevel(KE_LEVEL_HIGH
);
182 keUnlockSpinlock(mmGetMemoryLock());
183 // Clone file handles
184 keLockSpinlock(&newprocess
->lock
);
185 newprocess
->fd
= realloc(newprocess
->fd
, process
->fdcount
* sizeof(FsFileHandle
*));
186 newprocess
->fdcount
= process
->fdcount
;
187 memcpy(newprocess
->fd
, process
->fd
, process
->fdcount
* sizeof(FsFileHandle
*));
189 for (i
= 0; i
< process
->fdcount
; i
++)
193 process
->fd
[i
]->file
->refcount
++;
194 newprocess
->fd
[i
] = malloc(sizeof(FsFileHandle
));
195 memcpy(newprocess
->fd
[i
], process
->fd
[i
], sizeof(FsFileHandle
));
199 free(newprocess
->cwd
);
200 newprocess
->cwd
= strdup(process
->cwd
);
201 keUnlockSpinlock(&newprocess
->lock
);
203 KeThread
*newthread
= keCloneThread(newprocess
, thread
, current_stack
);
204 keThreadSetParam(newthread
, 1, 0);
206 *param1
= newprocess
->pid
;
209 void sysExec(KeThread
*thread
, uintptr_t *param1
, uintptr_t *param2
,
210 uintptr_t *param3
, uintptr_t *param4
, uintptr_t *param5
)
212 KeProcess
*process
= thread
->process
;
213 keSetExecutionLevel(KE_LEVEL_NORMAL
);
214 // Load executable file
215 // FIXME: Can be crashed by users
216 char *filename
= strdup((char*)*param1
);
217 FsFileHandle
*file
= fsOpen(filename
, FS_OPEN_READ
);
220 kePrint("exec: Could not open \"%s\".\n", filename
);
222 keSetExecutionLevel(KE_LEVEL_HIGH
);
227 int size
= fsSeek(file
, 0, 2);
229 keSetExecutionLevel(KE_LEVEL_HIGH
);
230 char *program
= malloc(size
);
231 keSetExecutionLevel(KE_LEVEL_NORMAL
);
234 kePrint("exec: Out of memory.\n");
237 keSetExecutionLevel(KE_LEVEL_HIGH
);
241 if (fsRead(file
, program
, size
+ 10, 1) != size
)
243 kePrint("exec: Could not read \"%s\".\n", filename
);
246 keSetExecutionLevel(KE_LEVEL_HIGH
);
250 uintptr_t entry
= ((ElfHeader
*)program
)->e_entry
;
253 if ((program
[0] != 0x7F) || (program
[1] != 'E')
254 || (program
[2] != 'L') || (program
[3] != 'F'))
256 kePrint("Not a valid ELF file: %x%x\n", *((uint32_t*)program
+ 1), *((uint32_t*)program
));
257 keSetExecutionLevel(KE_LEVEL_HIGH
);
262 // Map arguments/environment variables
263 keSetExecutionLevel(KE_LEVEL_HIGH
);
264 keLockSpinlock(mmGetMemoryLock());
265 uint32_t argcount
= *param2
;
269 args
= sysMapUserMemory(thread
, *param3
, argcount
* sizeof(char*), 0);
272 keUnlockSpinlock(mmGetMemoryLock());
278 uint32_t envcount
= *param4
;
282 env
= sysMapUserMemory(thread
, *param5
, envcount
* sizeof(char*), 0);
286 sysUnmapUserMemory(args
, argcount
* sizeof(char*));
287 keUnlockSpinlock(mmGetMemoryLock());
293 // Copy data to kernel space
294 uint32_t pagecount
= ((argcount
+ envcount
+ 2) * sizeof(char*) + 4095) / 0x1000;
297 keSetExecutionLevel(KE_LEVEL_HIGH
);
302 uintptr_t page
= mmAllocPhysicalMemory(0, 0, 0x1000);
303 uintptr_t argdata
= mmFindFreeKernelPages(MM_MAX_KERNEL_PAGE
,
304 MM_MIN_KERNEL_PAGE
, 1, 0x1000);
305 mmMapKernelMemory(page
, argdata
, MM_MAP_READ
| MM_MAP_WRITE
);
306 uint32_t stringsize
= 0;
308 for (i
= 0; i
< argcount
; i
++)
310 stringsize
+= strlen((char*)args
[i
]) + 1;
312 for (i
= 0; i
< envcount
; i
++)
314 stringsize
+= strlen((char*)env
[i
]) + 1;
316 memset((void*)argdata
, 0xab, 0x1000);
317 ((uintptr_t*)argdata
)[argcount
] = 0;
318 ((uintptr_t*)argdata
)[argcount
+ 1 + envcount
] = 0;
319 uintptr_t datapage
= mmAllocPhysicalMemory(0, 0, (stringsize
+ 0xFFF) & ~0xFFF);
320 uintptr_t datavirt
= mmFindFreeKernelPages(MM_MAX_KERNEL_PAGE
,
321 MM_MIN_KERNEL_PAGE
, 1, (stringsize
+ 0xFFF) & ~0xFFF);
322 for (i
= 0; i
< (stringsize
+ 0xFFF) / 0x1000; i
++)
324 mmMapKernelMemory(datapage
+ i
* 0x1000, datavirt
+ i
* 0x1000,
325 MM_MAP_READ
| MM_MAP_WRITE
);
327 char *s
= (char*)datavirt
;
328 for (i
= 0; i
< argcount
; i
++)
330 ((uintptr_t*)argdata
)[i
] = (uintptr_t)s
- datavirt
;
331 strcpy(s
, (char*)args
[i
]);
332 s
+= strlen((char*)args
[i
]) + 1;
334 for (i
= 0; i
< envcount
; i
++)
336 ((uintptr_t*)argdata
)[argcount
+ 1 + i
] = (uintptr_t)s
- datavirt
;
337 strcpy(s
, (char*)env
[i
]);
338 s
+= strlen((char*)env
[i
]) + 1;
340 // Unmap arguments again
342 sysUnmapUserMemory(args
, argcount
* sizeof(char*));
344 sysUnmapUserMemory(args
, argcount
* sizeof(char*));
345 keUnlockSpinlock(mmGetMemoryLock());
346 keSetExecutionLevel(KE_LEVEL_NORMAL
);
348 keClearProcess(process
, thread
);
349 keSetExecutionLevel(KE_LEVEL_HIGH
);
350 keLockSpinlock(mmGetMemoryLock());
351 keElfMapProgram(&process
->memory
, program
, size
);
352 uintptr_t targetaddr
= mmFindFreePages(&process
->memory
, MM_MAX_USER_PAGE
,
353 MM_MIN_USER_PAGE
, 0, 0x1000);
354 mmMapMemory(&process
->memory
, page
, targetaddr
, MM_MAP_READ
| MM_MAP_WRITE
);
355 uintptr_t dataaddr
= mmFindFreePages(&process
->memory
, MM_MAX_USER_PAGE
,
356 MM_MIN_USER_PAGE
, 0, (stringsize
+ 0xFFF) & ~0xFFF);
357 for (i
= 0; i
< argcount
; i
++)
359 ((uintptr_t*)argdata
)[i
] += dataaddr
;
361 for (i
= 0; i
< envcount
; i
++)
363 ((uintptr_t*)argdata
)[argcount
+ 1 + i
] += dataaddr
;
365 mmMapKernelMemory(0, argdata
, 0);
366 for (i
= 0; i
< (stringsize
+ 0xFFF) / 0x1000; i
++)
368 mmMapMemory(&process
->memory
, datapage
+ i
* 0x1000,
369 dataaddr
+ i
* 0x1000, MM_MAP_READ
| MM_MAP_WRITE
);
370 mmMapKernelMemory(0, datavirt
+ i
* 0x1000, 0);
372 keUnlockSpinlock(mmGetMemoryLock());
374 keDestroyThread(thread
);
375 keCreateThread(process
, entry
, 4, envcount
,
376 targetaddr
+ (argcount
+ 1) * sizeof(char*), argcount
, targetaddr
);
377 keSetExecutionLevel(KE_LEVEL_NORMAL
);
378 // Schedule into other thread
379 asm volatile("int $0x32");
381 void sysPipe(KeThread
*thread
, uintptr_t *param1
, uintptr_t *param2
,
382 uintptr_t *param3
, uintptr_t *param4
, uintptr_t *param5
)
384 KeProcess
*process
= thread
->process
;
386 FsFileHandle
*in
= malloc(sizeof(FsFileHandle
));
387 memset(in
, 0, sizeof(FsFileHandle
));
388 FsFileHandle
*out
= malloc(sizeof(FsFileHandle
));
389 memset(out
, 0, sizeof(FsFileHandle
));
390 if (sysOpenPipe(in
, out
))
396 // Save file descriptors
397 keLockSpinlock(&process
->lock
);
398 *param1
= sysCreateFileDescriptor(process
, in
);
399 *param2
= sysCreateFileDescriptor(process
, out
);
400 keUnlockSpinlock(&process
->lock
);
402 void sysSocket(KeThread
*thread
, uintptr_t *param1
, uintptr_t *param2
,
403 uintptr_t *param3
, uintptr_t *param4
, uintptr_t *param5
)
405 KeProcess
*process
= thread
->process
;
407 FsFileHandle
*fh
= malloc(sizeof(FsFileHandle
));
408 memset(fh
, 0, sizeof(FsFileHandle
));
409 keSetExecutionLevel(KE_LEVEL_NORMAL
);
410 int status
= netOpenSocket(fh
, NET_SOCKET_STREAM
);
411 keSetExecutionLevel(KE_LEVEL_HIGH
);
417 // Save file descriptors
418 keLockSpinlock(&process
->lock
);
419 *param1
= sysCreateFileDescriptor(process
, fh
);
420 keUnlockSpinlock(&process
->lock
);
422 void sysIoctl(KeThread
*thread
, uintptr_t *param1
, uintptr_t *param2
,
423 uintptr_t *param3
, uintptr_t *param4
, uintptr_t *param5
)
425 KeProcess
*process
= thread
->process
;
427 if ((*param1
>= process
->fdcount
) || !process
->fd
[*param1
])
429 kePrint("ioctl: invalid fd.\n");
434 keSetExecutionLevel(KE_LEVEL_NORMAL
);
435 int datasize
= fsGetIOCTLSize(process
->fd
[*param1
], *param2
);
436 keSetExecutionLevel(KE_LEVEL_HIGH
);
442 // Map memory to kernel space
446 keLockSpinlock(mmGetMemoryLock());
447 void *buffer
= sysMapUserMemory(thread
, *param3
, datasize
, 0);
448 keUnlockSpinlock(mmGetMemoryLock());
451 kePrint("ioctl: sysMapUserMemory failed (%x: %d).\n", (uint32_t)*param3
, datasize
);
455 data
= (uintptr_t)buffer
;
462 keSetExecutionLevel(KE_LEVEL_NORMAL
);
463 *param1
= fsIOCTL(process
->fd
[*param1
], *param2
, data
);
464 keSetExecutionLevel(KE_LEVEL_HIGH
);
468 keLockSpinlock(mmGetMemoryLock());
469 sysUnmapUserMemory((void*)data
, datasize
);
470 keUnlockSpinlock(mmGetMemoryLock());
473 void sysFcntl(KeThread
*thread
, uintptr_t *param1
, uintptr_t *param2
,
474 uintptr_t *param3
, uintptr_t *param4
, uintptr_t *param5
)
476 KeProcess
*process
= thread
->process
;
477 // Check file descriptor
478 if ((*param1
>= process
->fdcount
) || !process
->fd
[*param1
])
480 kePrint("fcntl: invalid fd.\n");
494 process
->fd
[*param1
]->file
->refcount
++;
495 FsFileHandle
*newfh
= malloc(sizeof(FsFileHandle
));
496 memcpy(newfh
, process
->fd
[*param1
], sizeof(FsFileHandle
));
497 *param1
= sysCreateFileDescriptor(process
, newfh
);
507 process
->fd
[*param1
]->file
->refcount
++;
508 FsFileHandle
*newfh
= malloc(sizeof(FsFileHandle
));
509 memcpy(newfh
, process
->fd
[*param1
], sizeof(FsFileHandle
));
511 while ((newfd
< (int)process
->fdcount
) && process
->fd
[newfd
])
515 if ((int)process
->fdcount
<= newfd
)
517 process
->fd
= realloc(process
->fd
, (newfd
+ 1) * sizeof(FsFileHandle
*));
518 memset(process
->fd
+ process
->fdcount
, 0, (newfd
+ 1 - process
->fdcount
) * sizeof(FsFileHandle
*));
519 process
->fdcount
= newfd
+ 1;
521 process
->fd
[newfd
] = newfh
;
531 void sysSignal(KeThread
*thread
, uintptr_t *param1
, uintptr_t *param2
,
532 uintptr_t *param3
, uintptr_t *param4
, uintptr_t *param5
)
534 int signal
= *param1
;
535 uintptr_t handler
= *param2
;
540 thread
->process
->signal_handlers
[signal
] = handler
;
543 void sysRaise(KeThread
*thread
, uintptr_t *param1
, uintptr_t *param2
,
544 uintptr_t *param3
, uintptr_t *param4
, uintptr_t *param5
)
546 int signal
= *param1
;
553 keSendSignal(thread
->process
, 0, signal
);
555 void sysKill(KeThread
*thread
, uintptr_t *param1
, uintptr_t *param2
,
556 uintptr_t *param3
, uintptr_t *param4
, uintptr_t *param5
)
559 int signal
= *param2
;
565 KeProcess
*target
= keGetProcess(pid
);
572 keSendSignal(target
, 0, signal
);
575 void sysSyscall(KeThread
*thread
, uintptr_t index
, uintptr_t *param1
,
576 uintptr_t *param2
, uintptr_t *param3
, uintptr_t *param4
, uintptr_t *param5
)
578 if (!thread
->process
)
587 keTerminateProcess(thread
->process
);
588 asm volatile("int $0x32");
591 sysOpen(thread
, param1
, param2
, param3
, param4
, param5
);
595 KeProcess
*process
= thread
->process
;
597 if ((*param1
>= process
->fdcount
) || !process
->fd
[*param1
])
602 kePrint("Closing %d.\n", *param1
);
603 FsFileHandle
*file
= process
->fd
[*param1
];
604 process
->fd
[*param1
] = 0;
606 keSetExecutionLevel(KE_LEVEL_NORMAL
);
608 keSetExecutionLevel(KE_LEVEL_HIGH
);
614 KeProcess
*process
= thread
->process
;
616 if ((*param1
>= process
->fdcount
) || !process
->fd
[*param1
])
618 kePrint("read: invalid fd.\n");
624 keLockSpinlock(mmGetMemoryLock());
625 void *buffer
= sysMapUserMemory(thread
, *param2
, *param3
, 1);
626 keUnlockSpinlock(mmGetMemoryLock());
629 kePrint("read: sysMapUserMemory failed (%x: %d).\n", (uint32_t)*param2
, (int)*param3
);
630 // TODO: Stop program here
635 keSetExecutionLevel(KE_LEVEL_NORMAL
);
636 FsFileHandle
*file
= process
->fd
[*param1
];
637 //kePrint("Reading %d bytes from %d.\n", (int)*param3, (int)*param1);
638 int read
= fsRead(file
, buffer
, *param3
, 1);
639 keSetExecutionLevel(KE_LEVEL_HIGH
);
642 keLockSpinlock(mmGetMemoryLock());
643 sysUnmapUserMemory(buffer
, *param3
);
644 keUnlockSpinlock(mmGetMemoryLock());
651 KeProcess
*process
= thread
->process
;
653 if ((*param1
>= process
->fdcount
) || !process
->fd
[*param1
])
655 kePrint("write: invalid fd.\n");
661 keLockSpinlock(mmGetMemoryLock());
662 void *buffer
= sysMapUserMemory(thread
, *param2
, *param3
, 0);
663 keUnlockSpinlock(mmGetMemoryLock());
666 kePrint("write: sysMapUserMemory failed (%x: %d).\n", (uint32_t)*param2
, (int)*param3
);
667 // TODO: Stop program here
672 keSetExecutionLevel(KE_LEVEL_NORMAL
);
673 FsFileHandle
*file
= process
->fd
[*param1
];
674 int written
= fsWrite(file
, buffer
, *param3
);
675 keSetExecutionLevel(KE_LEVEL_HIGH
);
678 keLockSpinlock(mmGetMemoryLock());
679 sysUnmapUserMemory(buffer
, *param3
);
680 keUnlockSpinlock(mmGetMemoryLock());
687 KeProcess
*process
= thread
->process
;
689 if ((*param1
>= process
->fdcount
) || !process
->fd
[*param1
])
691 kePrint("seek: invalid fd.\n");
696 keSetExecutionLevel(KE_LEVEL_NORMAL
);
697 FsFileHandle
*file
= process
->fd
[*param1
];
698 *param1
= fsSeek(file
, *param2
, *param3
);
699 keSetExecutionLevel(KE_LEVEL_HIGH
);
704 // TODO: Can be crashed easily
705 char *filename
= strdup((char*)*param1
);
707 uint32_t type
= *param2
& 0xF00;
709 mode
= FS_MKNOD_FILE
;
710 else if (type
== 0x500)
712 keSetExecutionLevel(KE_LEVEL_NORMAL
);
713 *param1
= fsMknod(filename
, mode
);
714 keSetExecutionLevel(KE_LEVEL_HIGH
);
719 KeProcess
*process
= thread
->process
;
720 uint32_t size
= *param1
;
721 uint32_t pagecount
= (size
+ 0xFFF) / 0x1000;
722 keLockSpinlock(mmGetMemoryLock());
723 // Look for free memory
724 uintptr_t vaddr
= mmFindFreePages(&process
->memory
, MM_MAX_USER_PAGE
,
725 MM_MIN_USER_PAGE
, 0, pagecount
* 0x1000);
730 for (i
= 0; i
< pagecount
; i
++)
732 uintptr_t paddr
= mmAllocPhysicalMemory(0, 0, 0x1000);
733 // TODO: Error handling
734 mmMapMemory(&process
->memory
, paddr
, vaddr
+ i
* 0x1000,
735 MM_MAP_READ
| MM_MAP_WRITE
);
738 keUnlockSpinlock(mmGetMemoryLock());
744 KeProcess
*process
= thread
->process
;
745 uint32_t addr
= *param1
;
746 uint32_t size
= *param2
;
747 uint32_t pagecount
= (size
+ 0xFFF) / 0x1000;
749 for (i
= 0; i
< pagecount
; i
++)
751 uintptr_t vaddr
= (addr
& ~0xFFF) + i
* 0x1000;
753 uintptr_t paddr
= mmGetPhysAddress(&process
->memory
, vaddr
);
754 if (paddr
) mmFreePhysicalMemory(paddr
, 0x1000);
756 mmMapMemory(&process
->memory
, 0, vaddr
, 0);
761 sysFork(thread
, param1
, param2
, param3
, param4
, param5
);
764 sysExec(thread
, param1
, param2
, param3
, param4
, param5
);
770 uint32_t options
= *param3
;
771 keSetExecutionLevel(KE_LEVEL_NORMAL
);
772 KeProcess
*process
= keGetProcess(pid
);
773 keSetExecutionLevel(KE_LEVEL_HIGH
);
779 // If the process was terminated, return at once
782 keSetExecutionLevel(KE_LEVEL_NORMAL
);
783 keDestroyProcess(process
);
784 keSetExecutionLevel(KE_LEVEL_HIGH
);
796 if (process
->waitthread
)
801 process
->waitthread
= thread
;
802 thread
->status
= KE_THREAD_WAIT
;
803 asm volatile("int $0x32");
808 thread
->status
= KE_THREAD_SLEEP
;
809 thread
->timeout
= keGetTime() + *param1
;
810 asm volatile("int $0x32");
814 KeProcess
*process
= thread
->process
;
815 int length
= strlen(process
->cwd
) + 1;
816 if (length
> (int)*param2
)
821 keLockSpinlock(mmGetMemoryLock());
822 char *buffer
= sysMapUserMemory(thread
, *param1
, length
+ 1, 0);
823 keUnlockSpinlock(mmGetMemoryLock());
830 strncpy(buffer
, process
->cwd
, length
);
833 keLockSpinlock(mmGetMemoryLock());
834 sysUnmapUserMemory(buffer
, length
+ 1);
835 keUnlockSpinlock(mmGetMemoryLock());
842 // FIXME: Can be crashed by users
843 char *filename
= strdup((char*)*param1
);
844 KeProcess
*process
= thread
->process
;
846 keSetExecutionLevel(KE_LEVEL_NORMAL
);
847 if (strlen(filename
) == 0)
850 keSetExecutionLevel(KE_LEVEL_HIGH
);
853 if (filename
[0] != '/')
856 char *tmp
= malloc(strlen(filename
) + strlen(process
->cwd
) + 2);
857 strcpy(tmp
, process
->cwd
);
858 strcpy(tmp
+ strlen(process
->cwd
), filename
);
861 if (filename
[strlen(filename
) - 1] != '/')
863 filename
[strlen(filename
) + 1] = 0;
864 filename
[strlen(filename
)] = '/';
867 FsFileHandle
*file
= fsOpen(filename
, FS_OPEN_READ
);
871 keSetExecutionLevel(KE_LEVEL_HIGH
);
875 keSetExecutionLevel(KE_LEVEL_HIGH
);
876 // Set working directory
878 process
->cwd
= filename
;
883 sysPipe(thread
, param1
, param2
, param3
, param4
, param5
);
886 sysSocket(thread
, param1
, param2
, param3
, param4
, param5
);
889 sysIoctl(thread
, param1
, param2
, param3
, param4
, param5
);
892 sysFcntl(thread
, param1
, param2
, param3
, param4
, param5
);
895 sysSignal(thread
, param1
, param2
, param3
, param4
, param5
);
898 sysRaise(thread
, param1
, param2
, param3
, param4
, param5
);
901 sysKill(thread
, param1
, param2
, param3
, param4
, param5
);
904 *param1
= thread
->process
->pid
;
908 uint64_t time
= keGetTime();
909 uint32_t seconds
= keGetCurrentCPU()->starttime
+ time
/ 1000000;
911 *param2
= time
% 1000000;