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

Fix access modes

parent 81c39551
No related branches found
No related tags found
No related merge requests found
......@@ -2,7 +2,8 @@ use redoxfs::FileSystem;
use std::cmp::{min, max};
use syscall::error::{Error, Result, EINVAL};
use syscall::error::{Error, Result, EBADF, EINVAL};
use syscall::flag::{O_ACCMODE, O_RDONLY, O_WRONLY, O_RDWR};
use syscall::{Stat, SEEK_SET, SEEK_CUR, SEEK_END};
pub trait Resource {
......@@ -55,7 +56,7 @@ impl Resource for DirResource {
}
fn write(&mut self, _buf: &[u8], _fs: &mut FileSystem) -> Result<usize> {
Err(Error::new(EINVAL))
Err(Error::new(EBADF))
}
fn seek(&mut self, offset: usize, whence: usize, _fs: &mut FileSystem) -> Result<usize> {
......@@ -93,25 +94,27 @@ impl Resource for DirResource {
}
fn sync(&mut self) -> Result<usize> {
Err(Error::new(EINVAL))
Err(Error::new(EBADF))
}
fn truncate(&mut self, _len: usize, _fs: &mut FileSystem) -> Result<usize> {
Err(Error::new(EINVAL))
Err(Error::new(EBADF))
}
}
pub struct FileResource {
path: String,
block: u64,
flags: usize,
seek: u64,
}
impl FileResource {
pub fn new(path: String, block: u64) -> FileResource {
pub fn new(path: String, block: u64, flags: usize) -> FileResource {
FileResource {
path: path,
block: block,
flags: flags,
seek: 0,
}
}
......@@ -122,20 +125,29 @@ impl Resource for FileResource {
Ok(Box::new(FileResource {
path: self.path.clone(),
block: self.block,
flags: self.flags,
seek: self.seek,
}))
}
fn read(&mut self, buf: &mut [u8], fs: &mut FileSystem) -> Result<usize> {
let count = try!(fs.read_node(self.block, self.seek, buf));
self.seek += count as u64;
Ok(count)
if self.flags & O_ACCMODE == O_RDWR || self.flags & O_ACCMODE == O_RDONLY {
let count = try!(fs.read_node(self.block, self.seek, buf));
self.seek += count as u64;
Ok(count)
} else {
Err(Error::new(EBADF))
}
}
fn write(&mut self, buf: &[u8], fs: &mut FileSystem) -> Result<usize> {
let count = try!(fs.write_node(self.block, self.seek, buf));
self.seek += count as u64;
Ok(count)
if self.flags & O_ACCMODE == O_RDWR || self.flags & O_ACCMODE == O_WRONLY {
let count = try!(fs.write_node(self.block, self.seek, buf));
self.seek += count as u64;
Ok(count)
} else {
Err(Error::new(EBADF))
}
}
fn seek(&mut self, offset: usize, whence: usize, fs: &mut FileSystem) -> Result<usize> {
......@@ -179,8 +191,11 @@ impl Resource for FileResource {
}
fn truncate(&mut self, len: usize, fs: &mut FileSystem) -> Result<usize> {
try!(fs.node_set_len(self.block, len as u64));
Ok(0)
if self.flags & O_ACCMODE == O_RDWR || self.flags & O_ACCMODE == O_WRONLY {
try!(fs.node_set_len(self.block, len as u64));
Ok(0)
} else {
Err(Error::new(EBADF))
}
}
}
......@@ -7,9 +7,10 @@ use std::collections::BTreeMap;
use std::str;
use std::sync::atomic::{AtomicUsize, Ordering};
use syscall::data::Stat;
use syscall::error::{Error, Result, EACCES, EEXIST, EISDIR, ENOTDIR, EPERM, ENOENT, EBADF};
use syscall::flag::{O_CREAT, O_TRUNC, O_ACCMODE, O_RDONLY, O_WRONLY, O_RDWR};
use syscall::scheme::Scheme;
use syscall::{Stat, O_CREAT, O_TRUNC};
pub struct FileScheme {
name: &'static str,
......@@ -44,10 +45,18 @@ impl Scheme for FileScheme {
// println!("dir not executable {:o}", node.1.mode);
return Err(Error::new(EACCES));
}
if ! node.1.is_dir() {
return Err(Error::new(ENOTDIR));
}
}
let resource: Box<Resource> = match node_result {
Ok(node) => if node.1.is_dir() {
if flags & O_ACCMODE != O_RDONLY {
// println!("dir not opened with O_RDONLY");
return Err(Error::new(EACCES));
}
if ! node.1.permission(uid, gid, Node::MODE_READ) {
// println!("dir not readable {:o}", node.1.mode);
return Err(Error::new(EACCES));
......@@ -67,11 +76,16 @@ impl Scheme for FileScheme {
Box::new(DirResource::new(path.to_string(), node.0, data))
} else {
if ! node.1.permission(uid, gid, Node::MODE_READ) {
if (flags & O_ACCMODE == O_RDONLY || flags & O_ACCMODE == O_RDWR) && ! node.1.permission(uid, gid, Node::MODE_READ) {
// println!("file not readable {:o}", node.1.mode);
return Err(Error::new(EACCES));
}
if (flags & O_ACCMODE == O_WRONLY || flags & O_ACCMODE == O_RDWR) && ! node.1.permission(uid, gid, Node::MODE_WRITE) {
// println!("file not writable {:o}", node.1.mode);
return Err(Error::new(EACCES));
}
if flags & O_TRUNC == O_TRUNC {
if ! node.1.permission(uid, gid, Node::MODE_WRITE) {
// println!("file not writable {:o}", node.1.mode);
......@@ -81,7 +95,7 @@ impl Scheme for FileScheme {
try!(fs.node_set_len(node.0, 0));
}
Box::new(FileResource::new(path.to_string(), node.0))
Box::new(FileResource::new(path.to_string(), node.0, flags))
},
Err(err) => if err.errno == ENOENT && flags & O_CREAT == O_CREAT {
let mut last_part = String::new();
......@@ -101,7 +115,18 @@ impl Scheme for FileScheme {
node.1.uid = uid;
node.1.gid = gid;
try!(fs.write_at(node.0, &node.1));
Box::new(FileResource::new(path.to_string(), node.0))
if (flags & O_ACCMODE == O_RDONLY || flags & O_ACCMODE == O_RDWR) && ! node.1.permission(uid, gid, Node::MODE_READ) {
// println!("file not readable {:o}", node.1.mode);
return Err(Error::new(EACCES));
}
if (flags & O_ACCMODE == O_WRONLY || flags & O_ACCMODE == O_RDWR) && ! node.1.permission(uid, gid, Node::MODE_WRITE) {
// println!("file not writable {:o}", node.1.mode);
return Err(Error::new(EACCES));
}
Box::new(FileResource::new(path.to_string(), node.0, flags))
} else {
return Err(Error::new(EPERM));
}
......@@ -133,6 +158,9 @@ impl Scheme for FileScheme {
// println!("dir not executable {:o}", node.1.mode);
return Err(Error::new(EACCES));
}
if ! node.1.is_dir() {
return Err(Error::new(ENOTDIR));
}
}
match node_result {
......@@ -182,6 +210,9 @@ impl Scheme for FileScheme {
// println!("dir not executable {:o}", node.1.mode);
return Err(Error::new(EACCES));
}
if ! node.1.is_dir() {
return Err(Error::new(ENOTDIR));
}
}
if let Some(parent) = nodes.last() {
......@@ -223,6 +254,9 @@ impl Scheme for FileScheme {
// println!("dir not executable {:o}", node.1.mode);
return Err(Error::new(EACCES));
}
if ! node.1.is_dir() {
return Err(Error::new(ENOTDIR));
}
}
if let Some(parent) = nodes.last() {
......
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