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