diff --git a/litebox/src/fs/in_mem.rs b/litebox/src/fs/in_mem.rs index 68efcfe673..3b5b1fe6c9 100644 --- a/litebox/src/fs/in_mem.rs +++ b/litebox/src/fs/in_mem.rs @@ -298,11 +298,6 @@ impl super::backend::Backend for InMe flags: super::OFlags, ) -> Result { assert_supported_oflags(flags); - if flags.intersects(super::OFlags::WRONLY | super::OFlags::RDWR) { - // TODO(jayb): POSIX requires `EISDIR` when write access is requested on a directory, - // but `OpenError` has no such variant yet. - unimplemented!() - } Ok(super::backend::DirHandle::from_typed::( InMemDirHandle { flags, diff --git a/litebox/src/fs/nine_p/mod.rs b/litebox/src/fs/nine_p/mod.rs index 721c488a06..a1c13f6315 100644 --- a/litebox/src/fs/nine_p/mod.rs +++ b/litebox/src/fs/nine_p/mod.rs @@ -352,11 +352,6 @@ where flags: OFlags, ) -> Result { assert_supported_oflags(flags); - if flags.intersects(OFlags::WRONLY | OFlags::RDWR) { - // TODO(jayb): POSIX requires `EISDIR` when write access is requested on a directory, - // but `OpenError` has no such variant yet. - unimplemented!() - } let (fid, is_backend_root) = dir.into_typed::().into_dir(); if flags.contains(OFlags::PATH) { // An `O_PATH` handle is never opened server-side, so the walked fid can be handed over diff --git a/litebox_shim_linux/src/syscalls/file.rs b/litebox_shim_linux/src/syscalls/file.rs index 8bf5bafdb6..98c5ed5ef3 100644 --- a/litebox_shim_linux/src/syscalls/file.rs +++ b/litebox_shim_linux/src/syscalls/file.rs @@ -365,10 +365,26 @@ impl Task { let files = self.files.borrow(); let fs = self.fs.borrow(); let context = fs.context.read(); - files + let file = files .fs .open(&context, path, flags - OFlags::CLOEXEC, mode) - .map_err(Errno::from) + .map_err(Errno::from)?; + if flags.intersects(OFlags::WRONLY | OFlags::RDWR) + && !flags.contains(OFlags::PATH) + && files + .fs + .fd_file_status(&file) + .map_err(|error| { + files.fs.close(&file).unwrap(); + Errno::from(error) + })? + .file_type + == litebox::fs::FileType::Directory + { + files.fs.close(&file).unwrap(); + return Err(Errno::EISDIR); + } + Ok(file) } fn do_openat(