Diff markup
001 001
002 002
003 003
004 004
005 005
006 006
007 007
008 008
009 009
010 010
011 011
012 012
013 013
014 014
015 015
016 016
017 017
018 #include <sos/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 <<
034 033
035 034
036 035
037 sos_ret_t sos_do_syscall(int syscall_id, 036 sos_ret_t sos_do_syscall(int syscall_id,
038 const struct sos_cpu_ 037 const struct sos_cpu_state *user_ctxt)
039 { 038 {
040 sos_ret_t retval; 039 sos_ret_t retval;
041 040
042 switch(syscall_id) 041 switch(syscall_id)
043 { 042 {
044 case SOS_SYSCALL_ID_EXIT: 043 case SOS_SYSCALL_ID_EXIT:
045 { 044 {
046 unsigned int status; 045 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; 051 retval = -SOS_EFATAL;
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 062
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 070
071 071
072 072
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 087
088 088
089 089
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;
097 struct sos_umem_vmm_as *new_as; 098 struct sos_umem_vmm_as *new_as;
098 sos_uaddr_t user_str, ustack, start_ua 099 sos_uaddr_t user_str, ustack, start_uaddr;
099 sos_size_t len; 100 sos_size_t len;
100 char * str; 101 char * str;
101 102
102 cur_thr = sos_thread_get_current(); 103 cur_thr = sos_thread_get_current();
>> 104 proc = cur_thr->process;
103 105
104 106
105 if (sos_process_get_nb_threads(cur_thr !! 107 if (sos_process_get_nb_threads(proc) != 1)
106 { 108 {
107 retval = -SOS_EBUSY; 109 retval = -SOS_EBUSY;
108 break; 110 break;
109 } 111 }
110 112
111 113
112 retval = sos_syscall_get2args(user_ctx 114 retval = sos_syscall_get2args(user_ctxt, & user_str, & len);
113 if (SOS_OK != retval) 115 if (SOS_OK != retval)
114 break; 116 break;
115 117
116 118
117 str = (char*)sos_kmalloc(len + 1, 0); !! 119 retval = sos_strndup_from_user(& str, user_str, len + 1, 0);
118 if (! str) !! 120 if (SOS_OK != retval)
119 { <<
120 retval = -SOS_ENOMEM; <<
121 break; <<
122 } <<
123 retval = sos_strzcpy_from_user(str, us <<
124 if (retval < SOS_OK) <<
125 { 121 {
126 sos_kfree((sos_vaddr_t)str); <<
127 break; 122 break;
128 } 123 }
129 124
130 125
131 new_as = sos_umem_vmm_create_empty_as( !! 126 new_as = sos_umem_vmm_create_empty_as(proc);
132 if (! new_as) 127 if (! new_as)
133 { 128 {
134 sos_kfree((sos_vaddr_t)str); 129 sos_kfree((sos_vaddr_t)str);
135 retval = -SOS_ENOMEM; 130 retval = -SOS_ENOMEM;
136 break; 131 break;
137 } 132 }
138 133
139 134
140 start_uaddr = sos_binfmt_elf32_map(new 135 start_uaddr = sos_binfmt_elf32_map(new_as, str);
141 if (start_uaddr == (sos_uaddr_t)NULL) 136 if (start_uaddr == (sos_uaddr_t)NULL)
142 { 137 {
143 sos_umem_vmm_delete_as(new_as); 138 sos_umem_vmm_delete_as(new_as);
144 sos_kfree((sos_vaddr_t)str); 139 sos_kfree((sos_vaddr_t)str);
145 retval = -SOS_ENOENT; 140 retval = -SOS_ENOENT;
146 break; 141 break;
147 } 142 }
148 143
149 144
150 #define SOS_DEFAULT_USER_STACK_SIZE (8 << 20) 145 #define SOS_DEFAULT_USER_STACK_SIZE (8 << 20)
151 ustack = (SOS_PAGING_TOP_USER_ADDRESS 146 ustack = (SOS_PAGING_TOP_USER_ADDRESS - SOS_DEFAULT_USER_STACK_SIZE)
152 + 1; 147 + 1;
153 retval = sos_dev_zero_map(new_as, &ust 148 retval = sos_dev_zero_map(new_as, &ustack, SOS_DEFAULT_USER_STACK_SIZE,
154 SOS_VM_MAP_P 149 SOS_VM_MAP_PROT_READ | SOS_VM_MAP_PROT_WRITE,
155 150 0);
156 if (SOS_OK != retval) 151 if (SOS_OK != retval)
157 { 152 {
158 sos_umem_vmm_delete_as(new_as); 153 sos_umem_vmm_delete_as(new_as);
159 sos_kfree((sos_vaddr_t)str); 154 sos_kfree((sos_vaddr_t)str);
160 break; 155 break;
161 } 156 }
162 157
163 158
164 new_thr = sos_create_user_thread(NULL, 159 new_thr = sos_create_user_thread(NULL,
165 cur_t !! 160 proc,
166 start 161 start_uaddr,
167 0, 0, 162 0, 0,
168 ustac 163 ustack + SOS_DEFAULT_USER_STACK_SIZE
169 - 4 164 - 4,
170 SOS_S 165 SOS_SCHED_PRIO_TS_LOWEST);
171 if (! new_thr) 166 if (! new_thr)
172 { 167 {
173 sos_umem_vmm_delete_as(new_as); 168 sos_umem_vmm_delete_as(new_as);
174 sos_kfree((sos_vaddr_t)str); 169 sos_kfree((sos_vaddr_t)str);
175 retval = -SOS_ENOMEM; 170 retval = -SOS_ENOMEM;
176 break; 171 break;
177 } 172 }
178 173
179 sos_process_set_name(cur_thr->process, !! 174 sos_process_set_name(proc, str);
180 175
181 176
182 retval = sos_process_set_address_space !! 177 retval = sos_process_set_address_space(proc,
183 178 new_as);
184 if (SOS_OK != retval) 179 if (SOS_OK != retval)
185 { 180 {
186 sos_umem_vmm_delete_as(new_as); 181 sos_umem_vmm_delete_as(new_as);
187 sos_kfree((sos_vaddr_t)str); 182 sos_kfree((sos_vaddr_t)str);
188 break; 183 break;
189 } 184 }
190 185
191 186
192 sos_kfree((sos_vaddr_t)str); 187 sos_kfree((sos_vaddr_t)str);
193 sos_thread_exit(); 188 sos_thread_exit();
194 retval = -SOS_EFATAL; 189 retval = -SOS_EFATAL;
195 } 190 }
196 break; 191 break;
197 192
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_ctx <<
213 (unsigne <<
214 (unsigne <<
215 (unsigne <<
216 (unsigne <<
217 (unsigne <<
218 (unsigne <<
219 (unsigne <<
220 if (SOS_OK != retval) <<
221 break; <<
222 <<
223 <<
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_vad <<
229 ptr_hint <<
230 sizeof(h <<
231 if (sizeof(hint_uaddr) != retval) <<
232 { <<
233 retval = -SOS_EFAULT; <<
234 break; <<
235 } <<
236 <<
237 retval = sos_strzcpy_from_user(name, n <<
238 if (SOS_OK != retval) <<
239 break; <<
240 <<
241 my_as <<
242 = sos_process_get_address_space(sos_ <<
243 if ( (0 == strncmp(name, "/dev/zero", <<
244 || (0 == strncmp(name, "/dev/null <<
245 retval = sos_dev_zero_map(my_as, & h <<
246 else if (0 == strncmp(name, "/dev/mem" <<
247 retval = sos_dev_physmem_map(my_as, <<
248 offset_ <<
249 else if (0 == strncmp(name, "/dev/kmem <<
250 retval = sos_dev_kmem_map(my_as, & h <<
251 offset_in_ <<
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 <<
259 (sos_vad <<
260 sizeof(h <<
261 { <<
262 sos_umem_vmm_unmap(my_as, hint <<
263 retval = -SOS_EFAULT; <<
264 } <<
265 } <<
266 <<
267 } <<
268 break; <<
269 <<
270 case SOS_SYSCALL_ID_MUNMAP: 193 case SOS_SYSCALL_ID_MUNMAP:
271 { 194 {
272 sos_uaddr_t start_uaddr; 195 sos_uaddr_t start_uaddr;
273 sos_size_t size; 196 sos_size_t size;
274 struct sos_umem_vmm_as * my_as; 197 struct sos_umem_vmm_as * my_as;
275 198
276 my_as 199 my_as
277 = sos_process_get_address_space(sos_ 200 = sos_process_get_address_space(sos_thread_get_current()->process);
278 201
279 retval = sos_syscall_get2args(user_ctx 202 retval = sos_syscall_get2args(user_ctxt,
280 (unsigne 203 (unsigned int*)& start_uaddr,
281 (unsigne 204 (unsigned int*)& size);
282 if (SOS_OK != retval) 205 if (SOS_OK != retval)
283 break; 206 break;
284 207
285 retval = sos_umem_vmm_unmap(my_as, sta 208 retval = sos_umem_vmm_unmap(my_as, start_uaddr, size);
286 } 209 }
287 break; 210 break;
288 211
289 case SOS_SYSCALL_ID_MPROTECT: 212 case SOS_SYSCALL_ID_MPROTECT:
290 { 213 {
291 sos_uaddr_t start_uaddr; 214 sos_uaddr_t start_uaddr;
292 sos_size_t size; 215 sos_size_t size;
293 sos_ui32_t new_access_rights; 216 sos_ui32_t new_access_rights;
294 struct sos_umem_vmm_as * my_as; 217 struct sos_umem_vmm_as * my_as;
295 218
296 my_as 219 my_as
297 = sos_process_get_address_space(sos_ 220 = sos_process_get_address_space(sos_thread_get_current()->process);
298 221
299 retval = sos_syscall_get3args(user_ctx 222 retval = sos_syscall_get3args(user_ctxt,
300 (unsigne 223 (unsigned int*)& start_uaddr,
301 (unsigne 224 (unsigned int*)& size,
302 (unsigne 225 (unsigned int*)& new_access_rights);
303 if (SOS_OK != retval) 226 if (SOS_OK != retval)
304 break; 227 break;
305 228
306 retval = sos_thread_prepare_user_space 229 retval = sos_thread_prepare_user_space_access(NULL, (sos_vaddr_t)NULL);
307 if (SOS_OK != retval) 230 if (SOS_OK != retval)
308 break; 231 break;
309 232
310 retval = sos_umem_vmm_chprot(my_as, st 233 retval = sos_umem_vmm_chprot(my_as, start_uaddr, size,
311 new_acces 234 new_access_rights);
312 235
313 sos_thread_end_user_space_access(); 236 sos_thread_end_user_space_access();
314 } 237 }
315 break; 238 break;
316 239
317 case SOS_SYSCALL_ID_MRESIZE: 240 case SOS_SYSCALL_ID_MRESIZE:
318 { 241 {
319 sos_uaddr_t old_uaddr; 242 sos_uaddr_t old_uaddr;
320 sos_size_t old_size; 243 sos_size_t old_size;
321 sos_uaddr_t *uptr_new_uaddr; 244 sos_uaddr_t *uptr_new_uaddr;
322 sos_uaddr_t new_uaddr; 245 sos_uaddr_t new_uaddr;
323 sos_size_t new_size; 246 sos_size_t new_size;
324 sos_ui32_t flags; 247 sos_ui32_t flags;
325 struct sos_umem_vmm_as * my_as; 248 struct sos_umem_vmm_as * my_as;
326 249
327 my_as 250 my_as
328 = sos_process_get_address_space(sos_ 251 = sos_process_get_address_space(sos_thread_get_current()->process);
329 252
330 retval = sos_syscall_get5args(user_ctx 253 retval = sos_syscall_get5args(user_ctxt,
331 (unsigne 254 (unsigned int*)& old_uaddr,
332 (unsigne 255 (unsigned int*)& old_size,
333 (unsigne 256 (unsigned int*)& uptr_new_uaddr,
334 (unsigne 257 (unsigned int*)& new_size,
335 (unsigne 258 (unsigned int*)& flags);
336 if (SOS_OK != retval) 259 if (SOS_OK != retval)
337 break; 260 break;
338 261
339 if (sizeof(new_uaddr) != sos_memcpy_fr 262 if (sizeof(new_uaddr) != sos_memcpy_from_user((sos_vaddr_t)& new_uaddr,
340 263 (sos_uaddr_t)
341 264 uptr_new_uaddr,
342 265 sizeof(new_uaddr)))
343 { 266 {
344 retval = -SOS_EFAULT; 267 retval = -SOS_EFAULT;
345 break; 268 break;
346 } 269 }
347 270
348 retval = sos_thread_prepare_user_space 271 retval = sos_thread_prepare_user_space_access(NULL, (sos_vaddr_t)NULL);
349 if (SOS_OK != retval) 272 if (SOS_OK != retval)
350 break; 273 break;
351 274
352 retval = sos_umem_vmm_resize(my_as, ol 275 retval = sos_umem_vmm_resize(my_as, old_uaddr, old_size,
353 & new_uad 276 & new_uaddr, new_size, flags);
354 sos_thread_end_user_space_access(); 277 sos_thread_end_user_space_access();
355 if (SOS_OK != retval) 278 if (SOS_OK != retval)
356 break; 279 break;
357 280
358 if (sizeof(new_uaddr) 281 if (sizeof(new_uaddr)
359 == sos_memcpy_to_user((sos_uaddr_t 282 == sos_memcpy_to_user((sos_uaddr_t)uptr_new_uaddr,
360 (sos_vaddr_t 283 (sos_vaddr_t)&new_uaddr,
361 sizeof(new_u 284 sizeof(new_uaddr)))
362 { 285 {
363 retval = -SOS_EFAULT; 286 retval = -SOS_EFAULT;
364 break; 287 break;
365 } 288 }
366 } 289 }
367 break; 290 break;
368 291
369 case SOS_SYSCALL_ID_NEW_THREAD: 292 case SOS_SYSCALL_ID_NEW_THREAD:
370 { 293 {
371 sos_uaddr_t start_func; 294 sos_uaddr_t start_func;
372 sos_ui32_t start_arg1, start_arg2; 295 sos_ui32_t start_arg1, start_arg2;
373 sos_size_t stack_size; 296 sos_size_t stack_size;
374 sos_uaddr_t stack_uaddr; 297 sos_uaddr_t stack_uaddr;
375 298
376 struct sos_thread * new_thr; 299 struct sos_thread * new_thr;
377 struct sos_umem_vmm_as * my_as; 300 struct sos_umem_vmm_as * my_as;
378 301
379 my_as 302 my_as
380 = sos_process_get_address_space(sos_ 303 = sos_process_get_address_space(sos_thread_get_current()->process);
381 304
382 retval = sos_syscall_get4args(user_ctx 305 retval = sos_syscall_get4args(user_ctxt,
383 (unsigne 306 (unsigned int*)& start_func,
384 (unsigne 307 (unsigned int*)& start_arg1,
385 (unsigne 308 (unsigned int*)& start_arg2,
386 (unsigne 309 (unsigned int*)& stack_size);
387 if (SOS_OK != retval) 310 if (SOS_OK != retval)
388 break; 311 break;
389 312
390 if (stack_size <= 0) 313 if (stack_size <= 0)
391 { 314 {
392 retval = -SOS_EINVAL; 315 retval = -SOS_EINVAL;
393 break; 316 break;
394 } 317 }
395 318
396 319
397 stack_uaddr = 0; 320 stack_uaddr = 0;
398 stack_size = SOS_PAGE_ALIGN_SUP(stack_ 321 stack_size = SOS_PAGE_ALIGN_SUP(stack_size);
399 retval = sos_dev_zero_map(my_as, & sta 322 retval = sos_dev_zero_map(my_as, & stack_uaddr, stack_size,
400 SOS_VM_MAP_P 323 SOS_VM_MAP_PROT_READ | SOS_VM_MAP_PROT_WRITE,
401 324 0);
402 if (SOS_OK != retval) 325 if (SOS_OK != retval)
403 break; 326 break;
404 327
405 328
406 new_thr = sos_create_user_thread(NULL, 329 new_thr = sos_create_user_thread(NULL,
407 sos_t 330 sos_thread_get_current()->process,
408 start 331 start_func,
409 start 332 start_arg1,
410 start 333 start_arg2,
411 stack 334 stack_uaddr + stack_size - 4,
412 SOS_S 335 SOS_SCHED_PRIO_TS_LOWEST);
413 336
414 if (! new_thr) 337 if (! new_thr)
415 { 338 {
416 sos_umem_vmm_unmap(my_as, stack_ua 339 sos_umem_vmm_unmap(my_as, stack_uaddr, stack_size);
417 retval = -SOS_ENOMEM; 340 retval = -SOS_ENOMEM;
418 break; 341 break;
419 } 342 }
>> 343
420 } 344 }
421 break; 345 break;
422 346
423 case SOS_SYSCALL_ID_NANOSLEEP: 347 case SOS_SYSCALL_ID_NANOSLEEP:
424 { 348 {
425 struct sos_time delay; 349 struct sos_time delay;
426 350
427 retval = sos_syscall_get2args(user_ctx 351 retval = sos_syscall_get2args(user_ctxt,
428 (unsigne 352 (unsigned int*)& delay.sec,
429 (unsigne 353 (unsigned int*)& delay.nanosec);
430 if (SOS_OK != retval) 354 if (SOS_OK != retval)
431 break; 355 break;
432 356
433 retval = sos_thread_sleep(& delay); 357 retval = sos_thread_sleep(& delay);
434 } 358 }
435 break; 359 break;
436 360
437 case SOS_SYSCALL_ID_BRK: 361 case SOS_SYSCALL_ID_BRK:
438 { 362 {
439 sos_uaddr_t new_top_heap; 363 sos_uaddr_t new_top_heap;
440 struct sos_umem_vmm_as * my_as; 364 struct sos_umem_vmm_as * my_as;
441 365
442 my_as 366 my_as
443 = sos_process_get_address_space(sos_ 367 = sos_process_get_address_space(sos_thread_get_current()->process);
444 368
445 retval = sos_syscall_get1arg(user_ctxt 369 retval = sos_syscall_get1arg(user_ctxt,
446 (unsigned 370 (unsigned int*)& new_top_heap);
447 if (SOS_OK != retval) 371 if (SOS_OK != retval)
448 break; 372 break;
449 373
450 retval = sos_thread_prepare_user_space 374 retval = sos_thread_prepare_user_space_access(NULL, (sos_vaddr_t)NULL);
451 if (SOS_OK != retval) 375 if (SOS_OK != retval)
452 break; 376 break;
453 377
454 retval = sos_umem_vmm_brk(my_as, new_t 378 retval = sos_umem_vmm_brk(my_as, new_top_heap);
455 sos_thread_end_user_space_access(); 379 sos_thread_end_user_space_access();
456 } 380 }
457 break; 381 break;
458 382
459 case SOS_SYSCALL_ID_BOCHS_WRITE: !! 383
>> 384
>> 385
>> 386
>> 387 case SOS_SYSCALL_ID_MOUNT:
460 { 388 {
461 sos_uaddr_t user_str; !! 389 sos_uaddr_t user_src;
462 sos_size_t len; !! 390 sos_size_t srclen;
463 char * str; !! 391 char * kernel_src = NULL;
464 retval = sos_syscall_get2args(user_ctx !! 392 sos_uaddr_t user_dst;
>> 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()->process;
>> 403 retval = sos_syscall_get7args(user_ctxt,
>> 404 (unsigned int*)& user_src,
>> 405 (unsigned int*)& srclen,
>> 406 (unsigned int*)& user_dst,
>> 407 (unsigned int*)& dstlen,
>> 408 (unsigned int*)& user_fstype,
>> 409 (unsigned int*)& mountflags,
>> 410 (unsigned int*)& user_args);
465 if (SOS_OK != retval) 411 if (SOS_OK != retval)
466 break; 412 break;
467 413
468 str = (char*)sos_kmalloc(len + 1, 0); !! 414 if (user_src != (sos_uaddr_t)NULL)
469 if (str) !! 415 {
>> 416 retval = sos_strndup_from_user(&kernel_src, user_src, srclen, 0);
>> 417 if (SOS_OK != retval)
>> 418 break;
>> 419 }
>> 420
>> 421 retval = sos_strndup_from_user(&kernel_dst, user_dst, dstlen, 0);
>> 422 if (SOS_OK != retval)
>> 423 {
>> 424 if (kernel_src)
>> 425 sos_kfree((sos_vaddr_t)kernel_src);
>> 426 break;
>> 427 }
>> 428
>> 429 retval = sos_strndup_from_user(& kernel_fstype, user_fstype, 256, 0);
>> 430 if (SOS_OK != retval)
>> 431 {
>> 432 if (kernel_src)
>> 433 sos_kfree((sos_vaddr_t)kernel_src);
>> 434 sos_kfree((sos_vaddr_t)kernel_dst);
>> 435 break;
>> 436 }
>> 437
>> 438 if (user_args != (sos_uaddr_t)NULL)
470 { 439 {
471 retval = sos_strzcpy_from_user(str !! 440 retval = sos_strndup_from_user(& kernel_args, user_args, 1024, 0);
472 str[len] = '\0'; !! 441 if (SOS_OK != retval)
473 if (SOS_OK == retval) <<
474 { 442 {
475 sos_bochs_printf("THR 0x%x: ", !! 443 if (kernel_src)
476 (unsigned)sos !! 444 sos_kfree((sos_vaddr_t)kernel_src);
477 retval = sos_bochs_putstring(s !! 445 sos_kfree((sos_vaddr_t)kernel_dst);
478 retval = len; !! 446 sos_kfree((sos_vaddr_t)kernel_fstype);
>> 447 break;
479 } 448 }
480 sos_kfree((sos_vaddr_t)str); <<
481 } 449 }
482 else !! 450
483 retval = -SOS_ENOMEM; !! 451 retval = sos_fs_mount(proc, kernel_src, srclen,
>> 452 kernel_dst, dstlen,
>> 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()->process;
>> 474 retval = sos_syscall_get2args(user_ctxt,
>> 475 (unsigned int*)& user_str,
>> 476 (unsigned int*)& len);
>> 477 if (SOS_OK != retval)
>> 478 break;
>> 479
>> 480 retval = sos_strndup_from_user(&path, user_str, len, 0);
>> 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_struct;
>> 503 char * path;
>> 504 struct sos_process * proc;
>> 505
>> 506 proc = sos_thread_get_current()->process;
>> 507 retval = sos_syscall_get3args(user_ctxt,
>> 508 (unsigned int*)& user_str,
>> 509 (unsigned int*)& len,
>> 510 (unsigned int*)& user_vfstat_struct);
>> 511 if (SOS_OK != retval)
>> 512 break;
>> 513
>> 514 retval = sos_strndup_from_user(&path, user_str, len, 0);
>> 515 if (SOS_OK != retval)
>> 516 break;
>> 517
>> 518 retval = sos_fs_vfstat(proc, path, len, & kernel_vfstat_struct);
>> 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_struct,
>> 525 (sos_vaddr_t) & kernel_vfstat_struct,
>> 526 sizeof(kernel_vfstat_struct)))
>> 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()->process;
>> 542 retval = sos_syscall_get4args(user_ctxt,
>> 543 (unsigned int*)& user_str,
>> 544 (unsigned int*)& len,
>> 545 (unsigned int*)& open_flags,
>> 546 (unsigned int*)& access_rights);
>> 547 if (SOS_OK != retval)
>> 548 break;
>> 549
>> 550 retval = sos_strndup_from_user(&path, user_str, len, 0);
>> 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_file(proc, of);
>> 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()->process;
>> 579 retval = sos_syscall_get1arg(user_ctxt,
>> 580 (unsigned int*)& fd);
>> 581 if (SOS_OK != retval)
>> 582 break;
>> 583
>> 584 of = sos_process_get_opened_file(proc, fd);
>> 585 if (NULL == of)
>> 586 {
>> 587 retval = -SOS_EBADF;
>> 588 break;
>> 589 }
>> 590
>> 591 retval = sos_process_unregister_opened_file(proc, fd);
>> 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()->process;
>> 609 retval = sos_syscall_get3args(user_ctxt,
>> 610 (unsigned int*)& fd,
>> 611 (unsigned int*)& uaddr_buf,
>> 612 (unsigned int*)& uaddr_buflen);
>> 613 if (SOS_OK != retval)
>> 614 break;
>> 615
>> 616
>> 617 retval = sos_memcpy_from_user((sos_vaddr_t)& kernel_buflen,
>> 618 uaddr_buflen,
>> 619 sizeof(kernel_buflen));
>> 620 if (sizeof(kernel_buflen) != retval)
>> 621 {
>> 622 retval = -SOS_EFAULT;
>> 623 break;
>> 624 }
>> 625
>> 626 of = sos_process_get_opened_file(proc, fd);
>> 627 if (NULL == of)
>> 628 {
>> 629 retval = -SOS_EBADF;
>> 630 break;
>> 631 }
>> 632
>> 633
>> 634 retval = sos_fs_read(of, uaddr_buf, & kernel_buflen);
>> 635
>> 636
>> 637 sos_memcpy_to_user(uaddr_buflen,
>> 638 (sos_vaddr_t)& kernel_buflen,
>> 639 sizeof(kernel_buflen));
>> 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()->process;
>> 652 retval = sos_syscall_get2args(user_ctxt,
>> 653 (unsigned int*)& fd,
>> 654 (unsigned int*)& uaddr_direntry);
>> 655 if (SOS_OK != retval)
>> 656 break;
>> 657
>> 658 of = sos_process_get_opened_file(proc, fd);
>> 659 if (NULL == of)
>> 660 {
>> 661 retval = -SOS_EBADF;
>> 662 break;
>> 663 }
>> 664
>> 665
>> 666 retval = sos_fs_readdir(of, & direntry);
>> 667 if (SOS_OK != retval)
>> 668 break;
>> 669
>> 670
>> 671 if (sizeof(direntry) != sos_memcpy_to_user(uaddr_direntry,
>> 672 (sos_vaddr_t)& direntry,
>> 673 sizeof(direntry)))
>> 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()->process;
>> 688 retval = sos_syscall_get3args(user_ctxt,
>> 689 (unsigned int*)& fd,
>> 690 (unsigned int*)& uaddr_buf,
>> 691 (unsigned int*)& uaddr_buflen);
>> 692 if (SOS_OK != retval)
>> 693 break;
>> 694
>> 695
>> 696 retval = sos_memcpy_from_user((sos_vaddr_t)& kernel_buflen,
>> 697 uaddr_buflen,
>> 698 sizeof(kernel_buflen));
>> 699 if (sizeof(kernel_buflen) != retval)
>> 700 {
>> 701 retval = -SOS_EFAULT;
>> 702 break;
>> 703 }
>> 704
>> 705 of = sos_process_get_opened_file(proc, fd);
>> 706 if (NULL == of)
>> 707 {
>> 708 retval = -SOS_EBADF;
>> 709 break;
>> 710 }
>> 711
>> 712
>> 713 retval = sos_fs_write(of, uaddr_buf, & kernel_buflen);
>> 714
>> 715
>> 716 sos_memcpy_to_user(uaddr_buflen,
>> 717 (sos_vaddr_t)& kernel_buflen,
>> 718 sizeof(kernel_buflen));
>> 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_position;
>> 729 int fd;
>> 730
>> 731 proc = sos_thread_get_current()->process;
>> 732 retval = sos_syscall_get3args(user_ctxt,
>> 733 (unsigned int*)& fd,
>> 734 (unsigned int*)& uaddr_offset,
>> 735 (unsigned int*)& whence);
>> 736 if (SOS_OK != retval)
>> 737 break;
>> 738
>> 739
>> 740 retval = sos_memcpy_from_user((sos_vaddr_t)& kernel_offset,
>> 741 uaddr_offset,
>> 742 sizeof(kernel_offset));
>> 743 if (sizeof(kernel_offset) != retval)
>> 744 {
>> 745 retval = -SOS_EFAULT;
>> 746 break;
>> 747 }
>> 748
>> 749 of = sos_process_get_opened_file(proc, fd);
>> 750 if (NULL == of)
>> 751 {
>> 752 retval = -SOS_EBADF;
>> 753 break;
>> 754 }
>> 755
>> 756
>> 757 retval = sos_fs_seek(of, kernel_offset, whence, & result_position);
>> 758
>> 759
>> 760 sos_memcpy_to_user(uaddr_offset,
>> 761 (sos_vaddr_t)& result_position,
>> 762 sizeof(kernel_offset));
>> 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()->process;
>> 774 retval = sos_syscall_get2args(user_ctxt,
>> 775 (unsigned int*)& fd,
>> 776 (unsigned int*)& length);
>> 777 if (SOS_OK != retval)
>> 778 break;
>> 779
>> 780 of = sos_process_get_opened_file(proc, fd);
>> 781 if (NULL == of)
>> 782 {
>> 783 retval = -SOS_EBADF;
>> 784 break;
>> 785 }
>> 786
>> 787
>> 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()->process;
>> 807 retval = sos_syscall_get7args(user_ctxt,
>> 808 (unsigned int*)& ptr_hint_uaddr,
>> 809 (unsigned int*)& length,
>> 810 (unsigned int*)& prot,
>> 811 (unsigned int*)& flags,
>> 812 (unsigned int*)& fd,
>> 813 (unsigned int*)& offs64_hi,
>> 814 (unsigned int*)& offs64_lo);
>> 815 if (SOS_OK != retval)
>> 816 break;
>> 817
>> 818 of = sos_process_get_opened_file(proc, fd);
>> 819 if (NULL == of)
>> 820 {
>> 821 retval = -SOS_EBADF;
>> 822 break;
>> 823 }
>> 824
>> 825
>> 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_vaddr_t)& hint_uaddr,
>> 831 ptr_hint_uaddr,
>> 832 sizeof(hint_uaddr));
>> 833 if (sizeof(hint_uaddr) != retval)
>> 834 {
>> 835 retval = -SOS_EFAULT;
>> 836 break;
>> 837 }
>> 838
>> 839 retval = sos_fs_mmap(of, & hint_uaddr, length, prot, flags,
>> 840 offset_in_resource);
>> 841 if (SOS_OK == retval)
>> 842 {
>> 843 if (sizeof(hint_uaddr)
>> 844 != sos_memcpy_to_user(ptr_hint_uaddr,
>> 845 (sos_vaddr_t)& hint_uaddr,
>> 846 sizeof(hint_uaddr)))
>> 847 {
>> 848 sos_umem_vmm_unmap(sos_process_get_address_space(proc),
>> 849 hint_uaddr, length);
>> 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()->process;
>> 864 retval = sos_syscall_get1arg(user_ctxt,
>> 865 (unsigned int*)& fd);
>> 866 if (SOS_OK != retval)
>> 867 break;
>> 868
>> 869 of = sos_process_get_opened_file(proc, fd);
>> 870 if (NULL == of)
>> 871 {
>> 872 retval = -SOS_EBADF;
>> 873 break;
>> 874 }
>> 875
>> 876
>> 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()->process;
>> 889 retval = sos_syscall_get3args(user_ctxt,
>> 890 (unsigned int*)& fd,
>> 891 (unsigned int*)& cmd,
>> 892 (unsigned int*)& arg);
>> 893 if (SOS_OK != retval)
>> 894 break;
>> 895
>> 896 of = sos_process_get_opened_file(proc, fd);
>> 897 if (NULL == of)
>> 898 {
>> 899 retval = -SOS_EBADF;
>> 900 break;
>> 901 }
>> 902
>> 903
>> 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()->process;
>> 916 retval = sos_syscall_get3args(user_ctxt,
>> 917 (unsigned int*)& fd,
>> 918 (unsigned int*)& cmd,
>> 919 (unsigned int*)& arg);
>> 920 if (SOS_OK != retval)
>> 921 break;
>> 922
>> 923 of = sos_process_get_opened_file(proc, fd);
>> 924 if (NULL == of)
>> 925 {
>> 926 retval = -SOS_EBADF;
>> 927 break;
>> 928 }
>> 929
>> 930
>> 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()->process;
>> 944 retval = sos_syscall_get3args(user_ctxt,
>> 945 (unsigned int*)& user_str,
>> 946 (unsigned int*)& len,
>> 947 (unsigned int*)& access_rights);
>> 948 if (SOS_OK != retval)
>> 949 break;
>> 950
>> 951 retval = sos_strndup_from_user(&path, user_str, len, 0);
>> 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_newpath;
>> 968 struct sos_process * proc;
>> 969
>> 970 proc = sos_thread_get_current()->process;
>> 971 retval = sos_syscall_get4args(user_ctxt,
>> 972 (unsigned int*)& user_oldpath,
>> 973 (unsigned int*)& oldpathlen,
>> 974 (unsigned int*)& user_newpath,
>> 975 (unsigned int*)& newpathlen);
>> 976 if (SOS_OK != retval)
>> 977 break;
>> 978
>> 979 retval = sos_strndup_from_user(&kernel_oldpath,
>> 980 user_oldpath,
>> 981 oldpathlen, 0);
>> 982 if (SOS_OK != retval)
>> 983 break;
>> 984
>> 985 retval = sos_strndup_from_user(&kernel_newpath,
>> 986 user_newpath,
>> 987 newpathlen, 0);
>> 988 if (SOS_OK != retval)
>> 989 {
>> 990 sos_kfree((sos_vaddr_t) kernel_oldpath);
>> 991 break;
>> 992 }
>> 993
>> 994 if (syscall_id == SOS_SYSCALL_ID_LINK)
>> 995 retval = sos_fs_link(proc,
>> 996 kernel_oldpath, oldpathlen,
>> 997 kernel_newpath, newpathlen);
>> 998 else
>> 999 retval = sos_fs_rename(proc,
>> 1000 kernel_oldpath, oldpathlen,
>> 1001 kernel_newpath, newpathlen);
>> 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()->process;
>> 1015 retval = sos_syscall_get2args(user_ctxt,
>> 1016 (unsigned int*)& user_str,
>> 1017 (unsigned int*)& len);
>> 1018 if (SOS_OK != retval)
>> 1019 break;
>> 1020
>> 1021 retval = sos_strndup_from_user(&path, user_str, len, 0);
>> 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_targetpath;
>> 1034 sos_size_t pathlen, targetpathlen;
>> 1035 char * kernel_path;
>> 1036 struct sos_process * proc;
>> 1037
>> 1038 proc = sos_thread_get_current()->process;
>> 1039 retval = sos_syscall_get4args(user_ctxt,
>> 1040 (unsigned int*)& user_path,
>> 1041 (unsigned int*)& pathlen,
>> 1042 (unsigned int*)& user_targetpath,
>> 1043 (unsigned int*)& targetpathlen);
>> 1044 if (SOS_OK != retval)
>> 1045 break;
>> 1046
>> 1047 retval = sos_strndup_from_user(&kernel_path,
>> 1048 user_path,
>> 1049 pathlen, 0);
>> 1050 if (SOS_OK != retval)
>> 1051 break;
>> 1052
>> 1053 retval = sos_fs_symlink(proc,
>> 1054 kernel_path, pathlen,
>> 1055 user_targetpath, targetpathlen);
>> 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()->process;
>> 1071 retval = sos_syscall_get6args(user_ctxt,
>> 1072 (unsigned int*)& user_str,
>> 1073 (unsigned int*)& len,
>> 1074 (unsigned int*)& type,
>> 1075 (unsigned int*)& access_rights,
>> 1076 (unsigned int*)& dev_id.device_class,
>> 1077 (unsigned int*)& dev_id.device_instance);
>> 1078 if (SOS_OK != retval)
>> 1079 break;
>> 1080
>> 1081 retval = sos_strndup_from_user(&path, user_str, len, 0);
>> 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, len, access_rights);
>> 1089 break;
>> 1090
>> 1091 case SOS_FS_NODE_DIRECTORY:
>> 1092 retval = sos_fs_mkdir(proc, path, len, access_rights);
>> 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, type, access_rights, &dev_id);
>> 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()->process;
>> 1122 retval = sos_syscall_get3args(user_ctxt,
>> 1123 (unsigned int*)& user_str,
>> 1124 (unsigned int*)& len,
>> 1125 (unsigned int*)& access_rights);
>> 1126 if (SOS_OK != retval)
>> 1127 break;
>> 1128
>> 1129 retval = sos_strndup_from_user(&path, user_str, len, 0);
>> 1130 if (SOS_OK != retval)
>> 1131 break;
>> 1132
>> 1133 retval = sos_fs_mkdir(proc,
>> 1134 path, len, access_rights);
>> 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()->process;
>> 1147 retval = sos_syscall_get2args(user_ctxt,
>> 1148 (unsigned int*)& user_str,
>> 1149 (unsigned int*)& len);
>> 1150 if (SOS_OK != retval)
>> 1151 break;
>> 1152
>> 1153 retval = sos_strndup_from_user(&path, user_str, len, 0);
>> 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()->process;
>> 1171 retval = sos_syscall_get3args(user_ctxt,
>> 1172 (unsigned int*)& user_str,
>> 1173 (unsigned int*)& len,
>> 1174 (unsigned int*)& access_rights);
>> 1175 if (SOS_OK != retval)
>> 1176 break;
>> 1177
>> 1178 retval = sos_strndup_from_user(&path, user_str, len, 0);
>> 1179 if (SOS_OK != retval)
>> 1180 break;
>> 1181
>> 1182 retval = sos_fs_chmod(proc, path, len, access_rights);
>> 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()->process;
>> 1198 retval = sos_syscall_get4args(user_ctxt,
>> 1199 (unsigned int*)& user_str,
>> 1200 (unsigned int*)& len,
>> 1201 (unsigned int*)& nofollow,
>> 1202 (unsigned int*)& user_stat_struct);
>> 1203 if (SOS_OK != retval)
>> 1204 break;
>> 1205
>> 1206 retval = sos_strndup_from_user(&path, user_str, len, 0);
>> 1207 if (SOS_OK != retval)
>> 1208 break;
>> 1209
>> 1210 retval = sos_fs_stat(proc, path, len, nofollow, & kernel_stat_struct);
>> 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_struct,
>> 1217 (sos_vaddr_t) & kernel_stat_struct,
>> 1218 sizeof(kernel_stat_struct)))
>> 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_of;
>> 1230 struct sos_process * proc;
>> 1231
>> 1232 proc = sos_thread_get_current()->process;
>> 1233 retval = sos_syscall_get2args(user_ctxt,
>> 1234 (unsigned int*)& user_str,
>> 1235 (unsigned int*)& len);
>> 1236 if (SOS_OK != retval)
>> 1237 break;
>> 1238
>> 1239 retval = sos_strndup_from_user(&path, user_str, len, 0);
>> 1240 if (SOS_OK != retval)
>> 1241 break;
>> 1242
>> 1243 retval = sos_fs_open(proc,
>> 1244 path, len,
>> 1245 SOS_FS_OPEN_DIRECTORY,
>> 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_CHROOT)
>> 1253 retval = sos_process_chroot(proc, of, & old_of);
>> 1254 else
>> 1255 retval = sos_process_chdir(proc, of, & old_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_of, * old_of;
>> 1270 struct sos_process * proc;
>> 1271 int fd;
>> 1272
>> 1273 proc = sos_thread_get_current()->process;
>> 1274 retval = sos_syscall_get1arg(user_ctxt,
>> 1275 (unsigned int*)& fd);
>> 1276 if (SOS_OK != retval)
>> 1277 break;
>> 1278
>> 1279 of = sos_process_get_opened_file(proc, fd);
>> 1280 if (NULL == of)
>> 1281 {
>> 1282 retval = -SOS_EBADF;
>> 1283 break;
>> 1284 }
>> 1285
>> 1286
>> 1287 retval = sos_fs_duplicate_opened_file(of, proc, & new_of);
>> 1288 if (SOS_OK != retval)
>> 1289 break;
>> 1290
>> 1291
>> 1292 retval = sos_process_chdir(proc, new_of, & old_of);
>> 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_ctxt, & user_str, & len);
>> 1309 if (SOS_OK != retval)
>> 1310 break;
>> 1311
>> 1312 retval = sos_strndup_from_user(& str, user_str, len + 1, 0);
>> 1313 if (SOS_OK == retval)
>> 1314 {
>> 1315 sos_bochs_printf("THR 0x%x: ",
>> 1316 (unsigned)sos_thread_get_current());
>> 1317 retval = sos_bochs_putstring(str);
>> 1318 retval = len;
>> 1319 sos_kfree((sos_vaddr_t)str);
>> 1320 }
484 } 1321 }
485 break; 1322 break;
486 1323
487 1324
488 1325
489 1326
490 1327
491 1328
492 1329
493 1330
494 1331
495 1332
496 1333
497 case 4012: 1334 case 4012:
498 { 1335 {
499 sos_uaddr_t user_str; 1336 sos_uaddr_t user_str;
500 unsigned int len; 1337 unsigned int len;
501 unsigned char * str; 1338 unsigned char * str;
502 1339
503 retval = sos_syscall_get2args(user_ctx 1340 retval = sos_syscall_get2args(user_ctxt, & user_str, & len);
504 if (SOS_OK != retval) 1341 if (SOS_OK != retval)
505 break; 1342 break;
506 1343
507 str = (char*)sos_kmalloc(len + 1, 0); !! 1344 str = (unsigned char*)sos_kmalloc(len, 0);
508 if (str) 1345 if (str)
509 { 1346 {
510 int i; 1347 int i;
511 sos_bochs_printf("Hexdump(0x%x, %d 1348 sos_bochs_printf("Hexdump(0x%x, %d):\n", user_str, len);
512 retval = sos_memcpy_from_user((sos 1349 retval = sos_memcpy_from_user((sos_vaddr_t) str, user_str, len);
513 sos_bochs_printf(" (Successfully 1350 sos_bochs_printf(" (Successfully copied %d out of %d)\n",
514 retval, len); 1351 retval, len);
515 1352
516 for (i = 0 ; i < retval ; i++) 1353 for (i = 0 ; i < retval ; i++)
517 { 1354 {
518 if ((i % 32) == 0) 1355 if ((i % 32) == 0)
519 sos_bochs_printf("%x:", i); 1356 sos_bochs_printf("%x:", i);
520 sos_bochs_printf(" %x", str[i] 1357 sos_bochs_printf(" %x", str[i]);
521 if (((i+1) % 32) == 0) 1358 if (((i+1) % 32) == 0)
522 sos_bochs_printf("\n"); 1359 sos_bochs_printf("\n");
523 } 1360 }
524 if (i % 32) 1361 if (i % 32)
525 sos_bochs_printf("\n"); 1362 sos_bochs_printf("\n");
526 1363
527 sos_kfree((sos_vaddr_t)str); 1364 sos_kfree((sos_vaddr_t)str);
528 } 1365 }
529 else 1366 else
530 retval = -SOS_ENOMEM; 1367 retval = -SOS_ENOMEM;
531 } 1368 }
532 break; 1369 break;
533 1370
534 1371
535 1372
536 1373
537 1374
538 1375
539 case 4004: 1376 case 4004:
540 { 1377 {
541 sos_uaddr_t ustr; 1378 sos_uaddr_t ustr;
542 char * kstr; 1379 char * kstr;
543 struct sos_umem_vmm_as * my_as; 1380 struct sos_umem_vmm_as * my_as;
544 1381
545 retval = sos_syscall_get1arg(user_ctxt 1382 retval = sos_syscall_get1arg(user_ctxt, & ustr);
546 if (SOS_OK != retval) 1383 if (SOS_OK != retval)
547 break; 1384 break;
548 1385
549 retval = sos_strndup_from_user(& kstr, 1386 retval = sos_strndup_from_user(& kstr, ustr, 256, 0);
550 if (SOS_OK != retval) 1387 if (SOS_OK != retval)
551 break; 1388 break;
552 1389
553 extern void sos_dump_as(const struct s 1390 extern void sos_dump_as(const struct sos_umem_vmm_as *, const char *);
554 my_as 1391 my_as
555 = sos_process_get_address_space(sos_ 1392 = sos_process_get_address_space(sos_thread_get_current()->process);
556 sos_dump_as(my_as, kstr); 1393 sos_dump_as(my_as, kstr);
557 sos_kfree((sos_vaddr_t)kstr); 1394 sos_kfree((sos_vaddr_t)kstr);
558 } 1395 }
559 break; 1396 break;
560 1397
561 1398
562 1399
563 1400
564 1401
565 1402
566 case 4008: 1403 case 4008:
567 { 1404 {
568 extern void sos_process_dumplist(void) 1405 extern void sos_process_dumplist(void);
569 sos_process_dumplist(); 1406 sos_process_dumplist();
570 retval = SOS_OK; 1407 retval = SOS_OK;
571 } 1408 }
572 break; 1409 break;
573 1410
574 default: 1411 default:
575 sos_bochs_printf("Syscall: UNKNOWN[%d]\n 1412 sos_bochs_printf("Syscall: UNKNOWN[%d]\n", syscall_id);
576 retval = -SOS_ENOSUP; 1413 retval = -SOS_ENOSUP;
577 } 1414 }
578 1415
579 return retval; 1416 return retval;
580 } 1417 }