cargo fmt and cargo fix
This commit is contained in:
@@ -12,10 +12,10 @@ extern "C" {
|
||||
fn mspace_memalign(msp: usize, alignment: size_t, bytes: size_t) -> *mut c_void;
|
||||
fn mspace_realloc(msp: usize, oldmem: *mut c_void, bytes: size_t) -> *mut c_void;
|
||||
fn mspace_free(msp: usize, mem: *mut c_void);
|
||||
//fn dlmalloc(bytes: size_t) -> *mut c_void;
|
||||
//fn dlmemalign(alignment: size_t, bytes: size_t) -> *mut c_void;
|
||||
//fn dlrealloc(oldmem: *mut c_void, bytes: size_t) -> *mut c_void;
|
||||
//fn dlfree(mem: *mut c_void);
|
||||
//fn dlmalloc(bytes: size_t) -> *mut c_void;
|
||||
//fn dlmemalign(alignment: size_t, bytes: size_t) -> *mut c_void;
|
||||
//fn dlrealloc(oldmem: *mut c_void, bytes: size_t) -> *mut c_void;
|
||||
//fn dlfree(mem: *mut c_void);
|
||||
}
|
||||
|
||||
pub struct Allocator {
|
||||
|
||||
+11
-5
@@ -1,6 +1,5 @@
|
||||
use crate::io::{self, Read, Write};
|
||||
use alloc::boxed::Box;
|
||||
use alloc::vec::Vec;
|
||||
use alloc::{boxed::Box, vec::Vec};
|
||||
use core::{fmt, ptr};
|
||||
|
||||
pub use self::allocator::*;
|
||||
@@ -283,7 +282,10 @@ pub unsafe fn get_auxvs(mut ptr: *const usize) -> Box<[[usize; 2]]> {
|
||||
auxvs.into_boxed_slice()
|
||||
}
|
||||
pub fn get_auxv(auxvs: &[[usize; 2]], key: usize) -> Option<usize> {
|
||||
auxvs.binary_search_by_key(&key, |[entry_key, _]| *entry_key).ok().map(|idx| auxvs[idx][1])
|
||||
auxvs
|
||||
.binary_search_by_key(&key, |[entry_key, _]| *entry_key)
|
||||
.ok()
|
||||
.map(|idx| auxvs[idx][1])
|
||||
}
|
||||
|
||||
#[cold]
|
||||
@@ -291,8 +293,12 @@ pub fn get_auxv(auxvs: &[[usize; 2]], key: usize) -> Option<usize> {
|
||||
pub fn init(auxvs: Box<[[usize; 2]]>) {
|
||||
use self::auxv_defs::*;
|
||||
|
||||
if let (Some(cwd_ptr), Some(cwd_len)) = (get_auxv(&auxvs, AT_REDOX_INITIALCWD_PTR), get_auxv(&auxvs, AT_REDOX_INITIALCWD_LEN)) {
|
||||
let cwd_bytes: &'static [u8] = unsafe { core::slice::from_raw_parts(cwd_ptr as *const u8, cwd_len) };
|
||||
if let (Some(cwd_ptr), Some(cwd_len)) = (
|
||||
get_auxv(&auxvs, AT_REDOX_INITIALCWD_PTR),
|
||||
get_auxv(&auxvs, AT_REDOX_INITIALCWD_LEN),
|
||||
) {
|
||||
let cwd_bytes: &'static [u8] =
|
||||
unsafe { core::slice::from_raw_parts(cwd_ptr as *const u8, cwd_len) };
|
||||
if let Ok(cwd) = core::str::from_utf8(cwd_bytes) {
|
||||
self::sys::path::setcwd_manual(cwd.into());
|
||||
}
|
||||
|
||||
+1
-1
@@ -347,7 +347,7 @@ pub unsafe extern "C" fn pte_osSemaphorePend(
|
||||
handle: pte_osSemaphoreHandle,
|
||||
pTimeout: *mut c_uint,
|
||||
) -> pte_osResult {
|
||||
let timeout_opt = if ! pTimeout.is_null() {
|
||||
let timeout_opt = if !pTimeout.is_null() {
|
||||
let timeout = *pTimeout as i64;
|
||||
let tv_sec = timeout / 1000;
|
||||
let tv_nsec = (timeout % 1000) * 1000000;
|
||||
|
||||
+42
-18
@@ -1,13 +1,13 @@
|
||||
use core::arch::global_asm;
|
||||
use core::mem::size_of;
|
||||
use core::{arch::global_asm, mem::size_of};
|
||||
|
||||
use alloc::boxed::Box;
|
||||
use alloc::vec::Vec;
|
||||
use alloc::{boxed::Box, vec::Vec};
|
||||
|
||||
use syscall::data::Map;
|
||||
use syscall::flag::{MapFlags, O_CLOEXEC};
|
||||
use syscall::error::{Error, Result, EINVAL, ENAMETOOLONG};
|
||||
use syscall::SIGCONT;
|
||||
use syscall::{
|
||||
data::Map,
|
||||
error::{Error, Result, EINVAL, ENAMETOOLONG},
|
||||
flag::{MapFlags, O_CLOEXEC},
|
||||
SIGCONT,
|
||||
};
|
||||
|
||||
use super::extra::{create_set_addr_space_buf, FdGuard};
|
||||
|
||||
@@ -25,7 +25,15 @@ pub unsafe fn pte_clone_impl(stack: *mut usize) -> Result<usize> {
|
||||
const SIGSTACK_SIZE: usize = 1024 * 256;
|
||||
|
||||
// TODO: Put sigstack at high addresses?
|
||||
let target_sigstack = syscall::fmap(!0, &Map { address: 0, flags: MapFlags::PROT_READ | MapFlags::PROT_WRITE | MapFlags::MAP_PRIVATE, offset: 0, size: SIGSTACK_SIZE })? + SIGSTACK_SIZE;
|
||||
let target_sigstack = syscall::fmap(
|
||||
!0,
|
||||
&Map {
|
||||
address: 0,
|
||||
flags: MapFlags::PROT_READ | MapFlags::PROT_WRITE | MapFlags::MAP_PRIVATE,
|
||||
offset: 0,
|
||||
size: SIGSTACK_SIZE,
|
||||
},
|
||||
)? + SIGSTACK_SIZE;
|
||||
|
||||
let _ = syscall::write(*sigstack_fd, &usize::to_ne_bytes(target_sigstack))?;
|
||||
}
|
||||
@@ -37,7 +45,11 @@ pub unsafe fn pte_clone_impl(stack: *mut usize) -> Result<usize> {
|
||||
let cur_addr_space_fd = FdGuard::new(syscall::dup(*cur_pid_fd, b"addrspace")?);
|
||||
let new_addr_space_sel_fd = FdGuard::new(syscall::dup(*new_pid_fd, b"current-addrspace")?);
|
||||
|
||||
let buf = create_set_addr_space_buf(*cur_addr_space_fd, __relibc_internal_pte_clone_ret as usize, stack as usize);
|
||||
let buf = create_set_addr_space_buf(
|
||||
*cur_addr_space_fd,
|
||||
__relibc_internal_pte_clone_ret as usize,
|
||||
stack as usize,
|
||||
);
|
||||
let _ = syscall::write(*new_addr_space_sel_fd, &buf)?;
|
||||
}
|
||||
|
||||
@@ -46,7 +58,10 @@ pub unsafe fn pte_clone_impl(stack: *mut usize) -> Result<usize> {
|
||||
let cur_filetable_fd = FdGuard::new(syscall::dup(*cur_pid_fd, b"filetable")?);
|
||||
let new_filetable_sel_fd = FdGuard::new(syscall::dup(*new_pid_fd, b"current-filetable")?);
|
||||
|
||||
let _ = syscall::write(*new_filetable_sel_fd, &usize::to_ne_bytes(*cur_filetable_fd))?;
|
||||
let _ = syscall::write(
|
||||
*new_filetable_sel_fd,
|
||||
&usize::to_ne_bytes(*cur_filetable_fd),
|
||||
)?;
|
||||
}
|
||||
|
||||
// Reuse sigactions (on Linux, CLONE_THREAD requires CLONE_SIGHAND which implies the sigactions
|
||||
@@ -55,7 +70,10 @@ pub unsafe fn pte_clone_impl(stack: *mut usize) -> Result<usize> {
|
||||
let cur_sigaction_fd = FdGuard::new(syscall::dup(*cur_pid_fd, b"sigactions")?);
|
||||
let new_sigaction_sel_fd = FdGuard::new(syscall::dup(*new_pid_fd, b"current-sigactions")?);
|
||||
|
||||
let _ = syscall::write(*new_sigaction_sel_fd, &usize::to_ne_bytes(*cur_sigaction_fd))?;
|
||||
let _ = syscall::write(
|
||||
*new_sigaction_sel_fd,
|
||||
&usize::to_ne_bytes(*cur_sigaction_fd),
|
||||
)?;
|
||||
}
|
||||
|
||||
copy_env_regs(*cur_pid_fd, *new_pid_fd)?;
|
||||
@@ -72,7 +90,8 @@ extern "C" {
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
core::arch::global_asm!("
|
||||
core::arch::global_asm!(
|
||||
"
|
||||
.globl __relibc_internal_pte_clone_ret
|
||||
.type __relibc_internal_pte_clone_ret, @function
|
||||
.p2align 6
|
||||
@@ -91,10 +110,12 @@ __relibc_internal_pte_clone_ret:
|
||||
|
||||
ret
|
||||
.size __relibc_internal_pte_clone_ret, . - __relibc_internal_pte_clone_ret
|
||||
");
|
||||
"
|
||||
);
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
core::arch::global_asm!("
|
||||
core::arch::global_asm!(
|
||||
"
|
||||
.globl __relibc_internal_pte_clone_ret
|
||||
.type __relibc_internal_pte_clone_ret, @function
|
||||
.p2align 6
|
||||
@@ -116,10 +137,12 @@ __relibc_internal_pte_clone_ret:
|
||||
|
||||
ret
|
||||
.size __relibc_internal_pte_clone_ret, . - __relibc_internal_pte_clone_ret
|
||||
");
|
||||
"
|
||||
);
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
core::arch::global_asm!("
|
||||
core::arch::global_asm!(
|
||||
"
|
||||
.globl __relibc_internal_pte_clone_ret
|
||||
.type __relibc_internal_pte_clone_ret, @function
|
||||
.p2align 6
|
||||
@@ -147,4 +170,5 @@ __relibc_internal_pte_clone_ret:
|
||||
|
||||
ret
|
||||
.size __relibc_internal_pte_clone_ret, . - __relibc_internal_pte_clone_ret
|
||||
");
|
||||
"
|
||||
);
|
||||
|
||||
+96
-26
@@ -1,15 +1,26 @@
|
||||
use crate::c_str::{CStr, CString};
|
||||
use crate::core_io::{BufReader, prelude::*, SeekFrom};
|
||||
use crate::fs::File;
|
||||
use crate::header::{fcntl, string::strlen};
|
||||
use crate::platform::{sys::{S_ISUID, S_ISGID}, types::*};
|
||||
use crate::{
|
||||
c_str::{CStr, CString},
|
||||
core_io::{prelude::*, BufReader, SeekFrom},
|
||||
fs::File,
|
||||
header::{fcntl, string::strlen},
|
||||
platform::{
|
||||
sys::{S_ISGID, S_ISUID},
|
||||
types::*,
|
||||
},
|
||||
};
|
||||
|
||||
use syscall::data::Stat;
|
||||
use syscall::flag::*;
|
||||
use syscall::error::*;
|
||||
use redox_exec::{FdGuard, ExtraInfo, FexecResult};
|
||||
use redox_exec::{ExtraInfo, FdGuard, FexecResult};
|
||||
use syscall::{data::Stat, error::*, flag::*};
|
||||
|
||||
fn fexec_impl(file: File, path: &[u8], args: &[&[u8]], envs: &[&[u8]], total_args_envs_size: usize, extrainfo: &ExtraInfo, interp_override: Option<redox_exec::InterpOverride>) -> Result<usize> {
|
||||
fn fexec_impl(
|
||||
file: File,
|
||||
path: &[u8],
|
||||
args: &[&[u8]],
|
||||
envs: &[&[u8]],
|
||||
total_args_envs_size: usize,
|
||||
extrainfo: &ExtraInfo,
|
||||
interp_override: Option<redox_exec::InterpOverride>,
|
||||
) -> Result<usize> {
|
||||
let fd = *file;
|
||||
core::mem::forget(file);
|
||||
let image_file = FdGuard::new(fd as usize);
|
||||
@@ -17,9 +28,24 @@ fn fexec_impl(file: File, path: &[u8], args: &[&[u8]], envs: &[&[u8]], total_arg
|
||||
let open_via_dup = FdGuard::new(syscall::open("thisproc:current/open_via_dup", 0)?);
|
||||
let memory = FdGuard::new(syscall::open("memory:", 0)?);
|
||||
|
||||
let addrspace_selection_fd = match redox_exec::fexec_impl(image_file, open_via_dup, &memory, path, args.iter().rev(), envs.iter().rev(), total_args_envs_size, extrainfo, interp_override)? {
|
||||
let addrspace_selection_fd = match redox_exec::fexec_impl(
|
||||
image_file,
|
||||
open_via_dup,
|
||||
&memory,
|
||||
path,
|
||||
args.iter().rev(),
|
||||
envs.iter().rev(),
|
||||
total_args_envs_size,
|
||||
extrainfo,
|
||||
interp_override,
|
||||
)? {
|
||||
FexecResult::Normal { addrspace_handle } => addrspace_handle,
|
||||
FexecResult::Interp { image_file, open_via_dup, path, interp_override: new_interp_override } => {
|
||||
FexecResult::Interp {
|
||||
image_file,
|
||||
open_via_dup,
|
||||
path,
|
||||
interp_override: new_interp_override,
|
||||
} => {
|
||||
drop(image_file);
|
||||
drop(open_via_dup);
|
||||
drop(memory);
|
||||
@@ -28,7 +54,15 @@ fn fexec_impl(file: File, path: &[u8], args: &[&[u8]], envs: &[&[u8]], total_arg
|
||||
// null-terminated. Violating this should therefore give the "format error" ENOEXEC.
|
||||
let path_cstr = CStr::from_bytes_with_nul(&path).map_err(|_| Error::new(ENOEXEC))?;
|
||||
|
||||
return execve(path_cstr, ArgEnv::Parsed { total_args_envs_size, args, envs }, Some(new_interp_override));
|
||||
return execve(
|
||||
path_cstr,
|
||||
ArgEnv::Parsed {
|
||||
total_args_envs_size,
|
||||
args,
|
||||
envs,
|
||||
},
|
||||
Some(new_interp_override),
|
||||
);
|
||||
}
|
||||
};
|
||||
drop(memory);
|
||||
@@ -39,10 +73,21 @@ fn fexec_impl(file: File, path: &[u8], args: &[&[u8]], envs: &[&[u8]], total_arg
|
||||
unreachable!();
|
||||
}
|
||||
pub enum ArgEnv<'a> {
|
||||
C { argv: *const *mut c_char, envp: *const *mut c_char },
|
||||
Parsed { args: &'a [&'a [u8]], envs: &'a [&'a [u8]], total_args_envs_size: usize },
|
||||
C {
|
||||
argv: *const *mut c_char,
|
||||
envp: *const *mut c_char,
|
||||
},
|
||||
Parsed {
|
||||
args: &'a [&'a [u8]],
|
||||
envs: &'a [&'a [u8]],
|
||||
total_args_envs_size: usize,
|
||||
},
|
||||
}
|
||||
pub fn execve(path: &CStr, arg_env: ArgEnv, interp_override: Option<redox_exec::InterpOverride>) -> Result<usize> {
|
||||
pub fn execve(
|
||||
path: &CStr,
|
||||
arg_env: ArgEnv,
|
||||
interp_override: Option<redox_exec::InterpOverride>,
|
||||
) -> Result<usize> {
|
||||
// NOTE: We must omit O_CLOEXEC and close manually, otherwise it will be closed before we
|
||||
// have even read it!
|
||||
let mut image_file = File::open(path, O_RDONLY as c_int).map_err(|_| Error::new(ENOENT))?;
|
||||
@@ -85,7 +130,7 @@ pub fn execve(path: &CStr, arg_env: ArgEnv, interp_override: Option<redox_exec::
|
||||
while !(*argv.add(len)).is_null() {
|
||||
len += 1;
|
||||
}
|
||||
}
|
||||
},
|
||||
ArgEnv::Parsed { args, .. } => len = args.len(),
|
||||
}
|
||||
|
||||
@@ -98,7 +143,10 @@ pub fn execve(path: &CStr, arg_env: ArgEnv, interp_override: Option<redox_exec::
|
||||
let mut shebang = [0; 2];
|
||||
|
||||
while read < 2 {
|
||||
match image_file.read(&mut shebang).map_err(|_| Error::new(ENOEXEC))? {
|
||||
match image_file
|
||||
.read(&mut shebang)
|
||||
.map_err(|_| Error::new(ENOEXEC))?
|
||||
{
|
||||
0 => break,
|
||||
i => read += i,
|
||||
}
|
||||
@@ -122,7 +170,9 @@ pub fn execve(path: &CStr, arg_env: ArgEnv, interp_override: Option<redox_exec::
|
||||
// So, this file is interpreted.
|
||||
// Then, read the actual interpreter:
|
||||
let mut interpreter = Vec::new();
|
||||
BufReader::new(&mut image_file).read_until(b'\n', &mut interpreter).map_err(|_| Error::new(EIO))?;
|
||||
BufReader::new(&mut image_file)
|
||||
.read_until(b'\n', &mut interpreter)
|
||||
.map_err(|_| Error::new(EIO))?;
|
||||
if interpreter.ends_with(&[b'\n']) {
|
||||
interpreter.pop().unwrap();
|
||||
}
|
||||
@@ -134,7 +184,9 @@ pub fn execve(path: &CStr, arg_env: ArgEnv, interp_override: Option<redox_exec::
|
||||
let path_ref = _interpreter_path.as_ref().unwrap();
|
||||
args.push(path_ref.as_bytes());
|
||||
} else {
|
||||
image_file.seek(SeekFrom::Start(0)).map_err(|_| Error::new(EIO))?;
|
||||
image_file
|
||||
.seek(SeekFrom::Start(0))
|
||||
.map_err(|_| Error::new(EIO))?;
|
||||
}
|
||||
|
||||
let (total_args_envs_size, args, envs): (usize, Vec<_>, Vec<_>) = match arg_env {
|
||||
@@ -166,16 +218,23 @@ pub fn execve(path: &CStr, arg_env: ArgEnv, interp_override: Option<redox_exec::
|
||||
args_envs_size_without_nul += len;
|
||||
envp = envp.add(1);
|
||||
}
|
||||
(args_envs_size_without_nul + args.len() + envs.len(), args, envs)
|
||||
}
|
||||
ArgEnv::Parsed { args: new_args, envs, total_args_envs_size } => {
|
||||
(
|
||||
args_envs_size_without_nul + args.len() + envs.len(),
|
||||
args,
|
||||
envs,
|
||||
)
|
||||
},
|
||||
ArgEnv::Parsed {
|
||||
args: new_args,
|
||||
envs,
|
||||
total_args_envs_size,
|
||||
} => {
|
||||
let prev_size: usize = args.iter().map(|a| a.len()).sum();
|
||||
args.extend(new_args);
|
||||
(total_args_envs_size + prev_size, args, Vec::from(envs))
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Close all O_CLOEXEC file descriptors. TODO: close_range?
|
||||
{
|
||||
// NOTE: This approach of implementing O_CLOEXEC will not work in multithreaded
|
||||
@@ -238,10 +297,21 @@ pub fn execve(path: &CStr, arg_env: ArgEnv, interp_override: Option<redox_exec::
|
||||
unreachable!()
|
||||
} else {
|
||||
let extrainfo = ExtraInfo { cwd: Some(&cwd) };
|
||||
fexec_impl(image_file, path.to_bytes(), &args, &envs, total_args_envs_size, &extrainfo, interp_override)
|
||||
fexec_impl(
|
||||
image_file,
|
||||
path.to_bytes(),
|
||||
&args,
|
||||
&envs,
|
||||
total_args_envs_size,
|
||||
&extrainfo,
|
||||
interp_override,
|
||||
)
|
||||
}
|
||||
}
|
||||
fn flatten_with_nul<T>(iter: impl IntoIterator<Item = T>) -> Box<[u8]> where T: AsRef<[u8]> {
|
||||
fn flatten_with_nul<T>(iter: impl IntoIterator<Item = T>) -> Box<[u8]>
|
||||
where
|
||||
T: AsRef<[u8]>,
|
||||
{
|
||||
let mut vec = Vec::new();
|
||||
for item in iter {
|
||||
vec.extend(item.as_ref());
|
||||
|
||||
+29
-23
@@ -1,11 +1,9 @@
|
||||
use core::{mem, ptr, result::Result as CoreResult, slice, str};
|
||||
use core::convert::TryFrom;
|
||||
use core::arch::asm;
|
||||
use core::{arch::asm, convert::TryFrom, mem, ptr, result::Result as CoreResult, slice, str};
|
||||
|
||||
use syscall::{
|
||||
self,
|
||||
data::{Map, Stat as redox_stat, StatVfs as redox_statvfs, TimeSpec as redox_timespec},
|
||||
PtraceEvent, Result, Error, EMFILE,
|
||||
Error, PtraceEvent, Result, EMFILE,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
@@ -217,12 +215,12 @@ impl Pal for Sys {
|
||||
loop {}
|
||||
}
|
||||
|
||||
unsafe fn execve(
|
||||
path: &CStr,
|
||||
argv: *const *mut c_char,
|
||||
envp: *const *mut c_char,
|
||||
) -> c_int {
|
||||
e(self::exec::execve(path, self::exec::ArgEnv::C { argv, envp }, None)) as c_int
|
||||
unsafe fn execve(path: &CStr, argv: *const *mut c_char, envp: *const *mut c_char) -> c_int {
|
||||
e(self::exec::execve(
|
||||
path,
|
||||
self::exec::ArgEnv::C { argv, envp },
|
||||
None,
|
||||
)) as c_int
|
||||
}
|
||||
|
||||
fn fchdir(fd: c_int) -> c_int {
|
||||
@@ -364,13 +362,17 @@ impl Pal for Sys {
|
||||
|
||||
let buf_slice = unsafe { slice::from_raw_parts_mut(buf as *mut u8, size as usize) };
|
||||
if buf_slice.is_empty() {
|
||||
unsafe { errno = EINVAL; }
|
||||
unsafe {
|
||||
errno = EINVAL;
|
||||
}
|
||||
return ptr::null_mut();
|
||||
}
|
||||
|
||||
if path::getcwd(buf_slice).is_none() {
|
||||
unsafe { errno = ERANGE; }
|
||||
return ptr::null_mut()
|
||||
unsafe {
|
||||
errno = ERANGE;
|
||||
}
|
||||
return ptr::null_mut();
|
||||
}
|
||||
|
||||
buf
|
||||
@@ -712,16 +714,17 @@ impl Pal for Sys {
|
||||
fn open(path: &CStr, oflag: c_int, mode: mode_t) -> c_int {
|
||||
let path = path_from_c_str!(path);
|
||||
|
||||
match path::open(path, ((oflag as usize) & 0xFFFF_0000) | ((mode as usize) & 0xFFFF)) {
|
||||
Ok(fd) => {
|
||||
match c_int::try_from(fd) {
|
||||
Ok(c_fd) => c_fd,
|
||||
Err(_) => {
|
||||
let _ = syscall::close(fd);
|
||||
e(Err(Error::new(EMFILE))) as c_int
|
||||
}
|
||||
match path::open(
|
||||
path,
|
||||
((oflag as usize) & 0xFFFF_0000) | ((mode as usize) & 0xFFFF),
|
||||
) {
|
||||
Ok(fd) => match c_int::try_from(fd) {
|
||||
Ok(c_fd) => c_fd,
|
||||
Err(_) => {
|
||||
let _ = syscall::close(fd);
|
||||
e(Err(Error::new(EMFILE))) as c_int
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(error) => e(Err(error)) as c_int,
|
||||
}
|
||||
}
|
||||
@@ -747,7 +750,10 @@ impl Pal for Sys {
|
||||
}
|
||||
|
||||
fn readlink(pathname: &CStr, out: &mut [u8]) -> ssize_t {
|
||||
match File::open(pathname, fcntl::O_RDONLY | fcntl::O_SYMLINK | fcntl::O_CLOEXEC) {
|
||||
match File::open(
|
||||
pathname,
|
||||
fcntl::O_RDONLY | fcntl::O_SYMLINK | fcntl::O_CLOEXEC,
|
||||
) {
|
||||
Ok(file) => Self::read(*file, out),
|
||||
Err(_) => return -1,
|
||||
}
|
||||
|
||||
+30
-26
@@ -1,11 +1,11 @@
|
||||
use syscall::data::Stat;
|
||||
use syscall::error::*;
|
||||
use syscall::flag::*;
|
||||
use syscall::{data::Stat, error::*, flag::*};
|
||||
|
||||
use alloc::borrow::{Cow, ToOwned};
|
||||
use alloc::boxed::Box;
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
use alloc::{
|
||||
borrow::{Cow, ToOwned},
|
||||
boxed::Box,
|
||||
string::String,
|
||||
vec::Vec,
|
||||
};
|
||||
|
||||
use super::FdGuard;
|
||||
use crate::sync::Mutex;
|
||||
@@ -25,7 +25,7 @@ pub fn canonicalize_using_cwd<'a>(cwd_opt: Option<&str>, path: &'a str) -> Optio
|
||||
|
||||
let mut canon = if !path.starts_with('/') {
|
||||
let mut c = cwd.to_owned();
|
||||
if ! c.ends_with('/') {
|
||||
if !c.ends_with('/') {
|
||||
c.push('/');
|
||||
}
|
||||
c
|
||||
@@ -41,7 +41,8 @@ pub fn canonicalize_using_cwd<'a>(cwd_opt: Option<&str>, path: &'a str) -> Optio
|
||||
|
||||
// NOTE: assumes the scheme does not include anything like "../" or "./"
|
||||
let mut result = {
|
||||
let parts = canon.split('/')
|
||||
let parts = canon
|
||||
.split('/')
|
||||
.rev()
|
||||
.scan(0, |nskip, part| {
|
||||
if part == "." {
|
||||
@@ -50,8 +51,8 @@ pub fn canonicalize_using_cwd<'a>(cwd_opt: Option<&str>, path: &'a str) -> Optio
|
||||
*nskip += 1;
|
||||
Some(None)
|
||||
} else if *nskip > 0 {
|
||||
*nskip -= 1;
|
||||
Some(None)
|
||||
*nskip -= 1;
|
||||
Some(None)
|
||||
} else {
|
||||
Some(Some(part))
|
||||
}
|
||||
@@ -59,21 +60,17 @@ pub fn canonicalize_using_cwd<'a>(cwd_opt: Option<&str>, path: &'a str) -> Optio
|
||||
.filter_map(|x| x)
|
||||
.filter(|x| !x.is_empty())
|
||||
.collect::<Vec<_>>();
|
||||
parts
|
||||
.iter()
|
||||
.rev()
|
||||
.fold(String::new(), |mut string, &part| {
|
||||
string.push_str(part);
|
||||
string.push('/');
|
||||
string
|
||||
})
|
||||
parts.iter().rev().fold(String::new(), |mut string, &part| {
|
||||
string.push_str(part);
|
||||
string.push('/');
|
||||
string
|
||||
})
|
||||
};
|
||||
result.pop(); // remove extra '/'
|
||||
|
||||
// replace with the root of the scheme if it's empty
|
||||
Some(if result.is_empty() {
|
||||
let pos = canon.find(':')
|
||||
.map_or(canon.len(), |p| p + 1);
|
||||
let pos = canon.find(':').map_or(canon.len(), |p| p + 1);
|
||||
canon.truncate(pos);
|
||||
canon
|
||||
} else {
|
||||
@@ -94,7 +91,8 @@ pub fn chdir(path: &str) -> Result<()> {
|
||||
let _siglock = SignalMask::lock();
|
||||
let mut cwd_guard = CWD.lock();
|
||||
|
||||
let canonicalized = canonicalize_using_cwd(cwd_guard.as_deref(), path).ok_or(Error::new(ENOENT))?;
|
||||
let canonicalized =
|
||||
canonicalize_using_cwd(cwd_guard.as_deref(), path).ok_or(Error::new(ENOENT))?;
|
||||
|
||||
let fd = syscall::open(&canonicalized, O_STAT | O_CLOEXEC)?;
|
||||
let mut stat = Stat::default();
|
||||
@@ -122,7 +120,9 @@ pub fn getcwd(buf: &mut [u8]) -> Option<usize> {
|
||||
let cwd = cwd_guard.as_deref().unwrap_or("").as_bytes();
|
||||
|
||||
// But is already checked not to be empty.
|
||||
if buf.len() - 1 < cwd.len() { return None; }
|
||||
if buf.len() - 1 < cwd.len() {
|
||||
return None;
|
||||
}
|
||||
|
||||
buf[..cwd.len()].copy_from_slice(&cwd);
|
||||
buf[cwd.len()..].fill(0_u8);
|
||||
@@ -153,7 +153,8 @@ pub struct SignalMask {
|
||||
impl SignalMask {
|
||||
pub fn lock() -> Self {
|
||||
let mut oldset = [0; 2];
|
||||
syscall::sigprocmask(syscall::SIG_SETMASK, Some(&[!0, !0]), Some(&mut oldset)).expect("failed to run sigprocmask");
|
||||
syscall::sigprocmask(syscall::SIG_SETMASK, Some(&[!0, !0]), Some(&mut oldset))
|
||||
.expect("failed to run sigprocmask");
|
||||
Self { oldset }
|
||||
}
|
||||
}
|
||||
@@ -180,11 +181,14 @@ pub fn open(path: &str, flags: usize) -> Result<usize> {
|
||||
|
||||
let bytes_read = syscall::read(*resolve_fd, &mut resolve_buf)?;
|
||||
// TODO: make resolve_buf PATH_MAX + 1 bytes?
|
||||
if bytes_read == resolve_buf.len() { return Err(Error::new(ENAMETOOLONG)); }
|
||||
if bytes_read == resolve_buf.len() {
|
||||
return Err(Error::new(ENAMETOOLONG));
|
||||
}
|
||||
|
||||
// If the symbolic link path is non-UTF8, it cannot be opened, and is thus
|
||||
// considered a "dangling symbolic link".
|
||||
path = core::str::from_utf8(&resolve_buf[..bytes_read]).map_err(|_| Error::new(ENOENT))?;
|
||||
path = core::str::from_utf8(&resolve_buf[..bytes_read])
|
||||
.map_err(|_| Error::new(ENOENT))?;
|
||||
}
|
||||
Err(other_error) => return Err(other_error),
|
||||
}
|
||||
|
||||
@@ -53,7 +53,9 @@ pub fn init_state() -> &'static State {
|
||||
}
|
||||
pub fn is_traceme(pid: pid_t) -> bool {
|
||||
// Skip special PIDs (<=0)
|
||||
if pid <= 0 { return false; }
|
||||
if pid <= 0 {
|
||||
return false;
|
||||
}
|
||||
File::open(
|
||||
&CString::new(format!("chan:ptrace-relibc/{}/traceme", pid)).unwrap(),
|
||||
fcntl::O_PATH,
|
||||
|
||||
@@ -1 +1 @@
|
||||
use crate::platform::{PalEpoll, Sys};
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ mod epoll;
|
||||
|
||||
#[test]
|
||||
fn access() {
|
||||
use crate::header::{errno, unistd};
|
||||
use crate::header::unistd;
|
||||
|
||||
//TODO: create test files
|
||||
assert_eq!(Sys::access(c_str!("not a file!"), unistd::F_OK), !0);
|
||||
@@ -69,7 +69,7 @@ fn clock_gettime() {
|
||||
|
||||
#[test]
|
||||
fn getrandom() {
|
||||
use crate::{header::sys_random, platform::types::ssize_t};
|
||||
use crate::platform::types::ssize_t;
|
||||
|
||||
let mut arrays = [[0; 32]; 32];
|
||||
for i in 1..arrays.len() {
|
||||
|
||||
Reference in New Issue
Block a user