Use ArrayString for Cwd
This commit is contained in:
+3
-3
@@ -379,15 +379,15 @@ pub unsafe fn init_inner(auxvs: Box<[[usize; 2]]>) {
|
||||
) {
|
||||
let cwd_bytes: &'static [u8] =
|
||||
unsafe { core::slice::from_raw_parts(cwd_ptr as *const u8, cwd_len) };
|
||||
if let (Ok(cwd_path), Some(cwd_fd)) = (
|
||||
core::str::from_utf8(cwd_bytes),
|
||||
if let (Ok(Ok(cwd_path)), Some(cwd_fd)) = (
|
||||
core::str::from_utf8(cwd_bytes).map(self::sys::path::CwdPath::from),
|
||||
(cwd_fd != usize::MAX).then(|| {
|
||||
FdGuard::new(cwd_fd)
|
||||
.to_upper()
|
||||
.expect("failed to move cwd fd to upper table")
|
||||
}),
|
||||
) {
|
||||
self::sys::path::set_cwd_manual(cwd_path.into(), cwd_fd);
|
||||
self::sys::path::set_cwd_manual(cwd_path, cwd_fd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ pub fn execve(
|
||||
return Err(Error::new(EPERM));
|
||||
}
|
||||
|
||||
let cwd: Box<[u8]> = super::path::clone_cwd().unwrap_or_default().into();
|
||||
let cwd = super::path::clone_cwd().unwrap_or_default();
|
||||
|
||||
// Path to interpreter binary and args if found
|
||||
let (interpreter_path, interpreter_args) = { parse_interpreter(&mut image_file)? };
|
||||
@@ -229,7 +229,7 @@ pub fn execve(
|
||||
let sigprocmask = redox_rt::signal::get_sigmask().unwrap();
|
||||
|
||||
let extrainfo = ExtraInfo {
|
||||
cwd: Some(&cwd),
|
||||
cwd: Some(cwd.as_bytes()),
|
||||
sigignmask: redox_rt::signal::get_sigignmask_to_inherit(),
|
||||
sigprocmask,
|
||||
umask: redox_rt::sys::get_umask(),
|
||||
|
||||
+22
-20
@@ -59,7 +59,10 @@ use crate::{
|
||||
out::Out,
|
||||
platform::{
|
||||
ERRNO, free,
|
||||
sys::timer::{TIMERS, timer_routine, timer_update_wake_time},
|
||||
sys::{
|
||||
path::{CwdPath, to_cwd_path},
|
||||
timer::{TIMERS, timer_routine, timer_update_wake_time},
|
||||
},
|
||||
},
|
||||
sync::rwlock::RwLock,
|
||||
};
|
||||
@@ -1208,11 +1211,8 @@ impl Pal for Sys {
|
||||
) -> Result<pid_t> {
|
||||
use crate::header::spawn::Flags;
|
||||
let child = redox_rt::proc::new_child_process(&redox_rt::proc::ForkArgs::Managed)?;
|
||||
let mut cwd: Box<[u8]> = path::clone_cwd().unwrap_or_default().into();
|
||||
let mut cwd_fd = {
|
||||
let cwd_str = core::str::from_utf8(&cwd).map_err(|_| Errno(EINVAL))?;
|
||||
FdGuard::open(cwd_str, syscall::O_STAT)?.to_upper()?
|
||||
};
|
||||
let mut cwd = path::clone_cwd().unwrap_or_default();
|
||||
let mut cwd_fd = FdGuard::open(cwd.as_str(), syscall::O_STAT)?.to_upper()?;
|
||||
let proc_fd = child.proc_fd.unwrap();
|
||||
let curr_proc_fd = redox_rt::current_proc_fd();
|
||||
let file_table = RtTcb::current()
|
||||
@@ -1254,8 +1254,7 @@ impl Pal for Sys {
|
||||
let dirfd = {
|
||||
// TODO: Cannot use cwd_fd (being an upper fd), also
|
||||
// cannot set cwd_fd as regular fd then call to_upper later
|
||||
let cwd_str = core::str::from_utf8(&cwd).map_err(|_| Errno(EINVAL))?;
|
||||
FdGuard::open(cwd_str, syscall::O_STAT)?
|
||||
FdGuard::open(cwd.as_str(), syscall::O_STAT)?
|
||||
};
|
||||
let src_fd = Sys::openat(
|
||||
dirfd.as_c_fd().ok_or(Errno(EMFILE))?,
|
||||
@@ -1278,17 +1277,21 @@ impl Pal for Sys {
|
||||
)?;
|
||||
}
|
||||
crate::header::spawn::Action::Chdir(path) => {
|
||||
cwd = Box::from(path.as_bytes());
|
||||
let cwd_str = core::str::from_utf8(&cwd).map_err(|_| Errno(EINVAL))?;
|
||||
let fd = FdGuard::open(cwd_str, syscall::O_STAT)?.to_upper()?;
|
||||
let cwd_str =
|
||||
core::str::from_utf8(path.as_bytes()).map_err(|_| Errno(EINVAL))?;
|
||||
cwd = to_cwd_path(cwd_str)?;
|
||||
let fd = FdGuard::open(cwd.as_str(), syscall::O_STAT)?.to_upper()?;
|
||||
cwd_fd = fd;
|
||||
}
|
||||
crate::header::spawn::Action::FChdir(fd) => {
|
||||
let mut buf = [0_u8; limits::PATH_MAX];
|
||||
let res = Sys::fpath(fd, &mut buf)?;
|
||||
cwd = Box::from(&buf[..res]);
|
||||
let cwd_str = core::str::from_utf8(&cwd).map_err(|_| Errno(EINVAL))?;
|
||||
let fd = FdGuard::open(cwd_str, syscall::O_STAT)?.to_upper()?;
|
||||
let mut buf = CwdPath::zero_filled();
|
||||
unsafe {
|
||||
// SAFETY: Sys::fpath is using str::from_utf8 already
|
||||
let res = Sys::fpath(fd, buf.as_bytes_mut())?;
|
||||
buf.set_len(res);
|
||||
}
|
||||
cwd = buf;
|
||||
let fd = FdGuard::open(cwd.as_str(), syscall::O_STAT)?.to_upper()?;
|
||||
cwd_fd = fd;
|
||||
}
|
||||
crate::header::spawn::Action::Dup2(old, new) => {
|
||||
@@ -1309,8 +1312,7 @@ impl Pal for Sys {
|
||||
let dirfd = {
|
||||
// TODO: Cannot use cwd_fd (being an upper fd), also
|
||||
// cannot set cwd_fd as regular fd then call to_upper later
|
||||
let cwd_str = core::str::from_utf8(&cwd).map_err(|_| Errno(EINVAL))?;
|
||||
FdGuard::open(cwd_str, syscall::O_STAT)?
|
||||
FdGuard::open(cwd.as_str(), syscall::O_STAT)?
|
||||
};
|
||||
|
||||
let executable = Sys::openat(
|
||||
@@ -1330,7 +1332,7 @@ impl Pal for Sys {
|
||||
// .map(|s| str::from_utf8(s).unwrap_or("???"))
|
||||
// .collect::<Vec<_>>()
|
||||
// .as_slice(),
|
||||
// str::from_utf8(&cwd).unwrap_or("???")
|
||||
// cwd.as_bytes()
|
||||
// );
|
||||
|
||||
new_file_table.call_wo(
|
||||
@@ -1340,7 +1342,7 @@ impl Pal for Sys {
|
||||
)?;
|
||||
|
||||
let extra_info = redox_rt::proc::ExtraInfo {
|
||||
cwd: Some(&cwd),
|
||||
cwd: Some(cwd.as_bytes()),
|
||||
// Signals set to be ignored by the calling process
|
||||
// must also be ignored by the child process
|
||||
sigignmask: redox_rt::signal::get_sigignmask_to_inherit(),
|
||||
|
||||
+23
-15
@@ -1,11 +1,14 @@
|
||||
use alloc::{
|
||||
boxed::Box,
|
||||
collections::btree_set::BTreeSet,
|
||||
ffi::CString,
|
||||
string::{String, ToString},
|
||||
vec::Vec,
|
||||
};
|
||||
use core::{ffi::c_int, str};
|
||||
use arrayvec::ArrayString;
|
||||
use core::{
|
||||
ffi::c_int,
|
||||
str::{self, FromStr},
|
||||
};
|
||||
use redox_rt::{proc::FdGuardUpper, signal::tmp_disable_signals};
|
||||
use syscall::{data::Stat, error::*, flag::*};
|
||||
|
||||
@@ -105,7 +108,7 @@ pub fn chdir(path: &str) -> Result<()> {
|
||||
let canon = canonicalize_using_cwd(cwd_guard.as_ref().map(|c| c.path.as_ref()), &path)
|
||||
.ok_or(Error::new(ENOENT))?;
|
||||
*cwd_guard = Some(Cwd {
|
||||
path: canon.into_boxed_str(),
|
||||
path: to_cwd_path(&canon)?,
|
||||
fd,
|
||||
});
|
||||
} else {
|
||||
@@ -120,7 +123,7 @@ pub fn chdir(path: &str) -> Result<()> {
|
||||
}
|
||||
|
||||
*cwd_guard = Some(Cwd {
|
||||
path: path.into_boxed_str(),
|
||||
path: to_cwd_path(&path)?,
|
||||
fd,
|
||||
});
|
||||
}
|
||||
@@ -129,12 +132,12 @@ pub fn chdir(path: &str) -> Result<()> {
|
||||
}
|
||||
|
||||
pub fn fchdir(fd: c_int) -> Result<()> {
|
||||
let mut buf = [0_u8; limits::PATH_MAX];
|
||||
let res = Sys::fpath(fd, &mut buf)?;
|
||||
|
||||
let path = core::str::from_utf8(&buf[..res])
|
||||
.map_err(|_| Errno(EINVAL))?
|
||||
.to_string();
|
||||
let mut buf = CwdPath::zero_filled();
|
||||
unsafe {
|
||||
// SAFETY: Sys::fpath is using str::from_utf8 already
|
||||
let res = Sys::fpath(fd, buf.as_bytes_mut())?;
|
||||
buf.set_len(res);
|
||||
}
|
||||
let fd = FdGuard::new(syscall::fcntl(
|
||||
fd as usize,
|
||||
syscall::F_DUPFD,
|
||||
@@ -142,7 +145,7 @@ pub fn fchdir(fd: c_int) -> Result<()> {
|
||||
)?)
|
||||
.to_upper()
|
||||
.unwrap();
|
||||
set_cwd_manual(path.into_boxed_str(), fd);
|
||||
set_cwd_manual(buf, fd);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -209,20 +212,25 @@ pub fn canonicalize(path: &str) -> Result<String> {
|
||||
canonicalize_with_cwd_internal(cwd_guard.as_ref().map(|c| c.path.as_ref()), path)
|
||||
}
|
||||
|
||||
pub type CwdPath = ArrayString<{ limits::PATH_MAX }>;
|
||||
|
||||
pub struct Cwd {
|
||||
pub path: Box<str>,
|
||||
pub path: CwdPath,
|
||||
pub fd: FdGuardUpper,
|
||||
}
|
||||
|
||||
// TODO: arraystring?
|
||||
static CWD: RwLock<Option<Cwd>> = RwLock::new(None);
|
||||
|
||||
pub fn set_cwd_manual(path: Box<str>, fd: FdGuardUpper) {
|
||||
pub fn to_cwd_path(path: &str) -> Result<CwdPath> {
|
||||
ArrayString::from_str(&path).or(Err(Error::new(ENAMETOOLONG)))
|
||||
}
|
||||
|
||||
pub fn set_cwd_manual(path: CwdPath, fd: FdGuardUpper) {
|
||||
let _siglock = tmp_disable_signals();
|
||||
*CWD.write() = Some(Cwd { path, fd });
|
||||
}
|
||||
|
||||
pub fn clone_cwd() -> Option<Box<str>> {
|
||||
pub fn clone_cwd() -> Option<CwdPath> {
|
||||
let _siglock = tmp_disable_signals();
|
||||
CWD.read().as_ref().map(|cwd| cwd.path.clone())
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
getcwd: /usr
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "test_helpers.h"
|
||||
|
||||
@@ -17,4 +18,9 @@ int main(void) {
|
||||
int c = close(fd);
|
||||
ERROR_IF(close, c, == -1);
|
||||
UNEXP_IF(close, c, != 0);
|
||||
|
||||
char cwd[PATH_MAX];
|
||||
char* cw = getcwd(cwd, sizeof(cwd));
|
||||
ERROR_IF(getcwd, cw, == NULL);
|
||||
printf("getcwd: %s\n", cwd);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user