Diff markup
001 001
002 002
003 003
004 004
005 005
006 006
007 007
008 008
009 009
010 010
011 011
012 012
013 013
014 014
015 015
016 016
017 017
018 #include <sos/assert.h> <<
019 #include <sos/thread.h> 018 #include <sos/thread.h>
020 #include <sos/kmalloc.h> 019 #include <sos/kmalloc.h>
021 #include <sos/klibc.h> 020 #include <sos/klibc.h>
022 #include <drivers/bochs.h> 021 #include <drivers/bochs.h>
023 #include <hwcore/paging.h> <<
024 #include <sos/physmem.h> <<
025 #include <sos/umem_vmm.h> <<
026 #include <drivers/zero.h> <<
027 #include <drivers/mem.h> <<
028 #include <sos/binfmt_elf32.h> <<
029 022
030 #include <hwcore/cpu_context.h> 023 #include <hwcore/cpu_context.h>
031 #include <sos/uaccess.h> 024 #include <sos/uaccess.h>
032 #include "syscall.h" 025 #include "syscall.h"
033 026
034 027
035 !! 028
036 !! 029
037 #define SYSCALL_VAR32_PTR(ui32_variable) \ !! 030
038 ((void*)&(ui32_variable)) !! 031 sos_ret_t sos_do_syscall(int syscall_id,
039 !! 032 const struct sos_cpu_state *user_ctxt)
040 !! 033 {
041 !! 034 sos_ret_t retval;
042 <<
043 <<
044 sos_ret_t sos_do_syscall(int syscall_id, <<
045 const struct sos_cpu_ <<
046 { <<
047 sos_ret_t retval; <<
048 <<
049 switch(syscall_id) <<
050 { <<
051 case SOS_SYSCALL_ID_EXIT: <<
052 { <<
053 unsigned int status; <<
054 <<
055 retval = sos_syscall_get1arg(user_ctxt <<
056 if (SOS_OK != retval) <<
057 break; <<
058 sos_thread_exit(); <<
059 retval = -SOS_EFATAL; <<
060 } <<
061 break; <<
062 <<
063 case SOS_SYSCALL_ID_FORK: <<
064 { <<
065 struct sos_thread *cur_thr, *new_thr; <<
066 struct sos_process *new_proc; <<
067 <<
068 cur_thr = sos_thread_get_current(); <<
069 <<
070 <<
071 new_proc = sos_process_create(NULL, TR <<
072 if (! new_proc) <<
073 { <<
074 retval = -SOS_ENOMEM; <<
075 break; <<
076 } <<
077 <<
078 <<
079 <<
080 <<
081 new_thr = <<
082 sos_duplicate_user_thread(NULL, new_ <<
083 cur_thr, <<
084 user_ctxt, <<
085 0); <<
086 if (! new_thr) <<
087 { <<
088 sos_process_unref(new_proc); <<
089 retval = -SOS_ENOMEM; <<
090 break; <<
091 } <<
092 <<
093 sos_process_unref(new_proc); <<
094 <<
095 <<
096 <<
097 <<
098 retval = (sos_ui32_t)new_proc; <<
099 } <<
100 break; <<
101 <<
102 case SOS_SYSCALL_ID_EXEC: <<
103 { <<
104 struct sos_thread *cur_thr, *new_thr; <<
105 struct sos_process * proc; <<
106 struct sos_umem_vmm_as *new_as; <<
107 sos_uaddr_t user_str, ustack, start_ua <<
108 sos_size_t len; <<
109 char * str; <<
110 <<
111 cur_thr = sos_thread_get_current(); <<
112 proc = cur_thr->process; <<
113 <<
114 <<
115 if (sos_process_get_nb_threads(proc) ! <<
116 { <<
117 retval = -SOS_EBUSY; <<
118 break; <<
119 } <<
120 <<
121 <<
122 retval = sos_syscall_get2args(user_ctx <<
123 if (SOS_OK != retval) <<
124 break; <<
125 <<
126 <<
127 retval = sos_strndup_from_user(& str, <<
128 if (SOS_OK != retval) <<
129 { <<
130 break; <<
131 } <<
132 <<
133 <<
134 new_as = sos_umem_vmm_create_empty_as( <<
135 if (! new_as) <<
136 { <<
137 sos_kfree((sos_vaddr_t)str); <<
138 retval = -SOS_ENOMEM; <<
139 break; <<
140 } <<
141 <<
142 <<
143 start_uaddr = sos_binfmt_elf32_map(new <<
144 if (start_uaddr == (sos_uaddr_t)NULL) <<
145 { <<
146 sos_umem_vmm_delete_as(new_as); <<
147 sos_kfree((sos_vaddr_t)str); <<
148 retval = -SOS_ENOENT; <<
149 break; <<
150 } <<
151 <<
152 <<
153 #define SOS_DEFAULT_USER_STACK_SIZE (8 << 20) <<
154 ustack = (SOS_PAGING_TOP_USER_ADDRESS <<
155 + 1; <<
156 retval = sos_dev_zero_map(new_as, &ust <<
157 SOS_VM_MAP_P <<
158 <<
159 if (SOS_OK != retval) <<
160 { <<
161 sos_umem_vmm_delete_as(new_as); <<
162 sos_kfree((sos_vaddr_t)str); <<
163 break; <<
164 } <<
165 <<
166 <<
167 new_thr = sos_create_user_thread(NULL, <<
168 proc, <<
169 start <<
170 0, 0, <<
171 ustac <<
172 - 4 <<
173 SOS_S <<
174 if (! new_thr) <<
175 { <<
176 sos_umem_vmm_delete_as(new_as); <<
177 sos_kfree((sos_vaddr_t)str); <<
178 retval = -SOS_ENOMEM; <<
179 break; <<
180 } <<
181 <<
182 sos_process_set_name(proc, str); <<
183 <<
184 <<
185 retval = sos_process_set_address_space <<
186 <<
187 if (SOS_OK != retval) <<
188 { <<
189 sos_umem_vmm_delete_as(new_as); <<
190 sos_kfree((sos_vaddr_t)str); <<
191 break; <<
192 } <<
193 <<
194 <<
195 sos_kfree((sos_vaddr_t)str); <<
196 sos_thread_exit(); <<
197 retval = -SOS_EFATAL; <<
198 } <<
199 break; <<
200 <<
201 case SOS_SYSCALL_ID_MUNMAP: <<
202 { <<
203 sos_uaddr_t start_uaddr; <<
204 sos_size_t size; <<
205 struct sos_umem_vmm_as * my_as; <<
206 <<
207 my_as <<
208 = sos_process_get_address_space(sos_ <<
209 <<
210 retval = sos_syscall_get2args(user_ctx <<
211 SYSCALL_ <<
212 SYSCALL_ <<
213 if (SOS_OK != retval) <<
214 break; <<
215 <<
216 retval = sos_umem_vmm_unmap(my_as, sta <<
217 } <<
218 break; <<
219 <<
220 case SOS_SYSCALL_ID_MPROTECT: <<
221 { <<
222 sos_uaddr_t start_uaddr; <<
223 sos_size_t size; <<
224 sos_ui32_t new_access_rights; <<
225 struct sos_umem_vmm_as * my_as; <<
226 <<
227 my_as <<
228 = sos_process_get_address_space(sos_ <<
229 <<
230 retval = sos_syscall_get3args(user_ctx <<
231 SYSCALL_ <<
232 SYSCALL_ <<
233 SYSCALL_ <<
234 if (SOS_OK != retval) <<
235 break; <<
236 <<
237 retval = sos_thread_prepare_user_space <<
238 if (SOS_OK != retval) <<
239 break; <<
240 <<
241 retval = sos_umem_vmm_chprot(my_as, st <<
242 new_acces <<
243 <<
244 sos_thread_end_user_space_access(); <<
245 } <<
246 break; <<
247 <<
248 case SOS_SYSCALL_ID_MRESIZE: <<
249 { <<
250 sos_uaddr_t old_uaddr; <<
251 sos_size_t old_size; <<
252 sos_uaddr_t *uptr_new_uaddr; <<
253 sos_uaddr_t new_uaddr; <<
254 sos_size_t new_size; <<
255 sos_ui32_t flags; <<
256 struct sos_umem_vmm_as * my_as; <<
257 <<
258 my_as <<
259 = sos_process_get_address_space(sos_ <<
260 <<
261 retval = sos_syscall_get5args(user_ctx <<
262 SYSCALL_ <<
263 SYSCALL_ <<
264 SYSCALL_ <<
265 SYSCALL_ <<
266 SYSCALL_ <<
267 if (SOS_OK != retval) <<
268 break; <<
269 <<
270 if (sizeof(new_uaddr) != sos_memcpy_fr <<
271 <<
272 <<
273 <<
274 { <<
275 retval = -SOS_EFAULT; <<
276 break; <<
277 } <<
278 <<
279 retval = sos_thread_prepare_user_space <<
280 if (SOS_OK != retval) <<
281 break; <<
282 <<
283 retval = sos_umem_vmm_resize(my_as, ol <<
284 & new_uad <<
285 sos_thread_end_user_space_access(); <<
286 if (SOS_OK != retval) <<
287 break; <<
288 <<
289 if (sizeof(new_uaddr) <<
290 == sos_memcpy_to_user((sos_uaddr_t <<
291 (sos_vaddr_t <<
292 sizeof(new_u <<
293 { <<
294 retval = -SOS_EFAULT; <<
295 break; <<
296 } <<
297 } <<
298 break; <<
299 <<
300 case SOS_SYSCALL_ID_MSYNC: <<
301 { <<
302 sos_uaddr_t start_uaddr; <<
303 sos_size_t size; <<
304 sos_ui32_t flags; <<
305 struct sos_umem_vmm_as * my_as; <<
306 <<
307 my_as <<
308 = sos_process_get_address_space(sos_ <<
309 <<
310 retval = sos_syscall_get3args(user_ctx <<
311 SYSCALL_ <<
312 SYSCALL_ <<
313 SYSCALL_ <<
314 if (SOS_OK != retval) <<
315 break; <<
316 <<
317 retval = sos_thread_prepare_user_space <<
318 if (SOS_OK != retval) <<
319 break; <<
320 retval = sos_umem_vmm_sync(my_as, star <<
321 sos_thread_end_user_space_access(); <<
322 } <<
323 break; <<
324 <<
325 case SOS_SYSCALL_ID_NEW_THREAD: <<
326 { <<
327 sos_uaddr_t start_func; <<
328 sos_ui32_t start_arg1, start_arg2; <<
329 sos_size_t stack_size; <<
330 sos_uaddr_t stack_uaddr; <<
331 <<
332 struct sos_thread * new_thr; <<
333 struct sos_umem_vmm_as * my_as; <<
334 <<
335 my_as <<
336 = sos_process_get_address_space(sos_ <<
337 <<
338 retval = sos_syscall_get4args(user_ctx <<
339 SYSCALL_ <<
340 SYSCALL_ <<
341 SYSCALL_ <<
342 SYSCALL_ <<
343 if (SOS_OK != retval) <<
344 break; <<
345 <<
346 if (stack_size <= 0) <<
347 { <<
348 retval = -SOS_EINVAL; <<
349 break; <<
350 } <<
351 <<
352 <<
353 stack_uaddr = 0; <<
354 stack_size = SOS_PAGE_ALIGN_SUP(stack_ <<
355 retval = sos_dev_zero_map(my_as, & sta <<
356 SOS_VM_MAP_P <<
357 <<
358 if (SOS_OK != retval) <<
359 break; <<
360 <<
361 <<
362 new_thr = sos_create_user_thread(NULL, <<
363 sos_t <<
364 start <<
365 start <<
366 start <<
367 stack <<
368 SOS_S <<
369 <<
370 if (! new_thr) <<
371 { <<
372 sos_umem_vmm_unmap(my_as, stack_ua <<
373 retval = -SOS_ENOMEM; <<
374 break; <<
375 } <<
376 <<
377 } <<
378 break; <<
379 <<
380 case SOS_SYSCALL_ID_NANOSLEEP: <<
381 { <<
382 struct sos_time delay; <<
383 <<
384 retval = sos_syscall_get2args(user_ctx <<
385 SYSCALL_ <<
386 SYSCALL_ <<
387 if (SOS_OK != retval) <<
388 break; <<
389 <<
390 retval = sos_thread_sleep(& delay); <<
391 } <<
392 break; <<
393 <<
394 case SOS_SYSCALL_ID_BRK: <<
395 { <<
396 sos_uaddr_t new_top_heap; <<
397 struct sos_umem_vmm_as * my_as; <<
398 <<
399 my_as <<
400 = sos_process_get_address_space(sos_ <<
401 <<
402 retval = sos_syscall_get1arg(user_ctxt <<
403 SYSCALL_V <<
404 if (SOS_OK != retval) <<
405 break; <<
406 <<
407 retval = sos_thread_prepare_user_space <<
408 if (SOS_OK != retval) <<
409 break; <<
410 <<
411 retval = sos_umem_vmm_brk(my_as, new_t <<
412 sos_thread_end_user_space_access(); <<
413 } <<
414 break; <<
415 <<
416 <<
417 <<
418 <<
419 <<
420 case SOS_SYSCALL_ID_MOUNT: <<
421 { <<
422 sos_uaddr_t user_src; <<
423 sos_size_t srclen; <<
424 char * kernel_src = NULL; <<
425 sos_uaddr_t user_dst; <<
426 sos_size_t dstlen; <<
427 char * kernel_dst; <<
428 sos_ui32_t mountflags; <<
429 sos_uaddr_t user_fstype; <<
430 char * kernel_fstype; <<
431 sos_uaddr_t user_args; <<
432 char * kernel_args = NULL; <<
433 struct sos_process * proc; <<
434 <<
435 proc = sos_thread_get_current()->proce <<
436 retval = sos_syscall_get7args(user_ctx <<
437 SYSCALL_ <<
438 SYSCALL_ <<
439 SYSCALL_ <<
440 SYSCALL_ <<
441 SYSCALL_ <<
442 SYSCALL_ <<
443 SYSCALL_ <<
444 if (SOS_OK != retval) <<
445 break; <<
446 <<
447 if (user_src != (sos_uaddr_t)NULL) <<
448 { <<
449 retval = sos_strndup_from_user(&ke <<
450 if (SOS_OK != retval) <<
451 break; <<
452 } <<
453 <<
454 retval = sos_strndup_from_user(&kernel <<
455 if (SOS_OK != retval) <<
456 { <<
457 if (kernel_src) <<
458 sos_kfree((sos_vaddr_t)kernel_sr <<
459 break; <<
460 } <<
461 <<
462 retval = sos_strndup_from_user(& kerne <<
463 if (SOS_OK != retval) <<
464 { <<
465 if (kernel_src) <<
466 sos_kfree((sos_vaddr_t)kernel_sr <<
467 sos_kfree((sos_vaddr_t)kernel_dst) <<
468 break; <<
469 } <<
470 <<
471 if (user_args != (sos_uaddr_t)NULL) <<
472 { <<
473 retval = sos_strndup_from_user(& k <<
474 if (SOS_OK != retval) <<
475 { <<
476 if (kernel_src) <<
477 sos_kfree((sos_vaddr_t)kerne <<
478 sos_kfree((sos_vaddr_t)kernel_ <<
479 sos_kfree((sos_vaddr_t)kernel_ <<
480 break; <<
481 } <<
482 } <<
483 <<
484 retval = sos_fs_mount(proc, kernel_src <<
485 kernel_dst, dstl <<
486 kernel_fstype, <<
487 mountflags, <<
488 kernel_args, <<
489 NULL); <<
490 if (kernel_src) <<
491 sos_kfree((sos_vaddr_t)kernel_src); <<
492 sos_kfree((sos_vaddr_t)kernel_dst); <<
493 sos_kfree((sos_vaddr_t)kernel_fstype); <<
494 if (kernel_args) <<
495 sos_kfree((sos_vaddr_t)kernel_args); <<
496 } <<
497 break; <<
498 <<
499 case SOS_SYSCALL_ID_UMOUNT: <<
500 { <<
501 sos_uaddr_t user_str; <<
502 sos_size_t len; <<
503 char * path; <<
504 struct sos_process * proc; <<
505 <<
506 proc = sos_thread_get_current()->proce <<
507 retval = sos_syscall_get2args(user_ctx <<
508 SYSCALL_ <<
509 SYSCALL_ <<
510 if (SOS_OK != retval) <<
511 break; <<
512 <<
513 retval = sos_strndup_from_user(&path, <<
514 if (SOS_OK != retval) <<
515 break; <<
516 <<
517 retval = sos_fs_umount(proc, <<
518 path, len); <<
519 sos_kfree((sos_vaddr_t)path); <<
520 } <<
521 break; <<
522 <<
523 case SOS_SYSCALL_ID_SYNC: <<
524 { <<
525 sos_fs_sync_all_fs(); <<
526 retval = SOS_OK; <<
527 } <<
528 break; <<
529 <<
530 case SOS_SYSCALL_ID_VFSTAT64: <<
531 { <<
532 sos_uaddr_t user_str; <<
533 sos_size_t len; <<
534 sos_uaddr_t user_vfstat_struct; <<
535 struct sos_fs_statfs kernel_vfstat_str <<
536 char * path; <<
537 struct sos_process * proc; <<
538 <<
539 proc = sos_thread_get_current()->proce <<
540 retval = sos_syscall_get3args(user_ctx <<
541 SYSCALL_ <<
542 SYSCALL_ <<
543 SYSCALL_ <<
544 if (SOS_OK != retval) <<
545 break; <<
546 <<
547 retval = sos_strndup_from_user(&path, <<
548 if (SOS_OK != retval) <<
549 break; <<
550 <<
551 retval = sos_fs_vfstat(proc, path, len <<
552 sos_kfree((sos_vaddr_t)path); <<
553 if (SOS_OK != retval) <<
554 break; <<
555 <<
556 if (sizeof(kernel_vfstat_struct) <<
557 != sos_memcpy_to_user(user_vfstat_ <<
558 (sos_vaddr_t <<
559 sizeof(kerne <<
560 retval = -SOS_EFAULT; <<
561 } <<
562 break; <<
563 <<
564 case SOS_SYSCALL_ID_OPEN: <<
565 { <<
566 sos_uaddr_t user_str; <<
567 sos_size_t len; <<
568 sos_ui32_t open_flags; <<
569 sos_ui32_t access_rights; <<
570 char * path; <<
571 struct sos_fs_opened_file * of; <<
572 struct sos_process * proc; <<
573 <<
574 proc = sos_thread_get_current()->proce <<
575 retval = sos_syscall_get4args(user_ctx <<
576 SYSCALL_ <<
577 SYSCALL_ <<
578 SYSCALL_ <<
579 SYSCALL_ <<
580 if (SOS_OK != retval) <<
581 break; <<
582 <<
583 retval = sos_strndup_from_user(&path, <<
584 if (SOS_OK != retval) <<
585 break; <<
586 <<
587 retval = sos_fs_open(proc, <<
588 path, len, <<
589 open_flags, <<
590 access_rights, <<
591 & of); <<
592 sos_kfree((sos_vaddr_t)path); <<
593 if (SOS_OK != retval) <<
594 break; <<
595 <<
596 retval = sos_process_register_opened_f <<
597 if (retval < 0) <<
598 { <<
599 sos_fs_close(of); <<
600 break; <<
601 } <<
602 } <<
603 break; <<
604 <<
605 case SOS_SYSCALL_ID_CLOSE: <<
606 { <<
607 struct sos_fs_opened_file * of; <<
608 struct sos_process * proc; <<
609 int fd; <<
610 <<
611 proc = sos_thread_get_current()->proce <<
612 retval = sos_syscall_get1arg(user_ctxt <<
613 SYSCALL_V <<
614 if (SOS_OK != retval) <<
615 break; <<
616 <<
617 of = sos_process_get_opened_file(proc, <<
618 if (NULL == of) <<
619 { <<
620 retval = -SOS_EBADF; <<
621 break; <<
622 } <<
623 <<
624 retval = sos_process_unregister_opened <<
625 if (SOS_OK != retval) <<
626 break; <<
627 <<
628 retval = sos_fs_close(of); <<
629 } <<
630 break; <<
631 <<
632 case SOS_SYSCALL_ID_READ: <<
633 { <<
634 struct sos_fs_opened_file * of; <<
635 struct sos_process * proc; <<
636 sos_uaddr_t uaddr_buf; <<
637 sos_uaddr_t uaddr_buflen; <<
638 sos_size_t kernel_buflen; <<
639 int fd; <<
640 <<
641 proc = sos_thread_get_current()->proce <<
642 retval = sos_syscall_get3args(user_ctx <<
643 SYSCALL_ <<
644 SYSCALL_ <<
645 SYSCALL_ <<
646 if (SOS_OK != retval) <<
647 break; <<
648 <<
649 <<
650 retval = sos_memcpy_from_user((sos_vad <<
651 uaddr_bu <<
652 sizeof(k <<
653 if (sizeof(kernel_buflen) != retval) <<
654 { <<
655 retval = -SOS_EFAULT; <<
656 break; <<
657 } <<
658 <<
659 of = sos_process_get_opened_file(proc, <<
660 if (NULL == of) <<
661 { <<
662 retval = -SOS_EBADF; <<
663 break; <<
664 } <<
665 <<
666 <<
667 retval = sos_fs_read(of, uaddr_buf, & <<
668 <<
669 <<
670 sos_memcpy_to_user(uaddr_buflen, <<
671 (sos_vaddr_t)& kern <<
672 sizeof(kernel_bufle <<
673 } <<
674 break; <<
675 <<
676 case SOS_SYSCALL_ID_READDIR: <<
677 { <<
678 struct sos_fs_opened_file * of; <<
679 struct sos_process * proc; <<
680 sos_uaddr_t uaddr_direntry; <<
681 struct sos_fs_dirent direntry; <<
682 int fd; <<
683 <<
684 proc = sos_thread_get_current()->proce <<
685 retval = sos_syscall_get2args(user_ctx <<
686 SYSCALL_ <<
687 SYSCALL_ <<
688 if (SOS_OK != retval) <<
689 break; <<
690 <<
691 of = sos_process_get_opened_file(proc, <<
692 if (NULL == of) <<
693 { <<
694 retval = -SOS_EBADF; <<
695 break; <<
696 } <<
697 <<
698 <<
699 retval = sos_fs_readdir(of, & direntry <<
700 if (SOS_OK != retval) <<
701 break; <<
702 <<
703 <<
704 if (sizeof(direntry) != sos_memcpy_to_ <<
705 <<
706 <<
707 retval = -SOS_EFAULT; <<
708 } <<
709 break; <<
710 <<
711 case SOS_SYSCALL_ID_WRITE: <<
712 { <<
713 struct sos_fs_opened_file * of; <<
714 struct sos_process * proc; <<
715 sos_uaddr_t uaddr_buf; <<
716 sos_uaddr_t uaddr_buflen; <<
717 sos_size_t kernel_buflen; <<
718 int fd; <<
719 <<
720 proc = sos_thread_get_current()->proce <<
721 retval = sos_syscall_get3args(user_ctx <<
722 SYSCALL_ <<
723 SYSCALL_ <<
724 SYSCALL_ <<
725 if (SOS_OK != retval) <<
726 break; <<
727 <<
728 <<
729 retval = sos_memcpy_from_user((sos_vad <<
730 uaddr_bu <<
731 sizeof(k <<
732 if (sizeof(kernel_buflen) != retval) <<
733 { <<
734 retval = -SOS_EFAULT; <<
735 break; <<
736 } <<
737 <<
738 of = sos_process_get_opened_file(proc, <<
739 if (NULL == of) <<
740 { <<
741 retval = -SOS_EBADF; <<
742 break; <<
743 } <<
744 <<
745 <<
746 retval = sos_fs_write(of, uaddr_buf, & <<
747 <<
748 <<
749 sos_memcpy_to_user(uaddr_buflen, <<
750 (sos_vaddr_t)& kern <<
751 sizeof(kernel_bufle <<
752 } <<
753 break; <<
754 <<
755 case SOS_SYSCALL_ID_SEEK64: <<
756 { <<
757 struct sos_fs_opened_file * of; <<
758 struct sos_process * proc; <<
759 sos_uaddr_t uaddr_offset; <<
760 sos_seek_whence_t whence; <<
761 sos_lsoffset_t kernel_offset, result_p <<
762 int fd; <<
763 <<
764 proc = sos_thread_get_current()->proce <<
765 retval = sos_syscall_get3args(user_ctx <<
766 SYSCALL_ <<
767 SYSCALL_ <<
768 SYSCALL_ <<
769 if (SOS_OK != retval) <<
770 break; <<
771 <<
772 <<
773 retval = sos_memcpy_from_user((sos_vad <<
774 uaddr_of <<
775 sizeof(k <<
776 if (sizeof(kernel_offset) != retval) <<
777 { <<
778 retval = -SOS_EFAULT; <<
779 break; <<
780 } <<
781 <<
782 of = sos_process_get_opened_file(proc, <<
783 if (NULL == of) <<
784 { <<
785 retval = -SOS_EBADF; <<
786 break; <<
787 } <<
788 <<
789 <<
790 retval = sos_fs_seek(of, kernel_offset <<
791 <<
792 <<
793 sos_memcpy_to_user(uaddr_offset, <<
794 (sos_vaddr_t)& resu <<
795 sizeof(kernel_offse <<
796 } <<
797 break; <<
798 <<
799 case SOS_SYSCALL_ID_FTRUNCATE64: <<
800 { <<
801 struct sos_fs_opened_file * of; <<
802 struct sos_process * proc; <<
803 sos_lsoffset_t length; <<
804 int fd; <<
805 <<
806 proc = sos_thread_get_current()->proce <<
807 retval = sos_syscall_get2args(user_ctx <<
808 SYSCALL_ <<
809 SYSCALL_ <<
810 if (SOS_OK != retval) <<
811 break; <<
812 <<
813 of = sos_process_get_opened_file(proc, <<
814 if (NULL == of) <<
815 { <<
816 retval = -SOS_EBADF; <<
817 break; <<
818 } <<
819 <<
820 <<
821 retval = sos_fs_ftruncate(of, length); <<
822 } <<
823 break; <<
824 <<
825 case SOS_SYSCALL_ID_FSMMAP: <<
826 { <<
827 sos_uaddr_t ptr_hint_uaddr; <<
828 sos_uaddr_t hint_uaddr; <<
829 sos_size_t length; <<
830 sos_ui32_t prot; <<
831 sos_ui32_t flags; <<
832 int fd; <<
833 sos_ui32_t offs64_hi; <<
834 sos_ui32_t offs64_lo; <<
835 sos_luoffset_t offset_in_resource; <<
836 struct sos_fs_opened_file * of; <<
837 struct sos_process * proc; <<
838 <<
839 proc = sos_thread_get_current()->proce <<
840 retval = sos_syscall_get7args(user_ctx <<
841 SYSCALL_ <<
842 SYSCALL_ <<
843 SYSCALL_ <<
844 SYSCALL_ <<
845 SYSCALL_ <<
846 SYSCALL_ <<
847 SYSCALL_ <<
848 if (SOS_OK != retval) <<
849 break; <<
850 <<
851 of = sos_process_get_opened_file(proc, <<
852 if (NULL == of) <<
853 { <<
854 retval = -SOS_EBADF; <<
855 break; <<
856 } <<
857 <<
858 <<
859 offset_in_resource = offs64_hi; <<
860 offset_in_resource <<= 32; <<
861 offset_in_resource |= offs64_lo; <<
862 <<
863 retval = sos_memcpy_from_user((sos_vad <<
864 ptr_hint <<
865 sizeof(h <<
866 if (sizeof(hint_uaddr) != retval) <<
867 { <<
868 retval = -SOS_EFAULT; <<
869 break; <<
870 } <<
871 <<
872 retval = sos_fs_mmap(of, & hint_uaddr, <<
873 offset_in_resourc <<
874 if (SOS_OK == retval) <<
875 { <<
876 if (sizeof(hint_uaddr) <<
877 != sos_memcpy_to_user(ptr_hint <<
878 (sos_vad <<
879 sizeof(h <<
880 { <<
881 sos_umem_vmm_unmap(sos_process <<
882 hint_uaddr, <<
883 retval = -SOS_EFAULT; <<
884 } <<
885 } <<
886 <<
887 } <<
888 break; <<
889 <<
890 case SOS_SYSCALL_ID_FSYNC: <<
891 { <<
892 struct sos_fs_opened_file * of; <<
893 struct sos_process * proc; <<
894 int fd; <<
895 <<
896 proc = sos_thread_get_current()->proce <<
897 retval = sos_syscall_get1arg(user_ctxt <<
898 SYSCALL_V <<
899 if (SOS_OK != retval) <<
900 break; <<
901 <<
902 of = sos_process_get_opened_file(proc, <<
903 if (NULL == of) <<
904 { <<
905 retval = -SOS_EBADF; <<
906 break; <<
907 } <<
908 <<
909 <<
910 retval = sos_fs_fsync(of); <<
911 } <<
912 break; <<
913 <<
914 case SOS_SYSCALL_ID_FCNTL: <<
915 { <<
916 struct sos_fs_opened_file * of; <<
917 struct sos_process * proc; <<
918 sos_ui32_t cmd, arg; <<
919 int fd; <<
920 <<
921 proc = sos_thread_get_current()->proce <<
922 retval = sos_syscall_get3args(user_ctx <<
923 SYSCALL_ <<
924 SYSCALL_ <<
925 SYSCALL_ <<
926 if (SOS_OK != retval) <<
927 break; <<
928 <<
929 of = sos_process_get_opened_file(proc, <<
930 if (NULL == of) <<
931 { <<
932 retval = -SOS_EBADF; <<
933 break; <<
934 } <<
935 <<
936 <<
937 retval = sos_fs_fcntl(of, cmd, arg); <<
938 } <<
939 break; <<
940 <<
941 case SOS_SYSCALL_ID_IOCTL: <<
942 { <<
943 struct sos_fs_opened_file * of; <<
944 struct sos_process * proc; <<
945 sos_ui32_t cmd, arg; <<
946 int fd; <<
947 <<
948 proc = sos_thread_get_current()->proce <<
949 retval = sos_syscall_get3args(user_ctx <<
950 SYSCALL_ <<
951 SYSCALL_ <<
952 SYSCALL_ <<
953 if (SOS_OK != retval) <<
954 break; <<
955 <<
956 of = sos_process_get_opened_file(proc, <<
957 if (NULL == of) <<
958 { <<
959 retval = -SOS_EBADF; <<
960 break; <<
961 } <<
962 <<
963 <<
964 retval = sos_fs_ioctl(of, cmd, arg); <<
965 } <<
966 break; <<
967 <<
968 case SOS_SYSCALL_ID_CREAT: <<
969 { <<
970 sos_uaddr_t user_str; <<
971 sos_size_t len; <<
972 sos_ui32_t access_rights; <<
973 char * path; <<
974 struct sos_process * proc; <<
975 <<
976 proc = sos_thread_get_current()->proce <<
977 retval = sos_syscall_get3args(user_ctx <<
978 SYSCALL_ <<
979 SYSCALL_ <<
980 SYSCALL_ <<
981 if (SOS_OK != retval) <<
982 break; <<
983 <<
984 retval = sos_strndup_from_user(&path, <<
985 if (SOS_OK != retval) <<
986 break; <<
987 <<
988 retval = sos_fs_creat(proc, <<
989 path, len, <<
990 access_rights); <<
991 sos_kfree((sos_vaddr_t)path); <<
992 } <<
993 break; <<
994 <<
995 case SOS_SYSCALL_ID_LINK: <<
996 case SOS_SYSCALL_ID_RENAME: <<
997 { <<
998 sos_uaddr_t user_oldpath, user_newpath <<
999 sos_size_t oldpathlen, newpathlen; <<
1000 char * kernel_oldpath, * kernel_newpa <<
1001 struct sos_process * proc; <<
1002 <<
1003 proc = sos_thread_get_current()->proc <<
1004 retval = sos_syscall_get4args(user_ct <<
1005 SYSCALL <<
1006 SYSCALL <<
1007 SYSCALL <<
1008 SYSCALL <<
1009 if (SOS_OK != retval) <<
1010 break; <<
1011 <<
1012 retval = sos_strndup_from_user(&kerne <<
1013 user_o <<
1014 oldpat <<
1015 if (SOS_OK != retval) <<
1016 break; <<
1017 <<
1018 retval = sos_strndup_from_user(&kerne <<
1019 user_n <<
1020 newpat <<
1021 if (SOS_OK != retval) <<
1022 { <<
1023 sos_kfree((sos_vaddr_t) kernel_ol <<
1024 break; <<
1025 } <<
1026 <<
1027 if (syscall_id == SOS_SYSCALL_ID_LINK <<
1028 retval = sos_fs_link(proc, <<
1029 kernel_oldpath <<
1030 kernel_newpath <<
1031 else <<
1032 retval = sos_fs_rename(proc, <<
1033 kernel_oldpa <<
1034 kernel_newpa <<
1035 sos_kfree((sos_vaddr_t)kernel_oldpath <<
1036 sos_kfree((sos_vaddr_t)kernel_newpath <<
1037 } <<
1038 break; <<
1039 <<
1040 case SOS_SYSCALL_ID_UNLINK: <<
1041 { <<
1042 sos_uaddr_t user_str; <<
1043 sos_size_t len; <<
1044 char * path; <<
1045 struct sos_process * proc; <<
1046 <<
1047 proc = sos_thread_get_current()->proc <<
1048 retval = sos_syscall_get2args(user_ct <<
1049 SYSCALL <<
1050 SYSCALL <<
1051 if (SOS_OK != retval) <<
1052 break; <<
1053 <<
1054 retval = sos_strndup_from_user(&path, <<
1055 if (SOS_OK != retval) <<
1056 break; <<
1057 <<
1058 retval = sos_fs_unlink(proc, <<
1059 path, len); <<
1060 sos_kfree((sos_vaddr_t)path); <<
1061 } <<
1062 break; <<
1063 <<
1064 case SOS_SYSCALL_ID_SYMLINK: <<
1065 { <<
1066 sos_uaddr_t user_path, user_targetpat <<
1067 sos_size_t pathlen, targetpathlen; <<
1068 char * kernel_path; <<
1069 struct sos_process * proc; <<
1070 <<
1071 proc = sos_thread_get_current()->proc <<
1072 retval = sos_syscall_get4args(user_ct <<
1073 SYSCALL <<
1074 SYSCALL <<
1075 SYSCALL <<
1076 SYSCALL <<
1077 if (SOS_OK != retval) <<
1078 break; <<
1079 <<
1080 retval = sos_strndup_from_user(&kerne <<
1081 user_p <<
1082 pathle <<
1083 if (SOS_OK != retval) <<
1084 break; <<
1085 <<
1086 retval = sos_fs_symlink(proc, <<
1087 kernel_path, <<
1088 user_targetpa <<
1089 sos_kfree((sos_vaddr_t)kernel_path); <<
1090 } <<
1091 break; <<
1092 <<
1093 case SOS_SYSCALL_ID_MKNOD: <<
1094 { <<
1095 sos_uaddr_t user_str; <<
1096 sos_size_t len; <<
1097 sos_ui32_t access_rights; <<
1098 int type; <<
1099 char * path; <<
1100 struct sos_fs_dev_id_t dev_id; <<
1101 struct sos_process * proc; <<
1102 <<
1103 proc = sos_thread_get_current()->proc <<
1104 retval = sos_syscall_get6args(user_ct <<
1105 SYSCALL <<
1106 SYSCALL <<
1107 SYSCALL <<
1108 SYSCALL <<
1109 SYSCALL <<
1110 SYSCALL <<
1111 if (SOS_OK != retval) <<
1112 break; <<
1113 <<
1114 retval = sos_strndup_from_user(&path, <<
1115 if (SOS_OK != retval) <<
1116 break; <<
1117 <<
1118 switch (type) <<
1119 { <<
1120 case SOS_FS_NODE_REGULAR_FILE: <<
1121 retval = sos_fs_creat(proc, path, <<
1122 break; <<
1123 <<
1124 case SOS_FS_NODE_DIRECTORY: <<
1125 retval = sos_fs_mkdir(proc, path, <<
1126 break; <<
1127 <<
1128 case SOS_FS_NODE_SYMLINK: <<
1129 retval = -SOS_ENOSUP; <<
1130 break; <<
1131 <<
1132 case SOS_FS_NODE_DEVICE_CHAR: <<
1133 case SOS_FS_NODE_DEVICE_BLOCK: <<
1134 retval = sos_fs_mknod(proc, <<
1135 path, len, <<
1136 break; <<
1137 <<
1138 default: <<
1139 retval = -SOS_EINVAL; <<
1140 break; <<
1141 } <<
1142 <<
1143 sos_kfree((sos_vaddr_t)path); <<
1144 } <<
1145 break; <<
1146 <<
1147 case SOS_SYSCALL_ID_MKDIR: <<
1148 { <<
1149 sos_uaddr_t user_str; <<
1150 sos_size_t len; <<
1151 sos_ui32_t access_rights; <<
1152 char * path; <<
1153 struct sos_process * proc; <<
1154 <<
1155 proc = sos_thread_get_current()->proc <<
1156 retval = sos_syscall_get3args(user_ct <<
1157 SYSCALL <<
1158 SYSCALL <<
1159 SYSCALL <<
1160 if (SOS_OK != retval) <<
1161 break; <<
1162 <<
1163 retval = sos_strndup_from_user(&path, <<
1164 if (SOS_OK != retval) <<
1165 break; <<
1166 <<
1167 retval = sos_fs_mkdir(proc, <<
1168 path, len, acce <<
1169 sos_kfree((sos_vaddr_t)path); <<
1170 } <<
1171 break; <<
1172 <<
1173 case SOS_SYSCALL_ID_RMDIR: <<
1174 { <<
1175 sos_uaddr_t user_str; <<
1176 sos_size_t len; <<
1177 char * path; <<
1178 struct sos_process * proc; <<
1179 <<
1180 proc = sos_thread_get_current()->proc <<
1181 retval = sos_syscall_get2args(user_ct <<
1182 SYSCALL <<
1183 SYSCALL <<
1184 if (SOS_OK != retval) <<
1185 break; <<
1186 <<
1187 retval = sos_strndup_from_user(&path, <<
1188 if (SOS_OK != retval) <<
1189 break; <<
1190 <<
1191 retval = sos_fs_rmdir(proc, path, len <<
1192 sos_kfree((sos_vaddr_t)path); <<
1193 } <<
1194 break; <<
1195 <<
1196 case SOS_SYSCALL_ID_CHMOD: <<
1197 { <<
1198 sos_uaddr_t user_str; <<
1199 sos_size_t len; <<
1200 sos_ui32_t access_rights; <<
1201 char * path; <<
1202 struct sos_process * proc; <<
1203 <<
1204 proc = sos_thread_get_current()->proc <<
1205 retval = sos_syscall_get3args(user_ct <<
1206 SYSCALL <<
1207 SYSCALL <<
1208 SYSCALL <<
1209 if (SOS_OK != retval) <<
1210 break; <<
1211 <<
1212 retval = sos_strndup_from_user(&path, <<
1213 if (SOS_OK != retval) <<
1214 break; <<
1215 <<
1216 retval = sos_fs_chmod(proc, path, len <<
1217 sos_kfree((sos_vaddr_t)path); <<
1218 } <<
1219 break; <<
1220 <<
1221 case SOS_SYSCALL_ID_STAT64: <<
1222 { <<
1223 sos_uaddr_t user_str; <<
1224 sos_size_t len; <<
1225 sos_uaddr_t user_stat_struct; <<
1226 struct sos_fs_stat kernel_stat_struct <<
1227 int nofollow; <<
1228 char * path; <<
1229 struct sos_process * proc; <<
1230 <<
1231 proc = sos_thread_get_current()->proc <<
1232 retval = sos_syscall_get4args(user_ct <<
1233 SYSCALL <<
1234 SYSCALL <<
1235 SYSCALL <<
1236 SYSCALL <<
1237 if (SOS_OK != retval) <<
1238 break; <<
1239 <<
1240 retval = sos_strndup_from_user(&path, <<
1241 if (SOS_OK != retval) <<
1242 break; <<
1243 <<
1244 retval = sos_fs_stat(proc, path, len, <<
1245 sos_kfree((sos_vaddr_t)path); <<
1246 if (SOS_OK != retval) <<
1247 break; <<
1248 <<
1249 if (sizeof(kernel_stat_struct) <<
1250 != sos_memcpy_to_user(user_stat_s <<
1251 (sos_vaddr_ <<
1252 sizeof(kern <<
1253 retval = -SOS_EFAULT; <<
1254 } <<
1255 break; <<
1256 <<
1257 case SOS_SYSCALL_ID_CHROOT: <<
1258 case SOS_SYSCALL_ID_CHDIR: <<
1259 { <<
1260 sos_uaddr_t user_str; <<
1261 sos_size_t len; <<
1262 char * path; <<
1263 struct sos_fs_opened_file * of, * old <<
1264 struct sos_process * proc; <<
1265 <<
1266 proc = sos_thread_get_current()->proc <<
1267 retval = sos_syscall_get2args(user_ct <<
1268 SYSCALL <<
1269 SYSCALL <<
1270 if (SOS_OK != retval) <<
1271 break; <<
1272 <<
1273 retval = sos_strndup_from_user(&path, <<
1274 if (SOS_OK != retval) <<
1275 break; <<
1276 <<
1277 retval = sos_fs_open(proc, <<
1278 path, len, <<
1279 SOS_FS_OPEN_DIRE <<
1280 SOS_FS_OPEN_READ <<
1281 & of); <<
1282 sos_kfree((sos_vaddr_t)path); <<
1283 if (SOS_OK != retval) <<
1284 break; <<
1285 <<
1286 if (syscall_id == SOS_SYSCALL_ID_CHRO <<
1287 retval = sos_process_chroot(proc, o <<
1288 else <<
1289 retval = sos_process_chdir(proc, of <<
1290 <<
1291 if (retval < 0) <<
1292 { <<
1293 sos_fs_close(of); <<
1294 break; <<
1295 } <<
1296 <<
1297 sos_fs_close(old_of); <<
1298 } <<
1299 break; <<
1300 035
1301 case SOS_SYSCALL_ID_FCHDIR: !! 036 switch(syscall_id)
>> 037 {
>> 038 case SOS_SYSCALL_ID_EXIT:
1302 { 039 {
1303 struct sos_fs_opened_file * of, * new !! 040 unsigned int status;
1304 struct sos_process * proc; !! 041 retval = sos_syscall_get1arg(user_ctxt, & status);
1305 int fd; <<
1306 <<
1307 proc = sos_thread_get_current()->proc <<
1308 retval = sos_syscall_get1arg(user_ctx <<
1309 SYSCALL_ <<
1310 if (SOS_OK != retval) <<
1311 break; <<
1312 <<
1313 of = sos_process_get_opened_file(proc <<
1314 if (NULL == of) <<
1315 { <<
1316 retval = -SOS_EBADF; <<
1317 break; <<
1318 } <<
1319 <<
1320 <<
1321 retval = sos_fs_duplicate_opened_file <<
1322 if (SOS_OK != retval) 042 if (SOS_OK != retval)
1323 break; 043 break;
1324 !! 044 sos_thread_exit();
1325 !! 045 retval = -SOS_EFATAL;
1326 retval = sos_process_chdir(proc, new_ <<
1327 if (retval < 0) <<
1328 { <<
1329 sos_fs_close(new_of); <<
1330 break; <<
1331 } <<
1332 <<
1333 sos_fs_close(old_of); <<
1334 } 046 }
1335 break; 047 break;
1336 <<
1337 case SOS_SYSCALL_ID_BOCHS_WRITE: 048 case SOS_SYSCALL_ID_BOCHS_WRITE:
1338 { 049 {
1339 sos_uaddr_t user_str; 050 sos_uaddr_t user_str;
1340 sos_size_t len; 051 sos_size_t len;
1341 char * str; 052 char * str;
1342 retval = sos_syscall_get2args(user_ct 053 retval = sos_syscall_get2args(user_ctxt, & user_str, & len);
1343 if (SOS_OK != retval) 054 if (SOS_OK != retval)
1344 break; 055 break;
1345 056
1346 retval = sos_strndup_from_user(& str, !! 057 str = (char*)sos_kmalloc(len + 1, 0);
1347 if (SOS_OK == retval) !! 058 if (str)
1348 { 059 {
1349 sos_bochs_printf("THR 0x%x: ", !! 060 retval = sos_strzcpy_from_user(str, user_str, len+1);
1350 (unsigned)sos_th !! 061 str[len] = '\0';
1351 retval = sos_bochs_putstring(str) !! 062 if (SOS_OK == retval)
1352 retval = len; !! 063 {
>> 064 sos_bochs_printf("THR 0x%x: ",
>> 065 (unsigned)sos_thread_get_current());
>> 066 retval = sos_bochs_putstring(str);
>> 067 retval = len;
>> 068 }
1353 sos_kfree((sos_vaddr_t)str); 069 sos_kfree((sos_vaddr_t)str);
1354 } 070 }
>> 071 else
>> 072 retval = -SOS_ENOMEM;
1355 } 073 }
1356 break; 074 break;
1357 075
1358 076
1359 077
1360 078
1361 079
1362 080
1363 081
1364 082
1365 083
1366 084
1367 085
1368 case 4012: 086 case 4012:
1369 { 087 {
1370 sos_uaddr_t user_str; 088 sos_uaddr_t user_str;
1371 unsigned int len; 089 unsigned int len;
1372 unsigned char * str; 090 unsigned char * str;
1373 091
1374 retval = sos_syscall_get2args(user_ct 092 retval = sos_syscall_get2args(user_ctxt, & user_str, & len);
1375 if (SOS_OK != retval) 093 if (SOS_OK != retval)
1376 break; 094 break;
1377 095
1378 str = (unsigned char*)sos_kmalloc(len !! 096 str = (char*)sos_kmalloc(len + 1, 0);
1379 if (str) 097 if (str)
1380 { 098 {
1381 sos_bochs_printf("THR %p, Hexdump !! 099 int i;
1382 sos_thread_get_c !! 100 sos_bochs_printf("Hexdump(0x%x, %d):\n", user_str, len);
1383 retval = sos_memcpy_from_user((so 101 retval = sos_memcpy_from_user((sos_vaddr_t) str, user_str, len);
1384 sos_bochs_printf(" (Successfully 102 sos_bochs_printf(" (Successfully copied %d out of %d)\n",
1385 retval, len); 103 retval, len);
1386 if (retval > 0) !! 104
1387 sos_bochs_hexdump(str, retval); !! 105 for (i = 0 ; i < retval ; i++)
>> 106 {
>> 107 if ((i % 32) == 0)
>> 108 sos_bochs_printf("%x:", i);
>> 109 sos_bochs_printf(" %x", str[i]);
>> 110 if (((i+1) % 32) == 0)
>> 111 sos_bochs_printf("\n");
>> 112 }
>> 113 if (i % 32)
>> 114 sos_bochs_printf("\n");
1388 115
1389 sos_kfree((sos_vaddr_t)str); 116 sos_kfree((sos_vaddr_t)str);
1390 } 117 }
1391 else 118 else
1392 retval = -SOS_ENOMEM; 119 retval = -SOS_ENOMEM;
1393 } <<
1394 break; <<
1395 <<
1396 <<
1397 <<
1398 <<
1399 <<
1400 <<
1401 case 4004: <<
1402 { <<
1403 sos_uaddr_t ustr; <<
1404 char * kstr; <<
1405 struct sos_umem_vmm_as * my_as; <<
1406 <<
1407 retval = sos_syscall_get1arg(user_ctx <<
1408 if (SOS_OK != retval) <<
1409 break; <<
1410 <<
1411 retval = sos_strndup_from_user(& kstr <<
1412 if (SOS_OK != retval) <<
1413 break; <<
1414 <<
1415 extern void sos_dump_as(const struct <<
1416 my_as <<
1417 = sos_process_get_address_space(sos <<
1418 sos_dump_as(my_as, kstr); <<
1419 sos_kfree((sos_vaddr_t)kstr); <<
1420 } 120 }
1421 break; 121 break;
1422 122
1423 123
1424 124
1425 125
1426 126
1427 127
1428 case 4008: 128 case 4008:
1429 { 129 {
1430 extern void sos_process_dumplist(void 130 extern void sos_process_dumplist(void);
1431 sos_process_dumplist(); 131 sos_process_dumplist();
1432 retval = SOS_OK; 132 retval = SOS_OK;
1433 } 133 }
1434 break; 134 break;
1435 135
1436 default: 136 default:
1437 sos_bochs_printf("Syscall: UNKNOWN[%d]\ 137 sos_bochs_printf("Syscall: UNKNOWN[%d]\n", syscall_id);
1438 retval = -SOS_ENOSUP; 138 retval = -SOS_ENOSUP;
1439 } 139 }
1440 140
1441 return retval; 141 return retval;
1442 } 142 }