Implement fpath in initfs
This commit is contained in:
parent
d5ac1a70bd
commit
0d762918e2
4
Makefile
4
Makefile
|
@ -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 \
|
||||
|
|
|
@ -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))?;
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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),
|
||||
_ => {
|
||||
|
|
Loading…
Reference in a new issue