| 3555 | } |
| 3556 | |
| 3557 | sysret_t _sys_fork(void) |
| 3558 | { |
| 3559 | int tid = 0; |
| 3560 | sysret_t falival = 0; |
| 3561 | struct rt_lwp *lwp = RT_NULL; |
| 3562 | struct rt_lwp *self_lwp = RT_NULL; |
| 3563 | rt_thread_t thread = RT_NULL; |
| 3564 | rt_thread_t self_thread = RT_NULL; |
| 3565 | void *user_stack = RT_NULL; |
| 3566 | rt_processgroup_t group; |
| 3567 | |
| 3568 | /* new lwp */ |
| 3569 | lwp = lwp_create(LWP_CREATE_FLAG_ALLOC_PID); |
| 3570 | if (!lwp) |
| 3571 | { |
| 3572 | SET_ERRNO(ENOMEM); |
| 3573 | goto fail; |
| 3574 | } |
| 3575 | |
| 3576 | /* new tid */ |
| 3577 | if ((tid = lwp_tid_get()) == 0) |
| 3578 | { |
| 3579 | SET_ERRNO(ENOMEM); |
| 3580 | goto fail; |
| 3581 | } |
| 3582 | |
| 3583 | /* user space init */ |
| 3584 | if (lwp_user_space_init(lwp, 1) != 0) |
| 3585 | { |
| 3586 | SET_ERRNO(ENOMEM); |
| 3587 | goto fail; |
| 3588 | } |
| 3589 | |
| 3590 | self_lwp = lwp_self(); |
| 3591 | |
| 3592 | /* copy address space of process from this proc to forked one */ |
| 3593 | if (lwp_fork_aspace(lwp, self_lwp) != 0) |
| 3594 | { |
| 3595 | SET_ERRNO(ENOMEM); |
| 3596 | goto fail; |
| 3597 | } |
| 3598 | |
| 3599 | /* copy lwp struct data */ |
| 3600 | lwp_struct_copy(lwp, self_lwp); |
| 3601 | |
| 3602 | /* copy files */ |
| 3603 | if (lwp_copy_files(lwp, self_lwp) != 0) |
| 3604 | { |
| 3605 | SET_ERRNO(ENOMEM); |
| 3606 | goto fail; |
| 3607 | } |
| 3608 | |
| 3609 | /* create thread */ |
| 3610 | self_thread = rt_thread_self(); |
| 3611 | |
| 3612 | thread = rt_thread_create(self_thread->parent.name, |
| 3613 | RT_NULL, |
| 3614 | RT_NULL, |
no test coverage detected