SimpleOS

LXR

Navigation



Site hébergé par : enix

The LXR Cross Referencer for SOS

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Article:1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 6.5 ] [ 7 ] [ 7.5 ] [ 8 ] [ 9 ] [ 9.5 ]

Diff markup

Differences between /sos/syscall.c (Article 7) and /sos/syscall.c (Article 8)


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

source navigation ] diff markup ] identifier search ] general search ]