Support shebangs in redox execve
This commit is contained in:
@@ -21,10 +21,10 @@ use header::sys_times::tms;
|
||||
use header::sys_utsname::utsname;
|
||||
use header::termios::termios;
|
||||
use header::time::timespec;
|
||||
use header::unistd::{F_OK, R_OK, W_OK, X_OK};
|
||||
use header::unistd::{F_OK, R_OK, W_OK, X_OK, SEEK_SET};
|
||||
|
||||
use super::types::*;
|
||||
use super::{errno, FileReader, FileWriter, Pal, RawFile, Read};
|
||||
use super::{errno, FileReader, FileWriter, Line, Pal, RawFile, RawLineBuffer, Read};
|
||||
|
||||
mod signal;
|
||||
mod socket;
|
||||
@@ -179,12 +179,58 @@ impl Pal for Sys {
|
||||
Err(_) => return -1,
|
||||
};
|
||||
|
||||
// Count arguments
|
||||
let mut len = 0;
|
||||
while !(*argv.offset(len)).is_null() {
|
||||
len += 1;
|
||||
}
|
||||
|
||||
let mut args: Vec<[usize; 2]> = Vec::with_capacity(len as usize);
|
||||
|
||||
// Read shebang (for example #!/bin/sh)
|
||||
let mut shebang = [0; 2];
|
||||
let mut read = 0;
|
||||
|
||||
while read < 2 {
|
||||
match Self::read(*fd, &mut shebang) {
|
||||
0 => break,
|
||||
i if i < 0 => return -1,
|
||||
i => read += i
|
||||
}
|
||||
}
|
||||
|
||||
let mut _interpreter_path = None;
|
||||
let mut _interpreter_file = None;
|
||||
let mut interpreter_fd = *fd;
|
||||
|
||||
if &shebang == b"#!" {
|
||||
match RawLineBuffer::new(*fd).next() {
|
||||
Line::Error => return -1,
|
||||
Line::EOF => (),
|
||||
Line::Some(line) => {
|
||||
let mut path = match CString::new(line) {
|
||||
Ok(path) => path,
|
||||
Err(_) => return -1
|
||||
};
|
||||
match RawFile::open(&path, O_RDONLY as c_int, 0) {
|
||||
Ok(file) => {
|
||||
interpreter_fd = *file;
|
||||
_interpreter_path = Some(path);
|
||||
_interpreter_file = Some(file);
|
||||
|
||||
let path_ref = _interpreter_path.as_ref().unwrap();
|
||||
args.push([path_ref.as_ptr() as usize, path_ref.to_bytes().len()]);
|
||||
},
|
||||
Err(_) => return -1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if Self::lseek(*fd, 0, SEEK_SET) < 0 {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Arguments
|
||||
while !(*argv).is_null() {
|
||||
let arg = *argv;
|
||||
|
||||
@@ -196,6 +242,7 @@ impl Pal for Sys {
|
||||
argv = argv.offset(1);
|
||||
}
|
||||
|
||||
// Environment variables
|
||||
let mut len = 0;
|
||||
while !(*envp.offset(len)).is_null() {
|
||||
len += 1;
|
||||
@@ -213,7 +260,7 @@ impl Pal for Sys {
|
||||
envp = envp.offset(1);
|
||||
}
|
||||
|
||||
e(syscall::fexec(*fd as usize, &args, &envs)) as c_int
|
||||
e(syscall::fexec(interpreter_fd as usize, &args, &envs)) as c_int
|
||||
}
|
||||
|
||||
fn fchdir(fd: c_int) -> c_int {
|
||||
|
||||
Reference in New Issue
Block a user