Skip to content
Snippets Groups Projects
Commit 879d582e authored by Jeremy Soller's avatar Jeremy Soller
Browse files

Implement fpath in initfs

parent bbacabce
No related branches found
No related tags found
No related merge requests found
...@@ -12,6 +12,7 @@ use syscall::scheme::Scheme; ...@@ -12,6 +12,7 @@ use syscall::scheme::Scheme;
mod gen; mod gen;
struct Handle { struct Handle {
path: &'static [u8],
data: &'static [u8], data: &'static [u8],
mode: u16, mode: u16,
seek: usize seek: usize
...@@ -35,28 +36,37 @@ impl InitFsScheme { ...@@ -35,28 +36,37 @@ impl InitFsScheme {
impl Scheme for InitFsScheme { impl Scheme for InitFsScheme {
fn open(&self, path: &[u8], _flags: usize) -> Result<usize> { fn open(&self, path: &[u8], _flags: usize) -> Result<usize> {
let path = str::from_utf8(path).map_err(|_err| Error::new(ENOENT))?.trim_matches('/'); let path_utf8 = str::from_utf8(path).map_err(|_err| Error::new(ENOENT))?;
let file = self.files.get(path.as_bytes()).ok_or(Error::new(ENOENT))?; let path_trimmed = path_utf8.trim_matches('/');
let id = self.next_id.fetch_add(1, Ordering::SeqCst); //Have to iterate to get the path without allocation
self.handles.write().insert(id, Handle { for entry in self.files.iter() {
data: file.0, if entry.0 == &path_trimmed.as_bytes() {
mode: if file.1 { MODE_DIR } else { MODE_FILE }, let id = self.next_id.fetch_add(1, Ordering::SeqCst);
seek: 0 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
});
return Ok(id)
}
}
Ok(id) Err(Error::new(ENOENT))
} }
fn dup(&self, id: usize) -> Result<usize> { fn dup(&self, id: usize) -> Result<usize> {
let (data, mode, seek) = { let (path, data, mode, seek) = {
let handles = self.handles.read(); let handles = self.handles.read();
let handle = handles.get(&id).ok_or(Error::new(EBADF))?; 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); let id = self.next_id.fetch_add(1, Ordering::SeqCst);
self.handles.write().insert(id, Handle { self.handles.write().insert(id, Handle {
path: path,
data: data, data: data,
mode: mode, mode: mode,
seek: seek seek: seek
...@@ -93,6 +103,28 @@ impl Scheme for InitFsScheme { ...@@ -93,6 +103,28 @@ impl Scheme for InitFsScheme {
Ok(handle.seek) 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> { fn fstat(&self, id: usize, stat: &mut Stat) -> Result<usize> {
let handles = self.handles.read(); let handles = self.handles.read();
let handle = handles.get(&id).ok_or(Error::new(EBADF))?; let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
......
...@@ -98,6 +98,24 @@ pub fn dup(fd: usize) -> Result<usize> { ...@@ -98,6 +98,24 @@ pub fn dup(fd: usize) -> Result<usize> {
scheme.dup(file.number) 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 /// Get information about the file
pub fn fstat(fd: usize, stat: &mut Stat) -> Result<usize> { pub fn fstat(fd: usize, stat: &mut Stat) -> Result<usize> {
let file = { let file = {
......
...@@ -44,6 +44,7 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize ...@@ -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_CLONE => clone(b, stack),
SYS_YIELD => sched_yield(), SYS_YIELD => sched_yield(),
SYS_GETCWD => getcwd(validate_slice_mut(b as *mut u8, c)?), 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_PHYSMAP => physmap(b, c, d),
SYS_PHYSUNMAP => physunmap(b), SYS_PHYSUNMAP => physunmap(b),
_ => { _ => {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment