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>
018 #include <sos/thread.h> 019 #include <sos/thread.h>
019 #include <sos/kmalloc.h> 020 #include <sos/kmalloc.h>
020 #include <sos/klibc.h> 021 #include <sos/klibc.h>
021 #include <drivers/bochs.h> 022 #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>
022 029
023 #include <hwcore/cpu_context.h> 030 #include <hwcore/cpu_context.h>
024 #include <sos/uaccess.h> 031 #include <sos/uaccess.h>
025 #include "syscall.h" 032 #include "syscall.h"
026 033
027 034
>> 035
>> 036
>> 037 #define SYSCALL_VAR32_PTR(ui32_variable) \
>> 038 ((void*)&(ui32_variable))
>> 039
>> 040
028 041
029 042
030 043
031 sos_ret_t sos_do_syscall(int syscall_id, 044 sos_ret_t sos_do_syscall(int syscall_id,
032 const struct sos_cpu_ 045 const struct sos_cpu_state *user_ctxt)
033 { 046 {
034 sos_ret_t retval; 047 sos_ret_t retval;
035 048
036 switch(syscall_id) !! 049 switch(syscall_id)
037 { !! 050 {
038 case SOS_SYSCALL_ID_EXIT: !! 051 case SOS_SYSCALL_ID_EXIT:
>> 052 {
>> 053 unsigned int status;
>> 054
>> 055 retval = sos_syscall_get1arg(user_ctxt, & status);
>> 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, TRUE);
>> 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_proc,
>> 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_uaddr;
>> 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) != 1)
>> 116 {
>> 117 retval = -SOS_EBUSY;
>> 118 break;
>> 119 }
>> 120
>> 121
>> 122 retval = sos_syscall_get2args(user_ctxt, & user_str, & len);
>> 123 if (SOS_OK != retval)
>> 124 break;
>> 125
>> 126
>> 127 retval = sos_strndup_from_user(& str, user_str, len + 1, 0);
>> 128 if (SOS_OK != retval)
>> 129 {
>> 130 break;
>> 131 }
>> 132
>> 133
>> 134 new_as = sos_umem_vmm_create_empty_as(proc);
>> 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_as, str);
>> 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 - SOS_DEFAULT_USER_STACK_SIZE)
>> 155 + 1;
>> 156 retval = sos_dev_zero_map(new_as, &ustack, SOS_DEFAULT_USER_STACK_SIZE,
>> 157 SOS_VM_MAP_PROT_READ | SOS_VM_MAP_PROT_WRITE,
>> 158 0);
>> 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_uaddr,
>> 170 0, 0,
>> 171 ustack + SOS_DEFAULT_USER_STACK_SIZE
>> 172 - 4,
>> 173 SOS_SCHED_PRIO_TS_LOWEST);
>> 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(proc,
>> 186 new_as);
>> 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_thread_get_current()->process);
>> 209
>> 210 retval = sos_syscall_get2args(user_ctxt,
>> 211 SYSCALL_VAR32_PTR(start_uaddr),
>> 212 SYSCALL_VAR32_PTR(size));
>> 213 if (SOS_OK != retval)
>> 214 break;
>> 215
>> 216 retval = sos_umem_vmm_unmap(my_as, start_uaddr, size);
>> 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_thread_get_current()->process);
>> 229
>> 230 retval = sos_syscall_get3args(user_ctxt,
>> 231 SYSCALL_VAR32_PTR(start_uaddr),
>> 232 SYSCALL_VAR32_PTR(size),
>> 233 SYSCALL_VAR32_PTR(new_access_rights));
>> 234 if (SOS_OK != retval)
>> 235 break;
>> 236
>> 237 retval = sos_thread_prepare_user_space_access(NULL, (sos_vaddr_t)NULL);
>> 238 if (SOS_OK != retval)
>> 239 break;
>> 240
>> 241 retval = sos_umem_vmm_chprot(my_as, start_uaddr, size,
>> 242 new_access_rights);
>> 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_thread_get_current()->process);
>> 260
>> 261 retval = sos_syscall_get5args(user_ctxt,
>> 262 SYSCALL_VAR32_PTR(old_uaddr),
>> 263 SYSCALL_VAR32_PTR(old_size),
>> 264 SYSCALL_VAR32_PTR(uptr_new_uaddr),
>> 265 SYSCALL_VAR32_PTR(new_size),
>> 266 SYSCALL_VAR32_PTR(flags));
>> 267 if (SOS_OK != retval)
>> 268 break;
>> 269
>> 270 if (sizeof(new_uaddr) != sos_memcpy_from_user((sos_vaddr_t)& new_uaddr,
>> 271 (sos_uaddr_t)
>> 272 uptr_new_uaddr,
>> 273 sizeof(new_uaddr)))
>> 274 {
>> 275 retval = -SOS_EFAULT;
>> 276 break;
>> 277 }
>> 278
>> 279 retval = sos_thread_prepare_user_space_access(NULL, (sos_vaddr_t)NULL);
>> 280 if (SOS_OK != retval)
>> 281 break;
>> 282
>> 283 retval = sos_umem_vmm_resize(my_as, old_uaddr, old_size,
>> 284 & new_uaddr, new_size, flags);
>> 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)uptr_new_uaddr,
>> 291 (sos_vaddr_t)&new_uaddr,
>> 292 sizeof(new_uaddr)))
>> 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_thread_get_current()->process);
>> 309
>> 310 retval = sos_syscall_get3args(user_ctxt,
>> 311 SYSCALL_VAR32_PTR(start_uaddr),
>> 312 SYSCALL_VAR32_PTR(size),
>> 313 SYSCALL_VAR32_PTR(flags));
>> 314 if (SOS_OK != retval)
>> 315 break;
>> 316
>> 317 retval = sos_thread_prepare_user_space_access(NULL, (sos_vaddr_t)NULL);
>> 318 if (SOS_OK != retval)
>> 319 break;
>> 320 retval = sos_umem_vmm_sync(my_as, start_uaddr, size, flags);
>> 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_thread_get_current()->process);
>> 337
>> 338 retval = sos_syscall_get4args(user_ctxt,
>> 339 SYSCALL_VAR32_PTR(start_func),
>> 340 SYSCALL_VAR32_PTR(start_arg1),
>> 341 SYSCALL_VAR32_PTR(start_arg2),
>> 342 SYSCALL_VAR32_PTR(stack_size));
>> 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_size);
>> 355 retval = sos_dev_zero_map(my_as, & stack_uaddr, stack_size,
>> 356 SOS_VM_MAP_PROT_READ | SOS_VM_MAP_PROT_WRITE,
>> 357 0);
>> 358 if (SOS_OK != retval)
>> 359 break;
>> 360
>> 361
>> 362 new_thr = sos_create_user_thread(NULL,
>> 363 sos_thread_get_current()->process,
>> 364 start_func,
>> 365 start_arg1,
>> 366 start_arg2,
>> 367 stack_uaddr + stack_size - 4,
>> 368 SOS_SCHED_PRIO_TS_LOWEST);
>> 369
>> 370 if (! new_thr)
>> 371 {
>> 372 sos_umem_vmm_unmap(my_as, stack_uaddr, stack_size);
>> 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_ctxt,
>> 385 SYSCALL_VAR32_PTR(delay.sec),
>> 386 SYSCALL_VAR32_PTR(delay.nanosec));
>> 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_thread_get_current()->process);
>> 401
>> 402 retval = sos_syscall_get1arg(user_ctxt,
>> 403 SYSCALL_VAR32_PTR(new_top_heap));
>> 404 if (SOS_OK != retval)
>> 405 break;
>> 406
>> 407 retval = sos_thread_prepare_user_space_access(NULL, (sos_vaddr_t)NULL);
>> 408 if (SOS_OK != retval)
>> 409 break;
>> 410
>> 411 retval = sos_umem_vmm_brk(my_as, new_top_heap);
>> 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()->process;
>> 436 retval = sos_syscall_get7args(user_ctxt,
>> 437 SYSCALL_VAR32_PTR(user_src),
>> 438 SYSCALL_VAR32_PTR(srclen),
>> 439 SYSCALL_VAR32_PTR(user_dst),
>> 440 SYSCALL_VAR32_PTR(dstlen),
>> 441 SYSCALL_VAR32_PTR(user_fstype),
>> 442 SYSCALL_VAR32_PTR(mountflags),
>> 443 SYSCALL_VAR32_PTR(user_args));
>> 444 if (SOS_OK != retval)
>> 445 break;
>> 446
>> 447 if (user_src != (sos_uaddr_t)NULL)
>> 448 {
>> 449 retval = sos_strndup_from_user(&kernel_src, user_src, srclen, 0);
>> 450 if (SOS_OK != retval)
>> 451 break;
>> 452 }
>> 453
>> 454 retval = sos_strndup_from_user(&kernel_dst, user_dst, dstlen, 0);
>> 455 if (SOS_OK != retval)
>> 456 {
>> 457 if (kernel_src)
>> 458 sos_kfree((sos_vaddr_t)kernel_src);
>> 459 break;
>> 460 }
>> 461
>> 462 retval = sos_strndup_from_user(& kernel_fstype, user_fstype, 256, 0);
>> 463 if (SOS_OK != retval)
>> 464 {
>> 465 if (kernel_src)
>> 466 sos_kfree((sos_vaddr_t)kernel_src);
>> 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(& kernel_args, user_args, 1024, 0);
>> 474 if (SOS_OK != retval)
>> 475 {
>> 476 if (kernel_src)
>> 477 sos_kfree((sos_vaddr_t)kernel_src);
>> 478 sos_kfree((sos_vaddr_t)kernel_dst);
>> 479 sos_kfree((sos_vaddr_t)kernel_fstype);
>> 480 break;
>> 481 }
>> 482 }
>> 483
>> 484 retval = sos_fs_mount(proc, kernel_src, srclen,
>> 485 kernel_dst, dstlen,
>> 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()->process;
>> 507 retval = sos_syscall_get2args(user_ctxt,
>> 508 SYSCALL_VAR32_PTR(user_str),
>> 509 SYSCALL_VAR32_PTR(len));
>> 510 if (SOS_OK != retval)
>> 511 break;
>> 512
>> 513 retval = sos_strndup_from_user(&path, user_str, len, 0);
>> 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_struct;
>> 536 char * path;
>> 537 struct sos_process * proc;
>> 538
>> 539 proc = sos_thread_get_current()->process;
>> 540 retval = sos_syscall_get3args(user_ctxt,
>> 541 SYSCALL_VAR32_PTR(user_str),
>> 542 SYSCALL_VAR32_PTR(len),
>> 543 SYSCALL_VAR32_PTR(user_vfstat_struct));
>> 544 if (SOS_OK != retval)
>> 545 break;
>> 546
>> 547 retval = sos_strndup_from_user(&path, user_str, len, 0);
>> 548 if (SOS_OK != retval)
>> 549 break;
>> 550
>> 551 retval = sos_fs_vfstat(proc, path, len, & kernel_vfstat_struct);
>> 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_struct,
>> 558 (sos_vaddr_t) & kernel_vfstat_struct,
>> 559 sizeof(kernel_vfstat_struct)))
>> 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()->process;
>> 575 retval = sos_syscall_get4args(user_ctxt,
>> 576 SYSCALL_VAR32_PTR(user_str),
>> 577 SYSCALL_VAR32_PTR(len),
>> 578 SYSCALL_VAR32_PTR(open_flags),
>> 579 SYSCALL_VAR32_PTR(access_rights));
>> 580 if (SOS_OK != retval)
>> 581 break;
>> 582
>> 583 retval = sos_strndup_from_user(&path, user_str, len, 0);
>> 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_file(proc, of);
>> 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()->process;
>> 612 retval = sos_syscall_get1arg(user_ctxt,
>> 613 SYSCALL_VAR32_PTR(fd));
>> 614 if (SOS_OK != retval)
>> 615 break;
>> 616
>> 617 of = sos_process_get_opened_file(proc, fd);
>> 618 if (NULL == of)
>> 619 {
>> 620 retval = -SOS_EBADF;
>> 621 break;
>> 622 }
>> 623
>> 624 retval = sos_process_unregister_opened_file(proc, fd);
>> 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()->process;
>> 642 retval = sos_syscall_get3args(user_ctxt,
>> 643 SYSCALL_VAR32_PTR(fd),
>> 644 SYSCALL_VAR32_PTR(uaddr_buf),
>> 645 SYSCALL_VAR32_PTR(uaddr_buflen));
>> 646 if (SOS_OK != retval)
>> 647 break;
>> 648
>> 649
>> 650 retval = sos_memcpy_from_user((sos_vaddr_t)& kernel_buflen,
>> 651 uaddr_buflen,
>> 652 sizeof(kernel_buflen));
>> 653 if (sizeof(kernel_buflen) != retval)
>> 654 {
>> 655 retval = -SOS_EFAULT;
>> 656 break;
>> 657 }
>> 658
>> 659 of = sos_process_get_opened_file(proc, fd);
>> 660 if (NULL == of)
>> 661 {
>> 662 retval = -SOS_EBADF;
>> 663 break;
>> 664 }
>> 665
>> 666
>> 667 retval = sos_fs_read(of, uaddr_buf, & kernel_buflen);
>> 668
>> 669
>> 670 sos_memcpy_to_user(uaddr_buflen,
>> 671 (sos_vaddr_t)& kernel_buflen,
>> 672 sizeof(kernel_buflen));
>> 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()->process;
>> 685 retval = sos_syscall_get2args(user_ctxt,
>> 686 SYSCALL_VAR32_PTR(fd),
>> 687 SYSCALL_VAR32_PTR(uaddr_direntry));
>> 688 if (SOS_OK != retval)
>> 689 break;
>> 690
>> 691 of = sos_process_get_opened_file(proc, fd);
>> 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_user(uaddr_direntry,
>> 705 (sos_vaddr_t)& direntry,
>> 706 sizeof(direntry)))
>> 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()->process;
>> 721 retval = sos_syscall_get3args(user_ctxt,
>> 722 SYSCALL_VAR32_PTR(fd),
>> 723 SYSCALL_VAR32_PTR(uaddr_buf),
>> 724 SYSCALL_VAR32_PTR(uaddr_buflen));
>> 725 if (SOS_OK != retval)
>> 726 break;
>> 727
>> 728
>> 729 retval = sos_memcpy_from_user((sos_vaddr_t)& kernel_buflen,
>> 730 uaddr_buflen,
>> 731 sizeof(kernel_buflen));
>> 732 if (sizeof(kernel_buflen) != retval)
>> 733 {
>> 734 retval = -SOS_EFAULT;
>> 735 break;
>> 736 }
>> 737
>> 738 of = sos_process_get_opened_file(proc, fd);
>> 739 if (NULL == of)
>> 740 {
>> 741 retval = -SOS_EBADF;
>> 742 break;
>> 743 }
>> 744
>> 745
>> 746 retval = sos_fs_write(of, uaddr_buf, & kernel_buflen);
>> 747
>> 748
>> 749 sos_memcpy_to_user(uaddr_buflen,
>> 750 (sos_vaddr_t)& kernel_buflen,
>> 751 sizeof(kernel_buflen));
>> 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_position;
>> 762 int fd;
>> 763
>> 764 proc = sos_thread_get_current()->process;
>> 765 retval = sos_syscall_get3args(user_ctxt,
>> 766 SYSCALL_VAR32_PTR(fd),
>> 767 SYSCALL_VAR32_PTR(uaddr_offset),
>> 768 SYSCALL_VAR32_PTR(whence));
>> 769 if (SOS_OK != retval)
>> 770 break;
>> 771
>> 772
>> 773 retval = sos_memcpy_from_user((sos_vaddr_t)& kernel_offset,
>> 774 uaddr_offset,
>> 775 sizeof(kernel_offset));
>> 776 if (sizeof(kernel_offset) != retval)
>> 777 {
>> 778 retval = -SOS_EFAULT;
>> 779 break;
>> 780 }
>> 781
>> 782 of = sos_process_get_opened_file(proc, fd);
>> 783 if (NULL == of)
>> 784 {
>> 785 retval = -SOS_EBADF;
>> 786 break;
>> 787 }
>> 788
>> 789
>> 790 retval = sos_fs_seek(of, kernel_offset, whence, & result_position);
>> 791
>> 792
>> 793 sos_memcpy_to_user(uaddr_offset,
>> 794 (sos_vaddr_t)& result_position,
>> 795 sizeof(kernel_offset));
>> 796 }
>> 797 break;
>> 798
>> 799 case SOS_SYSCALL_ID_FTRUNCATE64:
039 { 800 {
040 unsigned int status; !! 801 struct sos_fs_opened_file * of;
041 retval = sos_syscall_get1arg(user_ctxt !! 802 struct sos_process * proc;
>> 803 sos_lsoffset_t length;
>> 804 int fd;
>> 805
>> 806 proc = sos_thread_get_current()->process;
>> 807 retval = sos_syscall_get2args(user_ctxt,
>> 808 SYSCALL_VAR32_PTR(fd),
>> 809 SYSCALL_VAR32_PTR(length));
042 if (SOS_OK != retval) 810 if (SOS_OK != retval)
043 break; 811 break;
044 sos_thread_exit(); !! 812
045 retval = -SOS_EFATAL; !! 813 of = sos_process_get_opened_file(proc, fd);
>> 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()->process;
>> 840 retval = sos_syscall_get7args(user_ctxt,
>> 841 SYSCALL_VAR32_PTR(ptr_hint_uaddr),
>> 842 SYSCALL_VAR32_PTR(length),
>> 843 SYSCALL_VAR32_PTR(prot),
>> 844 SYSCALL_VAR32_PTR(flags),
>> 845 SYSCALL_VAR32_PTR(fd),
>> 846 SYSCALL_VAR32_PTR(offs64_hi),
>> 847 SYSCALL_VAR32_PTR(offs64_lo));
>> 848 if (SOS_OK != retval)
>> 849 break;
>> 850
>> 851 of = sos_process_get_opened_file(proc, fd);
>> 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_vaddr_t)& hint_uaddr,
>> 864 ptr_hint_uaddr,
>> 865 sizeof(hint_uaddr));
>> 866 if (sizeof(hint_uaddr) != retval)
>> 867 {
>> 868 retval = -SOS_EFAULT;
>> 869 break;
>> 870 }
>> 871
>> 872 retval = sos_fs_mmap(of, & hint_uaddr, length, prot, flags,
>> 873 offset_in_resource);
>> 874 if (SOS_OK == retval)
>> 875 {
>> 876 if (sizeof(hint_uaddr)
>> 877 != sos_memcpy_to_user(ptr_hint_uaddr,
>> 878 (sos_vaddr_t)& hint_uaddr,
>> 879 sizeof(hint_uaddr)))
>> 880 {
>> 881 sos_umem_vmm_unmap(sos_process_get_address_space(proc),
>> 882 hint_uaddr, length);
>> 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()->process;
>> 897 retval = sos_syscall_get1arg(user_ctxt,
>> 898 SYSCALL_VAR32_PTR(fd));
>> 899 if (SOS_OK != retval)
>> 900 break;
>> 901
>> 902 of = sos_process_get_opened_file(proc, fd);
>> 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()->process;
>> 922 retval = sos_syscall_get3args(user_ctxt,
>> 923 SYSCALL_VAR32_PTR(fd),
>> 924 SYSCALL_VAR32_PTR(cmd),
>> 925 SYSCALL_VAR32_PTR(arg));
>> 926 if (SOS_OK != retval)
>> 927 break;
>> 928
>> 929 of = sos_process_get_opened_file(proc, fd);
>> 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()->process;
>> 949 retval = sos_syscall_get3args(user_ctxt,
>> 950 SYSCALL_VAR32_PTR(fd),
>> 951 SYSCALL_VAR32_PTR(cmd),
>> 952 SYSCALL_VAR32_PTR(arg));
>> 953 if (SOS_OK != retval)
>> 954 break;
>> 955
>> 956 of = sos_process_get_opened_file(proc, fd);
>> 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()->process;
>> 977 retval = sos_syscall_get3args(user_ctxt,
>> 978 SYSCALL_VAR32_PTR(user_str),
>> 979 SYSCALL_VAR32_PTR(len),
>> 980 SYSCALL_VAR32_PTR(access_rights));
>> 981 if (SOS_OK != retval)
>> 982 break;
>> 983
>> 984 retval = sos_strndup_from_user(&path, user_str, len, 0);
>> 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_newpath;
>> 1001 struct sos_process * proc;
>> 1002
>> 1003 proc = sos_thread_get_current()->process;
>> 1004 retval = sos_syscall_get4args(user_ctxt,
>> 1005 SYSCALL_VAR32_PTR(user_oldpath),
>> 1006 SYSCALL_VAR32_PTR(oldpathlen),
>> 1007 SYSCALL_VAR32_PTR(user_newpath),
>> 1008 SYSCALL_VAR32_PTR(newpathlen));
>> 1009 if (SOS_OK != retval)
>> 1010 break;
>> 1011
>> 1012 retval = sos_strndup_from_user(&kernel_oldpath,
>> 1013 user_oldpath,
>> 1014 oldpathlen, 0);
>> 1015 if (SOS_OK != retval)
>> 1016 break;
>> 1017
>> 1018 retval = sos_strndup_from_user(&kernel_newpath,
>> 1019 user_newpath,
>> 1020 newpathlen, 0);
>> 1021 if (SOS_OK != retval)
>> 1022 {
>> 1023 sos_kfree((sos_vaddr_t) kernel_oldpath);
>> 1024 break;
>> 1025 }
>> 1026
>> 1027 if (syscall_id == SOS_SYSCALL_ID_LINK)
>> 1028 retval = sos_fs_link(proc,
>> 1029 kernel_oldpath, oldpathlen,
>> 1030 kernel_newpath, newpathlen);
>> 1031 else
>> 1032 retval = sos_fs_rename(proc,
>> 1033 kernel_oldpath, oldpathlen,
>> 1034 kernel_newpath, newpathlen);
>> 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()->process;
>> 1048 retval = sos_syscall_get2args(user_ctxt,
>> 1049 SYSCALL_VAR32_PTR(user_str),
>> 1050 SYSCALL_VAR32_PTR(len));
>> 1051 if (SOS_OK != retval)
>> 1052 break;
>> 1053
>> 1054 retval = sos_strndup_from_user(&path, user_str, len, 0);
>> 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_targetpath;
>> 1067 sos_size_t pathlen, targetpathlen;
>> 1068 char * kernel_path;
>> 1069 struct sos_process * proc;
>> 1070
>> 1071 proc = sos_thread_get_current()->process;
>> 1072 retval = sos_syscall_get4args(user_ctxt,
>> 1073 SYSCALL_VAR32_PTR(user_path),
>> 1074 SYSCALL_VAR32_PTR(pathlen),
>> 1075 SYSCALL_VAR32_PTR(user_targetpath),
>> 1076 SYSCALL_VAR32_PTR(targetpathlen));
>> 1077 if (SOS_OK != retval)
>> 1078 break;
>> 1079
>> 1080 retval = sos_strndup_from_user(&kernel_path,
>> 1081 user_path,
>> 1082 pathlen, 0);
>> 1083 if (SOS_OK != retval)
>> 1084 break;
>> 1085
>> 1086 retval = sos_fs_symlink(proc,
>> 1087 kernel_path, pathlen,
>> 1088 user_targetpath, targetpathlen);
>> 1089 sos_kfree((sos_vaddr_t)kernel_path);
046 } 1090 }
047 break; 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()->process;
>> 1104 retval = sos_syscall_get6args(user_ctxt,
>> 1105 SYSCALL_VAR32_PTR(user_str),
>> 1106 SYSCALL_VAR32_PTR(len),
>> 1107 SYSCALL_VAR32_PTR(type),
>> 1108 SYSCALL_VAR32_PTR(access_rights),
>> 1109 SYSCALL_VAR32_PTR(dev_id.device_class),
>> 1110 SYSCALL_VAR32_PTR(dev_id.device_instance));
>> 1111 if (SOS_OK != retval)
>> 1112 break;
>> 1113
>> 1114 retval = sos_strndup_from_user(&path, user_str, len, 0);
>> 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, len, access_rights);
>> 1122 break;
>> 1123
>> 1124 case SOS_FS_NODE_DIRECTORY:
>> 1125 retval = sos_fs_mkdir(proc, path, len, access_rights);
>> 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, type, access_rights, &dev_id);
>> 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()->process;
>> 1156 retval = sos_syscall_get3args(user_ctxt,
>> 1157 SYSCALL_VAR32_PTR(user_str),
>> 1158 SYSCALL_VAR32_PTR(len),
>> 1159 SYSCALL_VAR32_PTR(access_rights));
>> 1160 if (SOS_OK != retval)
>> 1161 break;
>> 1162
>> 1163 retval = sos_strndup_from_user(&path, user_str, len, 0);
>> 1164 if (SOS_OK != retval)
>> 1165 break;
>> 1166
>> 1167 retval = sos_fs_mkdir(proc,
>> 1168 path, len, access_rights);
>> 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()->process;
>> 1181 retval = sos_syscall_get2args(user_ctxt,
>> 1182 SYSCALL_VAR32_PTR(user_str),
>> 1183 SYSCALL_VAR32_PTR(len));
>> 1184 if (SOS_OK != retval)
>> 1185 break;
>> 1186
>> 1187 retval = sos_strndup_from_user(&path, user_str, len, 0);
>> 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()->process;
>> 1205 retval = sos_syscall_get3args(user_ctxt,
>> 1206 SYSCALL_VAR32_PTR(user_str),
>> 1207 SYSCALL_VAR32_PTR(len),
>> 1208 SYSCALL_VAR32_PTR(access_rights));
>> 1209 if (SOS_OK != retval)
>> 1210 break;
>> 1211
>> 1212 retval = sos_strndup_from_user(&path, user_str, len, 0);
>> 1213 if (SOS_OK != retval)
>> 1214 break;
>> 1215
>> 1216 retval = sos_fs_chmod(proc, path, len, access_rights);
>> 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()->process;
>> 1232 retval = sos_syscall_get4args(user_ctxt,
>> 1233 SYSCALL_VAR32_PTR(user_str),
>> 1234 SYSCALL_VAR32_PTR(len),
>> 1235 SYSCALL_VAR32_PTR(nofollow),
>> 1236 SYSCALL_VAR32_PTR(user_stat_struct));
>> 1237 if (SOS_OK != retval)
>> 1238 break;
>> 1239
>> 1240 retval = sos_strndup_from_user(&path, user_str, len, 0);
>> 1241 if (SOS_OK != retval)
>> 1242 break;
>> 1243
>> 1244 retval = sos_fs_stat(proc, path, len, nofollow, & kernel_stat_struct);
>> 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_struct,
>> 1251 (sos_vaddr_t) & kernel_stat_struct,
>> 1252 sizeof(kernel_stat_struct)))
>> 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_of;
>> 1264 struct sos_process * proc;
>> 1265
>> 1266 proc = sos_thread_get_current()->process;
>> 1267 retval = sos_syscall_get2args(user_ctxt,
>> 1268 SYSCALL_VAR32_PTR(user_str),
>> 1269 SYSCALL_VAR32_PTR(len));
>> 1270 if (SOS_OK != retval)
>> 1271 break;
>> 1272
>> 1273 retval = sos_strndup_from_user(&path, user_str, len, 0);
>> 1274 if (SOS_OK != retval)
>> 1275 break;
>> 1276
>> 1277 retval = sos_fs_open(proc,
>> 1278 path, len,
>> 1279 SOS_FS_OPEN_DIRECTORY,
>> 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_CHROOT)
>> 1287 retval = sos_process_chroot(proc, of, & old_of);
>> 1288 else
>> 1289 retval = sos_process_chdir(proc, of, & old_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
>> 1301 case SOS_SYSCALL_ID_FCHDIR:
>> 1302 {
>> 1303 struct sos_fs_opened_file * of, * new_of, * old_of;
>> 1304 struct sos_process * proc;
>> 1305 int fd;
>> 1306
>> 1307 proc = sos_thread_get_current()->process;
>> 1308 retval = sos_syscall_get1arg(user_ctxt,
>> 1309 SYSCALL_VAR32_PTR(fd));
>> 1310 if (SOS_OK != retval)
>> 1311 break;
>> 1312
>> 1313 of = sos_process_get_opened_file(proc, fd);
>> 1314 if (NULL == of)
>> 1315 {
>> 1316 retval = -SOS_EBADF;
>> 1317 break;
>> 1318 }
>> 1319
>> 1320
>> 1321 retval = sos_fs_duplicate_opened_file(of, proc, & new_of);
>> 1322 if (SOS_OK != retval)
>> 1323 break;
>> 1324
>> 1325
>> 1326 retval = sos_process_chdir(proc, new_of, & old_of);
>> 1327 if (retval < 0)
>> 1328 {
>> 1329 sos_fs_close(new_of);
>> 1330 break;
>> 1331 }
>> 1332
>> 1333 sos_fs_close(old_of);
>> 1334 }
>> 1335 break;
>> 1336
048 case SOS_SYSCALL_ID_BOCHS_WRITE: 1337 case SOS_SYSCALL_ID_BOCHS_WRITE:
049 { 1338 {
050 sos_uaddr_t user_str; 1339 sos_uaddr_t user_str;
051 sos_size_t len; 1340 sos_size_t len;
052 char * str; 1341 char * str;
053 retval = sos_syscall_get2args(user_ctx 1342 retval = sos_syscall_get2args(user_ctxt, & user_str, & len);
054 if (SOS_OK != retval) 1343 if (SOS_OK != retval)
055 break; 1344 break;
056 1345
057 str = (char*)sos_kmalloc(len + 1, 0); !! 1346 retval = sos_strndup_from_user(& str, user_str, len + 1, 0);
058 if (str) !! 1347 if (SOS_OK == retval)
059 { 1348 {
060 retval = sos_strzcpy_from_user(str !! 1349 sos_bochs_printf("THR 0x%x: ",
061 str[len] = '\0'; !! 1350 (unsigned)sos_thread_get_current());
062 if (SOS_OK == retval) !! 1351 retval = sos_bochs_putstring(str);
063 { !! 1352 retval = len;
064 sos_bochs_printf("THR 0x%x: ", <<
065 (unsigned)sos <<
066 retval = sos_bochs_putstring(s <<
067 retval = len; <<
068 } <<
069 sos_kfree((sos_vaddr_t)str); 1353 sos_kfree((sos_vaddr_t)str);
070 } 1354 }
071 else <<
072 retval = -SOS_ENOMEM; <<
073 } 1355 }
074 break; 1356 break;
075 1357
076 1358
077 1359
078 1360
079 1361
080 1362
081 1363
082 1364
083 1365
084 1366
085 1367
086 case 4012: 1368 case 4012:
087 { 1369 {
088 sos_uaddr_t user_str; 1370 sos_uaddr_t user_str;
089 unsigned int len; 1371 unsigned int len;
090 unsigned char * str; 1372 unsigned char * str;
091 1373
092 retval = sos_syscall_get2args(user_ctx 1374 retval = sos_syscall_get2args(user_ctxt, & user_str, & len);
093 if (SOS_OK != retval) 1375 if (SOS_OK != retval)
094 break; 1376 break;
095 1377
096 str = (char*)sos_kmalloc(len + 1, 0); !! 1378 str = (unsigned char*)sos_kmalloc(len, 0);
097 if (str) 1379 if (str)
098 { 1380 {
099 int i; !! 1381 sos_bochs_printf("THR %p, Hexdump(0x%x, %d):\n",
100 sos_bochs_printf("Hexdump(0x%x, %d !! 1382 sos_thread_get_current(), user_str, len);
101 retval = sos_memcpy_from_user((sos 1383 retval = sos_memcpy_from_user((sos_vaddr_t) str, user_str, len);
102 sos_bochs_printf(" (Successfully 1384 sos_bochs_printf(" (Successfully copied %d out of %d)\n",
103 retval, len); 1385 retval, len);
104 !! 1386 if (retval > 0)
105 for (i = 0 ; i < retval ; i++) !! 1387 sos_bochs_hexdump(str, retval);
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"); <<
115 1388
116 sos_kfree((sos_vaddr_t)str); 1389 sos_kfree((sos_vaddr_t)str);
117 } 1390 }
118 else 1391 else
119 retval = -SOS_ENOMEM; 1392 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_ctxt, & ustr);
>> 1408 if (SOS_OK != retval)
>> 1409 break;
>> 1410
>> 1411 retval = sos_strndup_from_user(& kstr, ustr, 256, 0);
>> 1412 if (SOS_OK != retval)
>> 1413 break;
>> 1414
>> 1415 extern void sos_dump_as(const struct sos_umem_vmm_as *, const char *);
>> 1416 my_as
>> 1417 = sos_process_get_address_space(sos_thread_get_current()->process);
>> 1418 sos_dump_as(my_as, kstr);
>> 1419 sos_kfree((sos_vaddr_t)kstr);
120 } 1420 }
121 break; 1421 break;
122 1422
123 1423
124 1424
125 1425
126 1426
127 1427
128 case 4008: 1428 case 4008:
129 { 1429 {
130 extern void sos_process_dumplist(void) 1430 extern void sos_process_dumplist(void);
131 sos_process_dumplist(); 1431 sos_process_dumplist();
132 retval = SOS_OK; 1432 retval = SOS_OK;
133 } 1433 }
134 break; 1434 break;
135 1435
136 default: 1436 default:
137 sos_bochs_printf("Syscall: UNKNOWN[%d]\n 1437 sos_bochs_printf("Syscall: UNKNOWN[%d]\n", syscall_id);
138 retval = -SOS_ENOSUP; 1438 retval = -SOS_ENOSUP;
139 } 1439 }
140 1440
141 return retval; 1441 return retval;
142 } 1442 }