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