* @brief Executes a program in the current process. * * This system call replaces the current process image with a new program specified by the * `path` argument. It loads the program located at the given `path` and passes the arguments * (`argv`) and environment variables (`envp`) to it. This effectively replaces the calling * process with a new one, and if successful, it never returns. If t
| 3749 | * image is replaced by the new program. |
| 3750 | */ |
| 3751 | sysret_t sys_execve(const char *path, char *const argv[], char *const envp[]) |
| 3752 | { |
| 3753 | rt_err_t error = -1; |
| 3754 | size_t len; |
| 3755 | struct rt_lwp *new_lwp = NULL; |
| 3756 | struct rt_lwp *lwp; |
| 3757 | int uni_thread; |
| 3758 | rt_thread_t thread; |
| 3759 | struct process_aux *aux; |
| 3760 | struct lwp_args_info args_info; |
| 3761 | char *kpath = RT_NULL; |
| 3762 | |
| 3763 | lwp = lwp_self(); |
| 3764 | thread = rt_thread_self(); |
| 3765 | uni_thread = 1; |
| 3766 | |
| 3767 | LWP_LOCK(lwp); |
| 3768 | if (lwp->t_grp.prev != &thread->sibling) |
| 3769 | { |
| 3770 | uni_thread = 0; |
| 3771 | } |
| 3772 | if (lwp->t_grp.next != &thread->sibling) |
| 3773 | { |
| 3774 | uni_thread = 0; |
| 3775 | } |
| 3776 | LWP_UNLOCK(lwp); |
| 3777 | |
| 3778 | if (!uni_thread) |
| 3779 | { |
| 3780 | return -EINVAL; |
| 3781 | } |
| 3782 | |
| 3783 | len = lwp_user_strlen(path); |
| 3784 | if (len <= 0) |
| 3785 | { |
| 3786 | return -EFAULT; |
| 3787 | } |
| 3788 | |
| 3789 | kpath = rt_malloc(len + 1); |
| 3790 | if (!kpath) |
| 3791 | { |
| 3792 | return -ENOMEM; |
| 3793 | } |
| 3794 | |
| 3795 | if (lwp_get_from_user(kpath, (void *)path, len) != len) |
| 3796 | { |
| 3797 | rt_free(kpath); |
| 3798 | return -EFAULT; |
| 3799 | } |
| 3800 | kpath[len] = '\0'; |
| 3801 | |
| 3802 | if (access(kpath, X_OK) != 0) |
| 3803 | { |
| 3804 | error = rt_get_errno(); |
| 3805 | rt_free(kpath); |
| 3806 | return (sysret_t)error; |
| 3807 | } |
| 3808 |
nothing calls this directly
no test coverage detected