Commit dc0b0c5c authored by Jeremy Soller's avatar Jeremy Soller

Fix compilation on Redox

parent dfd2dd8a
......@@ -4,6 +4,9 @@
#[cfg(unix)]
extern crate libc;
#[cfg(target_os = "redox")]
extern crate syscall;
extern crate redoxfs;
use std::env;
......@@ -33,11 +36,6 @@ fn pipe(pipes: &mut [usize; 2]) -> isize {
syscall::Error::mux(syscall::pipe2(pipes, 0)) as isize
}
#[cfg(target_os = "redox")]
fn mount<P: AsRef<Path>>(filesystem: redoxfs::FileSystem, mountpoint: &P, write: File) {
redox::mount(filesystem, mountpoint, write);
}
fn usage() {
println!("redoxfs [disk] [mountpoint]");
}
......@@ -62,13 +60,15 @@ fn main() {
println!("redoxfs: opened filesystem {}", path);
if let Some(mountpoint) = env::args().nth(2) {
match mount(filesystem, &mountpoint, write) {
match mount(filesystem, &mountpoint, || {
println!("redoxfs: mounted filesystem on {}:", mountpoint);
let _ = write.write(&[0]);
}) {
Ok(()) => {
process::exit(0);
},
Err(err) => {
println!("redoxfs: failed to mount {} to {}: {}", path, mountpoint, err);
process::exit(1);
}
}
} else {
......@@ -82,7 +82,6 @@ fn main() {
}
let _ = write.write(&[1]);
drop(write);
process::exit(1);
} else {
println!("redoxfs: no disk image provided");
......
......@@ -2,8 +2,7 @@ extern crate fuse;
extern crate time;
use std::ffi::OsStr;
use std::fs::File;
use std::io::{self, Write};
use std::io;
use std::os::unix::ffi::OsStrExt;
use std::path::Path;
use std::time::{SystemTime, UNIX_EPOCH};
......@@ -19,13 +18,12 @@ const TTL: Timespec = Timespec { sec: 1, nsec: 0 }; // 1 second
const NULL_TIME: Timespec = Timespec { sec: 0, nsec: 0 };
pub fn mount<D: Disk, P: AsRef<Path>>(filesystem: filesystem::FileSystem<D>, mountpoint: &P, mut write: File, options: &[&OsStr]) -> io::Result<()> {
pub fn mount<D: Disk, P: AsRef<Path>, F: FnMut()>(filesystem: filesystem::FileSystem<D>, mountpoint: &P, mut callback: F, options: &[&OsStr]) -> io::Result<()> {
let mut session = Session::new(Fuse {
fs: filesystem
}, mountpoint.as_ref(), options)?;
let _ = write.write(&[0]);
drop(write);
callback();
session.run()
}
......
use std::io;
use std::fs::File;
use std::path::Path;
use disk::Disk;
......@@ -12,10 +11,10 @@ mod fuse;
mod redox;
#[cfg(all(unix, target_os = "macos"))]
pub fn mount<D: Disk, P: AsRef<Path>>(filesystem: FileSystem<D>, mountpoint: &P, write: File) -> io::Result<()> {
pub fn mount<D: Disk, P: AsRef<Path>, F: FnMut()>(filesystem: FileSystem<D>, mountpoint: &P, callback: F) -> io::Result<()> {
use std::ffi::OsStr;
fuse::mount(filesystem, mountpoint, write, &[
fuse::mount(filesystem, mountpoint, callback, &[
// One of the uses of this redoxfs fuse wrapper is to populate a filesystem
// while building the Redox OS kernel. This means that we need to write on
// a filesystem that belongs to `root`, which in turn means that we need to
......@@ -26,11 +25,11 @@ pub fn mount<D: Disk, P: AsRef<Path>>(filesystem: FileSystem<D>, mountpoint: &P,
}
#[cfg(all(unix, not(target_os = "macos")))]
pub fn mount<D: Disk, P: AsRef<Path>>(filesystem: FileSystem<D>, mountpoint: &P, write: File) -> io::Result<()> {
fuse::mount(filesystem, mountpoint, write, &[])
pub fn mount<D: Disk, P: AsRef<Path>, F: FnMut()>(filesystem: FileSystem<D>, mountpoint: &P, callback: F) -> io::Result<()> {
fuse::mount(filesystem, mountpoint, callback, &[])
}
#[cfg(target_os = "redox")]
pub fn mount<D: Disk, P: AsRef<Path>>(filesystem: FileSystem<D>, mountpoint: &P, write: File) -> io::Result<()> {
redox::mount(filesystem, mountpoint, write)
pub fn mount<D: Disk, P: AsRef<Path>, F: FnMut()>(filesystem: FileSystem<D>, mountpoint: &P, callback: F) -> io::Result<()> {
redox::mount(filesystem, mountpoint, callback)
}
......@@ -6,20 +6,18 @@ use std::io::{self, Read, Write};
use std::path::Path;
use disk::Disk;
use filesystem::FileSystem;
use self::scheme::FileScheme;
pub mod resource;
pub mod scheme;
pub fn mount<D: Disk, P: AsRef<Path>>(filesystem: filesystem::FileSystem<D>, mountpoint: &P, mut write: File) -> io::Result<()> {
pub fn mount<D: Disk, P: AsRef<Path>, F: FnMut()>(filesystem: FileSystem<D>, mountpoint: &P, mut callback: F) -> io::Result<()> {
let mountpoint = mountpoint.as_ref();
let mut socket = File::create(format!(":{}", mountpoint.display()))?;
println!("redoxfs: mounted filesystem on {}:", mountpoint.display());
let _ = write.write(&[0]);
drop(write);
callback();
let scheme = FileScheme::new(format!("{}", mountpoint.display()), filesystem);
loop {
......@@ -28,6 +26,4 @@ pub fn mount<D: Disk, P: AsRef<Path>>(filesystem: filesystem::FileSystem<D>, mou
scheme.handle(&mut packet);
socket.write(&packet).unwrap();
}
Ok(())
}
use redoxfs::FileSystem;
use std::cmp::{min, max};
use std::time::{SystemTime, UNIX_EPOCH};
......@@ -8,17 +6,20 @@ use syscall::error::{Error, Result, EBADF, EINVAL, EISDIR};
use syscall::flag::{O_ACCMODE, O_RDONLY, O_WRONLY, O_RDWR, F_GETFL, F_SETFL};
use syscall::{Stat, SEEK_SET, SEEK_CUR, SEEK_END};
pub trait Resource {
fn dup(&self) -> Result<Box<Resource>>;
fn read(&mut self, buf: &mut [u8], fs: &mut FileSystem) -> Result<usize>;
fn write(&mut self, buf: &[u8], fs: &mut FileSystem) -> Result<usize>;
fn seek(&mut self, offset: usize, whence: usize, fs: &mut FileSystem) -> Result<usize>;
use disk::Disk;
use filesystem::FileSystem;
pub trait Resource<D: Disk> {
fn dup(&self) -> Result<Box<Resource<D>>>;
fn read(&mut self, buf: &mut [u8], fs: &mut FileSystem<D>) -> Result<usize>;
fn write(&mut self, buf: &[u8], fs: &mut FileSystem<D>) -> Result<usize>;
fn seek(&mut self, offset: usize, whence: usize, fs: &mut FileSystem<D>) -> Result<usize>;
fn fcntl(&mut self, cmd: usize, arg: usize) -> Result<usize>;
fn path(&self, buf: &mut [u8]) -> Result<usize>;
fn stat(&self, _stat: &mut Stat, fs: &mut FileSystem) -> Result<usize>;
fn stat(&self, _stat: &mut Stat, fs: &mut FileSystem<D>) -> Result<usize>;
fn sync(&mut self) -> Result<usize>;
fn truncate(&mut self, len: usize, fs: &mut FileSystem) -> Result<usize>;
fn utimens(&mut self, times: &[TimeSpec], fs: &mut FileSystem) -> Result<usize>;
fn truncate(&mut self, len: usize, fs: &mut FileSystem<D>) -> Result<usize>;
fn utimens(&mut self, times: &[TimeSpec], fs: &mut FileSystem<D>) -> Result<usize>;
}
pub struct DirResource {
......@@ -39,8 +40,8 @@ impl DirResource {
}
}
impl Resource for DirResource {
fn dup(&self) -> Result<Box<Resource>> {
impl<D: Disk> Resource<D> for DirResource {
fn dup(&self) -> Result<Box<Resource<D>>> {
Ok(Box::new(DirResource {
path: self.path.clone(),
block: self.block,
......@@ -49,7 +50,7 @@ impl Resource for DirResource {
}))
}
fn read(&mut self, buf: &mut [u8], _fs: &mut FileSystem) -> Result<usize> {
fn read(&mut self, buf: &mut [u8], _fs: &mut FileSystem<D>) -> Result<usize> {
let data = self.data.as_ref().ok_or(Error::new(EISDIR))?;
let mut i = 0;
while i < buf.len() && self.seek < data.len() {
......@@ -60,11 +61,11 @@ impl Resource for DirResource {
Ok(i)
}
fn write(&mut self, _buf: &[u8], _fs: &mut FileSystem) -> Result<usize> {
fn write(&mut self, _buf: &[u8], _fs: &mut FileSystem<D>) -> Result<usize> {
Err(Error::new(EBADF))
}
fn seek(&mut self, offset: usize, whence: usize, _fs: &mut FileSystem) -> Result<usize> {
fn seek(&mut self, offset: usize, whence: usize, _fs: &mut FileSystem<D>) -> Result<usize> {
let data = self.data.as_ref().ok_or(Error::new(EBADF))?;
self.seek = match whence {
SEEK_SET => max(0, min(data.len() as isize, offset as isize)) as usize,
......@@ -92,7 +93,7 @@ impl Resource for DirResource {
Ok(i)
}
fn stat(&self, stat: &mut Stat, fs: &mut FileSystem) -> Result<usize> {
fn stat(&self, stat: &mut Stat, fs: &mut FileSystem<D>) -> Result<usize> {
let node = fs.node(self.block)?;
*stat = Stat {
......@@ -117,11 +118,11 @@ impl Resource for DirResource {
Err(Error::new(EBADF))
}
fn truncate(&mut self, _len: usize, _fs: &mut FileSystem) -> Result<usize> {
fn truncate(&mut self, _len: usize, _fs: &mut FileSystem<D>) -> Result<usize> {
Err(Error::new(EBADF))
}
fn utimens(&mut self, _times: &[TimeSpec], _fs: &mut FileSystem) -> Result<usize> {
fn utimens(&mut self, _times: &[TimeSpec], _fs: &mut FileSystem<D>) -> Result<usize> {
Err(Error::new(EBADF))
}
}
......@@ -146,8 +147,8 @@ impl FileResource {
}
}
impl Resource for FileResource {
fn dup(&self) -> Result<Box<Resource>> {
impl<D: Disk> Resource<D> for FileResource {
fn dup(&self) -> Result<Box<Resource<D>>> {
Ok(Box::new(FileResource {
path: self.path.clone(),
block: self.block,
......@@ -157,7 +158,7 @@ impl Resource for FileResource {
}))
}
fn read(&mut self, buf: &mut [u8], fs: &mut FileSystem) -> Result<usize> {
fn read(&mut self, buf: &mut [u8], fs: &mut FileSystem<D>) -> Result<usize> {
if self.flags & O_ACCMODE == O_RDWR || self.flags & O_ACCMODE == O_RDONLY {
let count = fs.read_node(self.block, self.seek, buf)?;
self.seek += count as u64;
......@@ -167,7 +168,7 @@ impl Resource for FileResource {
}
}
fn write(&mut self, buf: &[u8], fs: &mut FileSystem) -> Result<usize> {
fn write(&mut self, buf: &[u8], fs: &mut FileSystem<D>) -> Result<usize> {
if self.flags & O_ACCMODE == O_RDWR || self.flags & O_ACCMODE == O_WRONLY {
let mtime = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
let count = fs.write_node(self.block, self.seek, buf, mtime.as_secs(), mtime.subsec_nanos())?;
......@@ -178,7 +179,7 @@ impl Resource for FileResource {
}
}
fn seek(&mut self, offset: usize, whence: usize, fs: &mut FileSystem) -> Result<usize> {
fn seek(&mut self, offset: usize, whence: usize, fs: &mut FileSystem<D>) -> Result<usize> {
let size = fs.node_len(self.block)?;
self.seek = match whence {
......@@ -214,7 +215,7 @@ impl Resource for FileResource {
Ok(i)
}
fn stat(&self, stat: &mut Stat, fs: &mut FileSystem) -> Result<usize> {
fn stat(&self, stat: &mut Stat, fs: &mut FileSystem<D>) -> Result<usize> {
let node = fs.node(self.block)?;
*stat = Stat {
......@@ -239,7 +240,7 @@ impl Resource for FileResource {
Ok(0)
}
fn truncate(&mut self, len: usize, fs: &mut FileSystem) -> Result<usize> {
fn truncate(&mut self, len: usize, fs: &mut FileSystem<D>) -> Result<usize> {
if self.flags & O_ACCMODE == O_RDWR || self.flags & O_ACCMODE == O_WRONLY {
fs.node_set_len(self.block, len as u64)?;
Ok(0)
......@@ -248,7 +249,7 @@ impl Resource for FileResource {
}
}
fn utimens(&mut self, times: &[TimeSpec], fs: &mut FileSystem) -> Result<usize> {
fn utimens(&mut self, times: &[TimeSpec], fs: &mut FileSystem<D>) -> Result<usize> {
let mut node = fs.node(self.block)?;
if node.1.uid == self.uid || self.uid == 0 {
......
use redox::resource::{Resource, DirResource, FileResource};
use redox::spin::Mutex;
use redoxfs::{FileSystem, Node};
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::str;
......@@ -13,15 +9,22 @@ use syscall::error::{Error, Result, EACCES, EEXIST, EISDIR, ENOTDIR, EPERM, ENOE
use syscall::flag::{O_APPEND, O_CREAT, O_DIRECTORY, O_STAT, O_EXCL, O_TRUNC, O_ACCMODE, O_RDONLY, O_WRONLY, O_RDWR, MODE_PERM, O_SYMLINK, O_NOFOLLOW};
use syscall::scheme::Scheme;
pub struct FileScheme {
use disk::Disk;
use filesystem::FileSystem;
use node::Node;
use super::resource::{Resource, DirResource, FileResource};
use super::spin::Mutex;
pub struct FileScheme<D: Disk> {
name: String,
fs: RefCell<FileSystem>,
fs: RefCell<FileSystem<D>>,
next_id: AtomicUsize,
files: Mutex<BTreeMap<usize, Box<Resource>>>
files: Mutex<BTreeMap<usize, Box<Resource<D>>>>
}
impl FileScheme {
pub fn new(name: String, fs: FileSystem) -> FileScheme {
impl<D: Disk> FileScheme<D> {
pub fn new(name: String, fs: FileSystem<D>) -> FileScheme<D> {
FileScheme {
name: name,
fs: RefCell::new(fs),
......@@ -29,10 +32,8 @@ impl FileScheme {
files: Mutex::new(BTreeMap::new())
}
}
}
impl FileScheme {
fn resolve_symlink(&self, fs: &mut FileSystem, uid: u32, gid: u32, url: &[u8], node: (u64, Node), nodes: &mut Vec<(u64, Node)>) -> Result<Vec<u8>> {
fn resolve_symlink(&self, fs: &mut FileSystem<D>, uid: u32, gid: u32, url: &[u8], node: (u64, Node), nodes: &mut Vec<(u64, Node)>) -> Result<Vec<u8>> {
let mut node = node;
for _ in 1..10 { // XXX What should the limit be?
let mut buf = [0; 4096];
......@@ -59,7 +60,7 @@ impl FileScheme {
Err(Error::new(ELOOP))
}
fn path_nodes(&self, fs: &mut FileSystem, path: &str, uid: u32, gid: u32, nodes: &mut Vec<(u64, Node)>) -> Result<Option<(u64, Node)>> {
fn path_nodes(&self, fs: &mut FileSystem<D>, path: &str, uid: u32, gid: u32, nodes: &mut Vec<(u64, Node)>) -> Result<Option<(u64, Node)>> {
let mut parts = path.split('/').filter(|part| ! part.is_empty());
let mut part_opt = None;
let mut block = fs.header.1.root;
......@@ -175,7 +176,7 @@ pub fn canonicalize(current: &[u8], path: &[u8]) -> Vec<u8> {
}
}
impl Scheme for FileScheme {
impl<D: Disk> Scheme for FileScheme<D> {
fn open(&self, url: &[u8], flags: usize, uid: u32, gid: u32) -> Result<usize> {
let path = str::from_utf8(url).unwrap_or("").trim_matches('/');
......@@ -185,7 +186,7 @@ impl Scheme for FileScheme {
let mut nodes = Vec::new();
let node_opt = self.path_nodes(&mut fs, path, uid, gid, &mut nodes)?;
let resource: Box<Resource> = match node_opt {
let resource: Box<Resource<D>> = match node_opt {
Some(node) => if flags & (O_CREAT | O_EXCL) == O_CREAT | O_EXCL {
return Err(Error::new(EEXIST));
} else if node.1.is_dir() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment