diff --git a/scheme/resource.rs b/scheme/resource.rs
index 12765154191d4381d825cb046a631daf6ca25999..ab756e578fdc473253f07bdaccd9fab8a9eb5f35 100644
--- a/scheme/resource.rs
+++ b/scheme/resource.rs
@@ -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))
+        }
     }
 }
diff --git a/scheme/scheme.rs b/scheme/scheme.rs
index 6f64dc10e8c525392adad6fb4c54c3f3d9bbb5ea..3270bdbd2374407b6092daaaee6161e3363d53ec 100644
--- a/scheme/scheme.rs
+++ b/scheme/scheme.rs
@@ -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() {