Fix access modes
This commit is contained in:
+29
-14
@@ -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
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user