Implement O_DIRECTORY, switch to open for mkdir

This commit is contained in:
Jeremy Soller 2016-11-25 18:24:38 -07:00
parent 09fb7d1d69
commit c018bfe5ef
10 changed files with 33 additions and 44 deletions

View file

@ -93,9 +93,9 @@ pub fn cpu_count() -> usize {
pub extern fn userspace_init() {
assert_eq!(syscall::chdir(b"initfs:bin"), Ok(0));
assert_eq!(syscall::open(b"debug:", 0).map(FileHandle::into), Ok(0));
assert_eq!(syscall::open(b"debug:", 0).map(FileHandle::into), Ok(1));
assert_eq!(syscall::open(b"debug:", 0).map(FileHandle::into), Ok(2));
assert_eq!(syscall::open(b"debug:", syscall::flag::O_RDONLY).map(FileHandle::into), Ok(0));
assert_eq!(syscall::open(b"debug:", syscall::flag::O_WRONLY).map(FileHandle::into), Ok(1));
assert_eq!(syscall::open(b"debug:", syscall::flag::O_WRONLY).map(FileHandle::into), Ok(2));
syscall::exec(b"initfs:bin/init", &[]).expect("failed to execute initfs:init");

View file

@ -224,14 +224,6 @@ impl Scheme for UserScheme {
result
}
fn mkdir(&self, path: &[u8], mode: u16, _uid: u32, _gid: u32) -> Result<usize> {
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
let address = inner.capture(path)?;
let result = inner.call(SYS_MKDIR, address, path.len(), mode as usize);
let _ = inner.release(address);
result
}
fn chmod(&self, path: &[u8], mode: u16, _uid: u32, _gid: u32) -> Result<usize> {
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
let address = inner.capture(path)?;

View file

@ -49,7 +49,7 @@ pub fn file_op_mut_slice(a: usize, fd: FileHandle, slice: &mut [u8]) -> Result<u
/// Change the current working directory
pub fn chdir(path: &[u8]) -> Result<usize> {
let fd = open(path, 0)?;
let fd = open(path, syscall::flag::O_RDONLY | syscall::flag::O_DIRECTORY)?;
let mut stat = Stat::default();
let stat_res = file_op_mut_slice(syscall::number::SYS_FSTAT, fd, &mut stat);
let _ = close(fd);
@ -144,28 +144,6 @@ pub fn pipe2(fds: &mut [usize], flags: usize) -> Result<usize> {
}
}
/// mkdir syscall
pub fn mkdir(path: &[u8], mode: u16) -> Result<usize> {
let (path_canon, uid, gid, scheme_ns) = {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
let context = context_lock.read();
(context.canonicalize(path), context.euid, context.egid, context.ens)
};
let mut parts = path_canon.splitn(2, |&b| b == b':');
let scheme_name_opt = parts.next();
let reference_opt = parts.next();
let scheme_name = scheme_name_opt.ok_or(Error::new(ENODEV))?;
let scheme = {
let schemes = scheme::schemes();
let (_scheme_id, scheme) = schemes.get_name(scheme_ns, scheme_name).ok_or(Error::new(ENODEV))?;
scheme.clone()
};
scheme.mkdir(reference_opt.unwrap_or(b""), mode, uid, gid)
}
/// chmod syscall
pub fn chmod(path: &[u8], mode: u16) -> Result<usize> {
let (path_canon, uid, gid, scheme_ns) = {

View file

@ -61,7 +61,6 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize
},
SYS_CLASS_PATH => match a {
SYS_OPEN => open(validate_slice(b as *const u8, c)?, d).map(FileHandle::into),
SYS_MKDIR => mkdir(validate_slice(b as *const u8, c)?, d as u16),
SYS_CHMOD => chmod(validate_slice(b as *const u8, c)?, d as u16),
SYS_RMDIR => rmdir(validate_slice(b as *const u8, c)?),
SYS_UNLINK => unlink(validate_slice(b as *const u8, c)?),

View file

@ -468,7 +468,7 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
(context.euid, context.egid, context.canonicalize(path))
};
let file = syscall::open(&canonical, 0)?;
let file = syscall::open(&canonical, syscall::flag::O_RDONLY)?;
let mut stat = Stat::default();
syscall::file_op_mut_slice(syscall::number::SYS_FSTAT, file, &mut stat)?;

View file

@ -9,7 +9,7 @@ pub use self::syscall::error::*;
pub use self::syscall::flag::*;
pub use self::syscall::{
clock_gettime, clone, execve as exec, exit, futex, getpid, kill, nanosleep, setregid, setreuid, waitpid,
chdir, chmod, getcwd, open, mkdir, rmdir, unlink, dup, pipe2,
chdir, chmod, getcwd, open, rmdir, unlink, dup, pipe2,
read, write, fcntl, fpath, fstat, fsync, ftruncate, lseek, close
};

View file

@ -1,13 +1,13 @@
extern crate syscall;
use std::env;
use std::{env, thread};
use std::os::unix::process::CommandExt;
use std::process::Command;
pub fn main() {
let mut args = env::args().skip(1);
let root = args.next();
let root_opt = args.next();
let cmd = args.next().unwrap_or("sh".to_string());
@ -17,7 +17,7 @@ pub fn main() {
"udp"
];
if root.is_none() {
if root_opt.is_none() {
names.push("file");
}
@ -28,6 +28,26 @@ pub fn main() {
let new_ns = syscall::mkns(&name_ptrs).unwrap();
let root_thread = if let Some(root) = root_opt {
Some(thread::spawn(move || {
syscall::setrens(-1isize as usize, new_ns).unwrap();
let scheme_fd = syscall::open(":file", syscall::O_CREAT | syscall::O_RDWR | syscall::O_CLOEXEC).unwrap();
syscall::setrens(-1isize as usize, syscall::getns().unwrap()).unwrap();
loop {
let mut packet = syscall::Packet::default();
if syscall::read(scheme_fd, &mut packet).unwrap() == 0 {
break;
}
println!("{:?}", packet);
}
let _ = syscall::close(scheme_fd);
}))
} else {
None
};
let pid = unsafe { syscall::clone(0).unwrap() };
if pid == 0 {
syscall::setrens(new_ns, new_ns).unwrap();

2
rust

@ -1 +1 @@
Subproject commit 6733074c847767fd3e0425fcefb73226bde1f6a1
Subproject commit 3a1bb2ba26a85bbea4c9be813a9a13d48ab448ac

@ -1 +1 @@
Subproject commit dcaf5c76be265bbfa5013cf131f14fa79680a634
Subproject commit 25fe6d382641184b447645d6a784316652eaed95

@ -1 +1 @@
Subproject commit 2835586ee671b0777ef1a98ced9237269c472941
Subproject commit 1908eea7e91142a058ae99c06edb2a9dd7efd692