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 9) and /sos/syscall.c (Article 7.5)


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

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