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/init/Cargo.toml
|
||||||
cargo clean --manifest-path programs/ion/Cargo.toml
|
cargo clean --manifest-path programs/ion/Cargo.toml
|
||||||
cargo clean --manifest-path programs/login/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
|
cargo clean --manifest-path schemes/example/Cargo.toml
|
||||||
rm -rf initfs/bin
|
rm -rf initfs/bin
|
||||||
rm -rf build
|
rm -rf build
|
||||||
|
@ -163,7 +164,8 @@ coreutils: \
|
||||||
initfs/bin/env \
|
initfs/bin/env \
|
||||||
initfs/bin/ls \
|
initfs/bin/ls \
|
||||||
initfs/bin/printenv \
|
initfs/bin/printenv \
|
||||||
initfs/bin/pwd
|
initfs/bin/pwd \
|
||||||
|
initfs/bin/realpath
|
||||||
|
|
||||||
$(BUILD)/initfs.rs: \
|
$(BUILD)/initfs.rs: \
|
||||||
initfs/bin/pcid \
|
initfs/bin/pcid \
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
||||||
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
|
||||||
|
});
|
||||||
|
|
||||||
Ok(id)
|
return 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 {
|
||||||
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> {
|
||||||
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
|
||||||
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),
|
||||||
_ => {
|
_ => {
|
||||||
|
|
Loading…
Reference in a new issue