Fix access modes

This commit is contained in:
Jeremy Soller
2016-11-08 10:52:27 -07:00
parent 81c39551d7
commit d058e56d6e
2 changed files with 67 additions and 18 deletions
+29 -14
View File
@@ -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))
}
}
}
+38 -4
View File
@@ -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() {