pub fn sys_execve(
        &mut self,
        path: UserInPtr<u8>,
        argv: UserInPtr<UserInPtr<u8>>,
        envp: UserInPtr<UserInPtr<u8>>,
    ) -> SysResult {
        let path = path.read_cstring()?;
        let args = argv.read_cstring_array()?;
        let envs = envp.read_cstring_array()?;
        info!(
            "execve: path: {:?}, argv: {:?}, envs: {:?}",
            path, argv, envs
        );
        if args.is_empty() {
            error!("execve: args is null");
            return Err(LxError::EINVAL);
        }

        // TODO: check and kill other threads

        // Read program file
        let proc = self.linux_process();
        let inode = proc.lookup_inode(&path)?;
        let data = inode.read_as_vec()?;

        proc.remove_cloexec_files();

        let vmar = self.zircon_process().vmar();
        vmar.clear()?;
        let loader = LinuxElfLoader {
            syscall_entry: self.syscall_entry,
            stack_pages: 8,
            root_inode: proc.root_inode().clone(),
        };
        let (entry, sp) = loader.load(&vmar, &data, args, envs, path.clone())?;

        // Activate page table
        // vmar.activate();

        // Modify exec path
        proc.set_execute_path(&path);

        // TODO: use right signal
        //self.zircon_process().signal_set(Signal::SIGNALED);
        //Workaround, the child process could NOT exit correctly

        #[cfg(not(target_arch = "riscv64"))]
        {
            *self.regs = GeneralRegs::new_fn(entry, sp, 0, 0);
        }

        #[cfg(target_arch = "riscv64")]
        {
            self.context.general = GeneralRegs::new_fn(entry, sp, 0, 0);
            self.context.sepc = entry;
            info!(
                "execve: PageTable: {:#x}, entry: {:#x}, sp: {:#x}",
                self.zircon_process().vmar().table_phys(),
                self.context.sepc,
                self.context.general.sp
            );
        }

        Ok(0)
    }
/// Replaces the current ** process ** with a new process image
///
/// `argv` is an array of argument strings passed to the new program.
/// `envp` is an array of strings, conventionally of the form `key=value`,
/// which are passed as environment to the new program.
///
/// NOTICE: `argv` & `envp` can not be NULL (different from Linux)
///
/// NOTICE: for multi-thread programs
/// A call to any exec function from a process with more than one thread
/// shall result in all threads being terminated and the new executable image
/// being loaded and executed.
Replaces the current ** process ** with a new process image
`argv` is an array of argument strings passed to the new program.
`envp` is an array of strings, conventionally of the form `key=value`,
which are passed as environment to the new program.

`argv` & `envp` can not be NULL (different from Linux)

for multi-thread programs
A call to any exec function from a process with more than one thread
shall result in all threads being terminated and the new executable image
being loaded and executed.
Replaces the current ** process ** with a new process image ` argv ` is an array of argument strings passed to the new program . ` envp ` is an array of strings conventionally of the form ` key = value ` which are passed as environment to the new program . ` argv ` & ` envp ` can not be NULL ( different from Linux ) for multi - thread programs A call to any exec function from a process with more than one thread shall result in all threads being terminated and the new executable image being loaded and executed .
pub fn sys_execve(
        &mut self,
        path: UserInPtr<u8>,
        argv: UserInPtr<UserInPtr<u8>>,
        envp: UserInPtr<UserInPtr<u8>>,
    ) -> SysResult {
        let path = path.read_cstring()?;
        let args = argv.read_cstring_array()?;
        let envs = envp.read_cstring_array()?;
        info!(
            "execve: path: {:?}, argv: {:?}, envs: {:?}",
            path, argv, envs
        );
        if args.is_empty() {
            error!("execve: args is null");
            return Err(LxError::EINVAL);
        }
        // TODO: check and kill other threads
        // Read program file
        let proc = self.linux_process();
        let inode = proc.lookup_inode(&path)?;
        let data = inode.read_as_vec()?;
        proc.remove_cloexec_files();
        let vmar = self.zircon_process().vmar();
        vmar.clear()?;
        let loader = LinuxElfLoader {
            syscall_entry: self.syscall_entry,
            stack_pages: 8,
            root_inode: proc.root_inode().clone(),
        };
        let (entry, sp) = loader.load(&vmar, &data, args, envs, path.clone())?;
        // Activate page table
        // vmar.activate();
        // Modify exec path
        proc.set_execute_path(&path);
        // TODO: use right signal
        //self.zircon_process().signal_set(Signal::SIGNALED);
        //Workaround, the child process could NOT exit correctly
        #[cfg(not(target_arch = "riscv64"))]
        {
            *self.regs = GeneralRegs::new_fn(entry, sp, 0, 0);
        }
        #[cfg(target_arch = "riscv64")]
        {
            self.context.general = GeneralRegs::new_fn(entry, sp, 0, 0);
            self.context.sepc = entry;
            info!(
                "execve: PageTable: {:#x}, entry: {:#x}, sp: {:#x}",
                self.zircon_process().vmar().table_phys(),
                self.context.sepc,
                self.context.general.sp
            );
        }
        Ok(0)
    }
pub fn sys_execve ( & mut self , path : UserInPtr < u8 > , argv : UserInPtr < UserInPtr < u8 > > , envp : UserInPtr < UserInPtr < u8 > > , ) -> SysResult { let path = path . read_cstring ( ) ? ; let args = argv . read_cstring_array ( ) ? ; let envs = envp . read_cstring_array ( ) ? ; info ! ( " " path argv envs ) ; if args . is_empty ( ) { error ! ( " " ) ; return Err ( LxError :: EINVAL ) ; } // TODO: check and kill other threads // Read program file let proc = self . linux_process ( ) ; let inode = proc . lookup_inode ( & path ) ? ; let data = inode . read_as_vec ( ) ? ; proc . remove_cloexec_files ( ) ; let vmar = self . zircon_process ( ) . vmar ( ) ; vmar . clear ( ) ? ; let loader = LinuxElfLoader { syscall_entry : self . syscall_entry , stack_pages : 8 , root_inode : proc . root_inode ( ) . clone ( ) , } ; let ( entry , sp ) = loader . load ( & vmar , & data , args , envs , path . clone ( ) ) ? ; // Activate page table // vmar.activate(); // Modify exec path proc . set_execute_path ( & path ) ; // TODO: use right signal //self.zircon_process().signal_set(Signal::SIGNALED); //Workaround, the child process could NOT exit correctly # [ cfg ( not ( target_arch " " ) ) ] { * self . regs = GeneralRegs :: new_fn ( entry , sp , 0 , 0 ) ; } # [ cfg ( target_arch " " ) ] { self . context . general = GeneralRegs :: new_fn ( entry , sp , 0 , 0 ) ; self . context . sepc = entry ; info ! ( " " self zircon_process ( ) vmar ( ) table_phys ( ) self context sepc self context general sp ) ; } Ok ( 0 ) }
Replaces the current ** process ** with a new process image
`argv` is an array of argument strings passed to the new program.
Replaces the current ** process ** with a new process image ` argv ` is an array of argument strings passed to the new program .
&mut self
path
UserInPtr<u8>
argv
UserInPtr<UserInPtr<u8>>
envp
UserInPtr<UserInPtr<u8>>
&mut self
path
UserInPtr<u8>
argv
UserInPtr<UserInPtr<u8>>
envp
UserInPtr<UserInPtr<u8>>