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
;
360 kePrint("Arg: %x\n", ((uintptr_t*)argdata
)[i
]);
362 for (i
= 0; i
< envcount
; i
++)
364 ((uintptr_t*)argdata
)[argcount
+ 1 + i
] += dataaddr
;
366 mmMapKernelMemory(0, argdata
, 0);
367 for (i
= 0; i
< (stringsize
+ 0xFFF) / 0x1000; i
++)
369 mmMapMemory(&process
->memory
, datapage
+ i
* 0x1000,
370 dataaddr
+ i
* 0x1000, MM_MAP_READ
| MM_MAP_WRITE
);
371 mmMapKernelMemory(0, datavirt
+ i
* 0x1000, 0);
373 keUnlockSpinlock(mmGetMemoryLock());
375 keDestroyThread(thread
);
376 keCreateThread(process
, entry
, 4, envcount
,
377 targetaddr
+ (argcount
+ 1) * sizeof(char*), argcount
, targetaddr
);
378 keSetExecutionLevel(KE_LEVEL_NORMAL
);
379 // Schedule into other thread
380 asm volatile("int $0x32");
382 void sysPipe(KeThread
*thread
, uintptr_t *param1
, uintptr_t *param2
,
383 uintptr_t *param3
, uintptr_t *param4
, uintptr_t *param5
)
385 KeProcess
*process
= thread
->process
;
387 FsFileHandle
*in
= malloc(sizeof(FsFileHandle
));
388 memset(in
, 0, sizeof(FsFileHandle
));
389 FsFileHandle
*out
= malloc(sizeof(FsFileHandle
));
390 memset(out
, 0, sizeof(FsFileHandle
));
391 if (sysOpenPipe(in
, out
))
397 // Save file descriptors
398 keLockSpinlock(&process
->lock
);
399 *param1
= sysCreateFileDescriptor(process
, in
);
400 *param2
= sysCreateFileDescriptor(process
, out
);
401 keUnlockSpinlock(&process
->lock
);
403 void sysSocket(KeThread
*thread
, uintptr_t *param1
, uintptr_t *param2
,
404 uintptr_t *param3
, uintptr_t *param4
, uintptr_t *param5
)
406 KeProcess
*process
= thread
->process
;
408 FsFileHandle
*fh
= malloc(sizeof(FsFileHandle
));
409 memset(fh
, 0, sizeof(FsFileHandle
));
410 keSetExecutionLevel(KE_LEVEL_NORMAL
);
411 int status
= netOpenSocket(fh
, NET_SOCKET_STREAM
);
412 keSetExecutionLevel(KE_LEVEL_HIGH
);
418 // Save file descriptors
419 keLockSpinlock(&process
->lock
);
420 *param1
= sysCreateFileDescriptor(process
, fh
);
421 keUnlockSpinlock(&process
->lock
);
423 void sysIoctl(KeThread
*thread
, uintptr_t *param1
, uintptr_t *param2
,
424 uintptr_t *param3
, uintptr_t *param4
, uintptr_t *param5
)
426 KeProcess
*process
= thread
->process
;
428 if ((*param1
>= process
->fdcount
) || !process
->fd
[*param1
])
430 kePrint("ioctl: invalid fd.\n");
435 keSetExecutionLevel(KE_LEVEL_NORMAL
);
436 int datasize
= fsGetIOCTLSize(process
->fd
[*param1
], *param2
);
437 keSetExecutionLevel(KE_LEVEL_HIGH
);
443 // Map memory to kernel space
447 keLockSpinlock(mmGetMemoryLock());
448 void *buffer
= sysMapUserMemory(thread
, *param3
, datasize
, 0);
449 keUnlockSpinlock(mmGetMemoryLock());
452 kePrint("ioctl: sysMapUserMemory failed (%x: %d).\n", (uint32_t)*param3
, datasize
);
456 data
= (uintptr_t)buffer
;
463 keSetExecutionLevel(KE_LEVEL_NORMAL
);
464 *param1
= fsIOCTL(process
->fd
[*param1
], *param2
, data
);
465 keSetExecutionLevel(KE_LEVEL_HIGH
);
469 keLockSpinlock(mmGetMemoryLock());
470 sysUnmapUserMemory((void*)data
, datasize
);
471 keUnlockSpinlock(mmGetMemoryLock());
474 void sysFcntl(KeThread
*thread
, uintptr_t *param1
, uintptr_t *param2
,
475 uintptr_t *param3
, uintptr_t *param4
, uintptr_t *param5
)
477 KeProcess
*process
= thread
->process
;
478 // Check file descriptor
479 if ((*param1
>= process
->fdcount
) || !process
->fd
[*param1
])
481 kePrint("fcntl: invalid fd.\n");
495 process
->fd
[*param1
]->file
->refcount
++;
496 FsFileHandle
*newfh
= malloc(sizeof(FsFileHandle
));
497 memcpy(newfh
, process
->fd
[*param1
], sizeof(FsFileHandle
));
498 *param1
= sysCreateFileDescriptor(process
, newfh
);
508 process
->fd
[*param1
]->file
->refcount
++;
509 FsFileHandle
*newfh
= malloc(sizeof(FsFileHandle
));
510 memcpy(newfh
, process
->fd
[*param1
], sizeof(FsFileHandle
));
512 while ((newfd
< (int)process
->fdcount
) && process
->fd
[newfd
])
516 if ((int)process
->fdcount
<= newfd
)
518 process
->fd
= realloc(process
->fd
, (newfd
+ 1) * sizeof(FsFileHandle
*));
519 memset(process
->fd
+ process
->fdcount
, 0, (newfd
+ 1 - process
->fdcount
) * sizeof(FsFileHandle
*));
520 process
->fdcount
= newfd
+ 1;
522 process
->fd
[newfd
] = newfh
;
532 void sysSignal(KeThread
*thread
, uintptr_t *param1
, uintptr_t *param2
,
533 uintptr_t *param3
, uintptr_t *param4
, uintptr_t *param5
)
535 int signal
= *param1
;
536 uintptr_t handler
= *param2
;
541 thread
->process
->signal_handlers
[signal
] = handler
;
544 void sysRaise(KeThread
*thread
, uintptr_t *param1
, uintptr_t *param2
,
545 uintptr_t *param3
, uintptr_t *param4
, uintptr_t *param5
)
547 int signal
= *param1
;
553 keSendSignal(thread
->process
, 0, signal
);
556 void sysSyscall(KeThread
*thread
, uintptr_t index
, uintptr_t *param1
,
557 uintptr_t *param2
, uintptr_t *param3
, uintptr_t *param4
, uintptr_t *param5
)
559 if (!thread
->process
)
568 keTerminateProcess(thread
->process
);
569 asm volatile("int $0x32");
572 sysOpen(thread
, param1
, param2
, param3
, param4
, param5
);
576 KeProcess
*process
= thread
->process
;
578 if ((*param1
>= process
->fdcount
) || !process
->fd
[*param1
])
583 kePrint("Closing %d.\n", *param1
);
584 FsFileHandle
*file
= process
->fd
[*param1
];
585 process
->fd
[*param1
] = 0;
587 keSetExecutionLevel(KE_LEVEL_NORMAL
);
589 keSetExecutionLevel(KE_LEVEL_HIGH
);
595 KeProcess
*process
= thread
->process
;
597 if ((*param1
>= process
->fdcount
) || !process
->fd
[*param1
])
599 kePrint("read: invalid fd.\n");
605 keLockSpinlock(mmGetMemoryLock());
606 void *buffer
= sysMapUserMemory(thread
, *param2
, *param3
, 1);
607 keUnlockSpinlock(mmGetMemoryLock());
610 kePrint("read: sysMapUserMemory failed (%x: %d).\n", (uint32_t)*param2
, (int)*param3
);
611 // TODO: Stop program here
616 keSetExecutionLevel(KE_LEVEL_NORMAL
);
617 FsFileHandle
*file
= process
->fd
[*param1
];
618 //kePrint("Reading %d bytes from %d.\n", (int)*param3, (int)*param1);
619 int read
= fsRead(file
, buffer
, *param3
, 1);
620 keSetExecutionLevel(KE_LEVEL_HIGH
);
623 keLockSpinlock(mmGetMemoryLock());
624 sysUnmapUserMemory(buffer
, *param3
);
625 keUnlockSpinlock(mmGetMemoryLock());
632 KeProcess
*process
= thread
->process
;
634 if ((*param1
>= process
->fdcount
) || !process
->fd
[*param1
])
636 kePrint("write: invalid fd.\n");
642 keLockSpinlock(mmGetMemoryLock());
643 void *buffer
= sysMapUserMemory(thread
, *param2
, *param3
, 0);
644 keUnlockSpinlock(mmGetMemoryLock());
647 kePrint("write: sysMapUserMemory failed (%x: %d).\n", (uint32_t)*param2
, (int)*param3
);
648 // TODO: Stop program here
653 keSetExecutionLevel(KE_LEVEL_NORMAL
);
654 FsFileHandle
*file
= process
->fd
[*param1
];
655 int written
= fsWrite(file
, buffer
, *param3
);
656 keSetExecutionLevel(KE_LEVEL_HIGH
);
659 keLockSpinlock(mmGetMemoryLock());
660 sysUnmapUserMemory(buffer
, *param3
);
661 keUnlockSpinlock(mmGetMemoryLock());
668 KeProcess
*process
= thread
->process
;
670 if ((*param1
>= process
->fdcount
) || !process
->fd
[*param1
])
672 kePrint("seek: invalid fd.\n");
677 keSetExecutionLevel(KE_LEVEL_NORMAL
);
678 FsFileHandle
*file
= process
->fd
[*param1
];
679 *param1
= fsSeek(file
, *param2
, *param3
);
680 keSetExecutionLevel(KE_LEVEL_HIGH
);
685 // TODO: Can be crashed easily
686 char *filename
= strdup((char*)*param1
);
688 uint32_t type
= *param2
& 0xF00;
690 mode
= FS_MKNOD_FILE
;
691 else if (type
== 0x500)
693 keSetExecutionLevel(KE_LEVEL_NORMAL
);
694 *param1
= fsMknod(filename
, mode
);
695 keSetExecutionLevel(KE_LEVEL_HIGH
);
700 KeProcess
*process
= thread
->process
;
701 uint32_t size
= *param1
;
702 uint32_t pagecount
= (size
+ 0xFFF) / 0x1000;
703 keLockSpinlock(mmGetMemoryLock());
704 // Look for free memory
705 uintptr_t vaddr
= mmFindFreePages(&process
->memory
, MM_MAX_USER_PAGE
,
706 MM_MIN_USER_PAGE
, 0, pagecount
* 0x1000);
711 for (i
= 0; i
< pagecount
; i
++)
713 uintptr_t paddr
= mmAllocPhysicalMemory(0, 0, 0x1000);
714 // TODO: Error handling
715 mmMapMemory(&process
->memory
, paddr
, vaddr
+ i
* 0x1000,
716 MM_MAP_READ
| MM_MAP_WRITE
);
719 keUnlockSpinlock(mmGetMemoryLock());
725 KeProcess
*process
= thread
->process
;
726 uint32_t addr
= *param1
;
727 uint32_t size
= *param2
;
728 uint32_t pagecount
= (size
+ 0xFFF) / 0x1000;
730 for (i
= 0; i
< pagecount
; i
++)
732 uintptr_t vaddr
= (addr
& ~0xFFF) + i
* 0x1000;
734 uintptr_t paddr
= mmGetPhysAddress(&process
->memory
, vaddr
);
735 if (paddr
) mmFreePhysicalMemory(paddr
, 0x1000);
737 mmMapMemory(&process
->memory
, 0, vaddr
, 0);
742 sysFork(thread
, param1
, param2
, param3
, param4
, param5
);
745 sysExec(thread
, param1
, param2
, param3
, param4
, param5
);
751 uint32_t options
= *param3
;
752 keSetExecutionLevel(KE_LEVEL_NORMAL
);
753 KeProcess
*process
= keGetProcess(pid
);
754 keSetExecutionLevel(KE_LEVEL_HIGH
);
760 // If the process was terminated, return at once
763 keSetExecutionLevel(KE_LEVEL_NORMAL
);
764 keDestroyProcess(process
);
765 keSetExecutionLevel(KE_LEVEL_HIGH
);
777 if (process
->waitthread
)
782 process
->waitthread
= thread
;
783 thread
->status
= KE_THREAD_WAIT
;
784 asm volatile("int $0x32");
789 thread
->status
= KE_THREAD_SLEEP
;
790 thread
->timeout
= keGetTime() + *param1
;
791 asm volatile("int $0x32");
795 KeProcess
*process
= thread
->process
;
796 int length
= strlen(process
->cwd
) + 1;
797 if (length
> (int)*param2
)
802 keLockSpinlock(mmGetMemoryLock());
803 char *buffer
= sysMapUserMemory(thread
, *param1
, length
+ 1, 0);
804 keUnlockSpinlock(mmGetMemoryLock());
811 strncpy(buffer
, process
->cwd
, length
);
814 keLockSpinlock(mmGetMemoryLock());
815 sysUnmapUserMemory(buffer
, length
+ 1);
816 keUnlockSpinlock(mmGetMemoryLock());
823 // FIXME: Can be crashed by users
824 char *filename
= strdup((char*)*param1
);
825 KeProcess
*process
= thread
->process
;
827 keSetExecutionLevel(KE_LEVEL_NORMAL
);
828 if (strlen(filename
) == 0)
831 keSetExecutionLevel(KE_LEVEL_HIGH
);
834 if (filename
[0] != '/')
837 char *tmp
= malloc(strlen(filename
) + strlen(process
->cwd
) + 2);
838 strcpy(tmp
, process
->cwd
);
839 strcpy(tmp
+ strlen(process
->cwd
), filename
);
842 if (filename
[strlen(filename
) - 1] != '/')
844 filename
[strlen(filename
) + 1] = 0;
845 filename
[strlen(filename
)] = '/';
848 FsFileHandle
*file
= fsOpen(filename
, FS_OPEN_READ
);
852 keSetExecutionLevel(KE_LEVEL_HIGH
);
856 keSetExecutionLevel(KE_LEVEL_HIGH
);
857 // Set working directory
859 process
->cwd
= filename
;
864 sysPipe(thread
, param1
, param2
, param3
, param4
, param5
);
867 sysSocket(thread
, param1
, param2
, param3
, param4
, param5
);
870 sysIoctl(thread
, param1
, param2
, param3
, param4
, param5
);
873 sysFcntl(thread
, param1
, param2
, param3
, param4
, param5
);
876 sysSignal(thread
, param1
, param2
, param3
, param4
, param5
);
879 sysRaise(thread
, param1
, param2
, param3
, param4
, param5
);
882 *param1
= thread
->process
->pid
;
886 uint64_t time
= keGetTime();
887 uint32_t seconds
= keGetCurrentCPU()->starttime
+ time
/ 1000000;
889 *param2
= time
% 1000000;