diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs index ac28a846bbf56da57952905fdf00cf74c82e9da1..f0e9a635d08280a7b85dbfb58a573f29b3e70d5e 100644 --- a/src/platform/redox/mod.rs +++ b/src/platform/redox/mod.rs @@ -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 {