Commit dc0b0c5c authored by Jeremy Soller's avatar Jeremy Soller

Fix compilation on Redox

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