Implement fpath in initfs

This commit is contained in:
Jeremy Soller 2016-09-22 21:13:17 -06:00
parent d5ac1a70bd
commit 0d762918e2
4 changed files with 65 additions and 12 deletions

View file

@ -30,6 +30,7 @@ clean:
cargo clean --manifest-path programs/init/Cargo.toml
cargo clean --manifest-path programs/ion/Cargo.toml
cargo clean --manifest-path programs/login/Cargo.toml
cargo clean --manifest-path programs/coreutils/Cargo.toml
cargo clean --manifest-path schemes/example/Cargo.toml
rm -rf initfs/bin
rm -rf build
@ -163,7 +164,8 @@ coreutils: \
initfs/bin/env \
initfs/bin/ls \
initfs/bin/printenv \
initfs/bin/pwd
initfs/bin/pwd \
initfs/bin/realpath
$(BUILD)/initfs.rs: \
initfs/bin/pcid \

View file

@ -12,6 +12,7 @@ use syscall::scheme::Scheme;
mod gen;
struct Handle {
path: &'static [u8],
data: &'static [u8],
mode: u16,
seek: usize
@ -35,28 +36,37 @@ impl InitFsScheme {
impl Scheme for InitFsScheme {
fn open(&self, path: &[u8], _flags: usize) -> Result<usize> {
let path = str::from_utf8(path).map_err(|_err| Error::new(ENOENT))?.trim_matches('/');
let file = self.files.get(path.as_bytes()).ok_or(Error::new(ENOENT))?;
let path_utf8 = str::from_utf8(path).map_err(|_err| Error::new(ENOENT))?;
let path_trimmed = path_utf8.trim_matches('/');
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
self.handles.write().insert(id, Handle {
data: file.0,
mode: if file.1 { MODE_DIR } else { MODE_FILE },
seek: 0
});
//Have to iterate to get the path without allocation
for entry in self.files.iter() {
if entry.0 == &path_trimmed.as_bytes() {
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
self.handles.write().insert(id, Handle {
path: entry.0,
data: (entry.1).0,
mode: if (entry.1).1 { MODE_DIR } else { MODE_FILE },
seek: 0
});
Ok(id)
return Ok(id)
}
}
Err(Error::new(ENOENT))
}
fn dup(&self, id: usize) -> Result<usize> {
let (data, mode, seek) = {
let (path, data, mode, seek) = {
let handles = self.handles.read();
let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
(handle.data, handle.mode, handle.seek)
(handle.path, handle.data, handle.mode, handle.seek)
};
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
self.handles.write().insert(id, Handle {
path: path,
data: data,
mode: mode,
seek: seek
@ -93,6 +103,28 @@ impl Scheme for InitFsScheme {
Ok(handle.seek)
}
fn fpath(&self, id: usize, buf: &mut [u8]) -> Result<usize> {
let handles = self.handles.read();
let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
//TODO: Copy scheme part in kernel
let mut i = 0;
let scheme_path = b"initfs:";
while i < buf.len() && i < scheme_path.len() {
buf[i] = scheme_path[i];
i += 1;
}
let mut j = 0;
while i < buf.len() && j < handle.path.len() {
buf[i] = handle.path[j];
i += 1;
j += 1;
}
Ok(i)
}
fn fstat(&self, id: usize, stat: &mut Stat) -> Result<usize> {
let handles = self.handles.read();
let handle = handles.get(&id).ok_or(Error::new(EBADF))?;

View file

@ -98,6 +98,24 @@ pub fn dup(fd: usize) -> Result<usize> {
scheme.dup(file.number)
}
/// Get the canonical path of the file
pub fn fpath(fd: usize, buf: &mut [u8]) -> Result<usize> {
let file = {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
let context = context_lock.read();
let file = context.get_file(fd).ok_or(Error::new(EBADF))?;
file
};
let scheme = {
let schemes = scheme::schemes();
let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?;
scheme.clone()
};
scheme.fpath(file.number, buf)
}
/// Get information about the file
pub fn fstat(fd: usize, stat: &mut Stat) -> Result<usize> {
let file = {

View file

@ -44,6 +44,7 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize
SYS_CLONE => clone(b, stack),
SYS_YIELD => sched_yield(),
SYS_GETCWD => getcwd(validate_slice_mut(b as *mut u8, c)?),
SYS_FPATH => fpath(b, validate_slice_mut(c as *mut u8, d)?),
SYS_PHYSMAP => physmap(b, c, d),
SYS_PHYSUNMAP => physunmap(b),
_ => {