diff --git a/src/libos/src/fs/dev_null.rs b/src/libos/src/fs/dev_null.rs index d5cb3380..8b665dba 100644 --- a/src/libos/src/fs/dev_null.rs +++ b/src/libos/src/fs/dev_null.rs @@ -16,42 +16,6 @@ impl File for DevNull { Ok(bufs.iter().map(|buf| buf.len()).sum()) } - fn read(&self, _buf: &mut [u8]) -> Result { - return_errno!(EINVAL, "device not support reads") - } - - fn read_at(&self, _offset: usize, _buf: &mut [u8]) -> Result { - return_errno!(EINVAL, "device not support reads") - } - - fn readv(&self, bufs: &mut [&mut [u8]]) -> Result { - return_errno!(EINVAL, "device not support reads") - } - - fn seek(&self, pos: SeekFrom) -> Result { - return_errno!(EINVAL, "device not support seeks") - } - - fn metadata(&self) -> Result { - unimplemented!() - } - - fn set_len(&self, len: u64) -> Result<()> { - return_errno!(EINVAL, "device not support resizing") - } - - fn sync_all(&self) -> Result<()> { - Ok(()) - } - - fn sync_data(&self) -> Result<()> { - Ok(()) - } - - fn read_entry(&self) -> Result { - return_errno!(ENOTDIR, "device is not a directory") - } - fn as_any(&self) -> &Any { self } diff --git a/src/libos/src/fs/dev_random.rs b/src/libos/src/fs/dev_random.rs index 5ae9c382..35b45257 100644 --- a/src/libos/src/fs/dev_random.rs +++ b/src/libos/src/fs/dev_random.rs @@ -41,42 +41,6 @@ impl File for DevRandom { Ok(total_nbytes) } - fn write(&self, _buf: &[u8]) -> Result { - return_errno!(EINVAL, "device not support writes") - } - - fn write_at(&self, _offset: usize, _buf: &[u8]) -> Result { - return_errno!(EINVAL, "device not support writes") - } - - fn writev(&self, bufs: &[&[u8]]) -> Result { - return_errno!(EINVAL, "device not support writes") - } - - fn seek(&self, pos: SeekFrom) -> Result { - return_errno!(EINVAL, "device not support seeks") - } - - fn metadata(&self) -> Result { - unimplemented!() - } - - fn set_len(&self, len: u64) -> Result<()> { - return_errno!(EINVAL, "device not support resizing") - } - - fn sync_all(&self) -> Result<()> { - Ok(()) - } - - fn sync_data(&self) -> Result<()> { - Ok(()) - } - - fn read_entry(&self) -> Result { - return_errno!(ENOTDIR, "device is not a directory") - } - fn as_any(&self) -> &Any { self } diff --git a/src/libos/src/fs/dev_zero.rs b/src/libos/src/fs/dev_zero.rs index 64d4ca53..35e35a1f 100644 --- a/src/libos/src/fs/dev_zero.rs +++ b/src/libos/src/fs/dev_zero.rs @@ -23,42 +23,6 @@ impl File for DevZero { Ok(total_nbytes) } - fn write(&self, _buf: &[u8]) -> Result { - return_errno!(EINVAL, "device not support writes") - } - - fn write_at(&self, _offset: usize, _buf: &[u8]) -> Result { - return_errno!(EINVAL, "device not support writes") - } - - fn writev(&self, bufs: &[&[u8]]) -> Result { - return_errno!(EINVAL, "device not support writes") - } - - fn seek(&self, pos: SeekFrom) -> Result { - return_errno!(EINVAL, "device not support seeks") - } - - fn metadata(&self) -> Result { - unimplemented!() - } - - fn set_len(&self, len: u64) -> Result<()> { - return_errno!(EINVAL, "device not support resizing") - } - - fn sync_all(&self) -> Result<()> { - Ok(()) - } - - fn sync_data(&self) -> Result<()> { - Ok(()) - } - - fn read_entry(&self) -> Result { - return_errno!(ENOTDIR, "device is not a directory") - } - fn as_any(&self) -> &Any { self } diff --git a/src/libos/src/fs/file.rs b/src/libos/src/fs/file.rs index c7b4cbf0..cc57f9dc 100644 --- a/src/libos/src/fs/file.rs +++ b/src/libos/src/fs/file.rs @@ -4,19 +4,69 @@ use std::borrow::BorrowMut; use std::fmt; use std::io::SeekFrom; +macro_rules! return_op_unsupported_error { + ($op_name: expr, $errno: expr) => {{ + let errno = $errno; + // FIXME: use the safe core::any::type_name when we upgrade to Rust 1.38 or above + let type_name = unsafe { core::intrinsics::type_name::() }; + let op_name = $op_name; + let error = FileOpNotSupportedError::new(errno, type_name, op_name); + return_errno!(error) + }}; + ($op_name: expr) => {{ + return_op_unsupported_error!($op_name, ENOSYS) + }}; +} + pub trait File: Debug + Sync + Send + Any { - fn read(&self, buf: &mut [u8]) -> Result; - fn write(&self, buf: &[u8]) -> Result; - fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result; - fn write_at(&self, offset: usize, buf: &[u8]) -> Result; - fn readv(&self, bufs: &mut [&mut [u8]]) -> Result; - fn writev(&self, bufs: &[&[u8]]) -> Result; - fn seek(&self, pos: SeekFrom) -> Result; - fn metadata(&self) -> Result; - fn set_len(&self, len: u64) -> Result<()>; - fn sync_all(&self) -> Result<()>; - fn sync_data(&self) -> Result<()>; - fn read_entry(&self) -> Result; + fn read(&self, buf: &mut [u8]) -> Result { + return_op_unsupported_error!("read") + } + + fn write(&self, buf: &[u8]) -> Result { + return_op_unsupported_error!("write") + } + + fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result { + return_op_unsupported_error!("read_at") + } + + fn write_at(&self, offset: usize, buf: &[u8]) -> Result { + return_op_unsupported_error!("write_at") + } + + fn readv(&self, bufs: &mut [&mut [u8]]) -> Result { + return_op_unsupported_error!("readv") + } + + fn writev(&self, bufs: &[&[u8]]) -> Result { + return_op_unsupported_error!("writev") + } + + fn seek(&self, pos: SeekFrom) -> Result { + return_op_unsupported_error!("seek") + } + + fn metadata(&self) -> Result { + return_op_unsupported_error!("metadata") + } + + fn set_len(&self, len: u64) -> Result<()> { + return_op_unsupported_error!("set_len") + } + + fn read_entry(&self) -> Result { + return_op_unsupported_error!("read_entry", ENOTDIR) + } + + fn sync_all(&self) -> Result<()> { + Ok(()) + } + + fn sync_data(&self) -> Result<()> { + Ok(()) + } + fn as_any(&self) -> &Any; } @@ -96,26 +146,6 @@ impl File for SgxFile { inner.seek(pos) } - fn metadata(&self) -> Result { - unimplemented!() - } - - fn set_len(&self, len: u64) -> Result<()> { - unimplemented!() - } - - fn sync_all(&self) -> Result<()> { - unimplemented!() - } - - fn sync_data(&self) -> Result<()> { - unimplemented!() - } - - fn read_entry(&self) -> Result { - unimplemented!() - } - fn as_any(&self) -> &Any { self } @@ -296,27 +326,15 @@ impl StdoutFile { } impl File for StdoutFile { - fn read(&self, buf: &mut [u8]) -> Result { - return_errno!(EBADF, "Stdout does not support read") - } - fn write(&self, buf: &[u8]) -> Result { let write_len = { self.inner.lock().write(buf).map_err(|e| errno!(e))? }; Ok(write_len) } - fn read_at(&self, _offset: usize, buf: &mut [u8]) -> Result { - self.read(buf) - } - fn write_at(&self, _offset: usize, buf: &[u8]) -> Result { self.write(buf) } - fn readv(&self, bufs: &mut [&mut [u8]]) -> Result { - return_errno!(EBADF, "Stdout does not support read") - } - fn writev(&self, bufs: &[&[u8]]) -> Result { let mut guard = self.inner.lock(); let mut total_bytes = 0; @@ -341,10 +359,6 @@ impl File for StdoutFile { Ok(total_bytes) } - fn seek(&self, seek_pos: SeekFrom) -> Result { - return_errno!(ESPIPE, "Stdout does not support seek") - } - fn metadata(&self) -> Result { Ok(Metadata { dev: 0, @@ -364,10 +378,6 @@ impl File for StdoutFile { }) } - fn set_len(&self, _len: u64) -> Result<()> { - return_errno!(EINVAL, "Stdout does not support set_len") - } - fn sync_all(&self) -> Result<()> { self.sync_data() } @@ -377,10 +387,6 @@ impl File for StdoutFile { Ok(()) } - fn read_entry(&self) -> Result { - return_errno!(ENOTDIR, "Stdout does not support read_entry") - } - fn as_any(&self) -> &Any { self } @@ -413,18 +419,6 @@ impl File for StdinFile { Ok(read_len) } - fn write(&self, buf: &[u8]) -> Result { - return_errno!(EBADF, "Stdin does not support write") - } - - fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result { - unimplemented!() - } - - fn write_at(&self, offset: usize, buf: &[u8]) -> Result { - unimplemented!() - } - fn readv(&self, bufs: &mut [&mut [u8]]) -> Result { let mut guard = self.inner.lock(); let mut total_bytes = 0; @@ -449,14 +443,6 @@ impl File for StdinFile { Ok(total_bytes) } - fn writev(&self, bufs: &[&[u8]]) -> Result { - return_errno!(EBADF, "Stdin does not support write") - } - - fn seek(&self, pos: SeekFrom) -> Result { - return_errno!(ESPIPE, "Stdin does not support seek") - } - fn metadata(&self) -> Result { Ok(Metadata { dev: 0, @@ -476,22 +462,6 @@ impl File for StdinFile { }) } - fn set_len(&self, _len: u64) -> Result<()> { - return_errno!(EINVAL, "Stdin does not support set_len") - } - - fn sync_all(&self) -> Result<()> { - self.sync_data() - } - - fn sync_data(&self) -> Result<()> { - Ok(()) - } - - fn read_entry(&self) -> Result { - return_errno!(ENOTDIR, "Stdin does not support read_entry") - } - fn as_any(&self) -> &Any { self } @@ -505,3 +475,36 @@ impl Debug for StdinFile { unsafe impl Send for StdinFile {} unsafe impl Sync for StdinFile {} + +#[derive(Copy, Clone, Debug)] +struct FileOpNotSupportedError { + errno: Errno, + type_name: &'static str, + op_name: &'static str, +} + +impl FileOpNotSupportedError { + pub fn new( + errno: Errno, + type_name: &'static str, + op_name: &'static str, + ) -> FileOpNotSupportedError { + FileOpNotSupportedError { + errno, + type_name, + op_name, + } + } +} + +impl fmt::Display for FileOpNotSupportedError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{} does not support {}", self.type_name, self.op_name) + } +} + +impl ToErrno for FileOpNotSupportedError { + fn errno(&self) -> Errno { + self.errno + } +} diff --git a/src/libos/src/fs/io_multiplexing.rs b/src/libos/src/fs/io_multiplexing.rs index 7100c9b7..faa1ef1b 100644 --- a/src/libos/src/fs/io_multiplexing.rs +++ b/src/libos/src/fs/io_multiplexing.rs @@ -308,54 +308,6 @@ impl Drop for EpollFileInner { } impl File for EpollFile { - fn read(&self, buf: &mut [u8]) -> Result { - unimplemented!() - } - - fn write(&self, buf: &[u8]) -> Result { - unimplemented!() - } - - fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result { - unimplemented!() - } - - fn write_at(&self, offset: usize, buf: &[u8]) -> Result { - unimplemented!() - } - - fn readv(&self, bufs: &mut [&mut [u8]]) -> Result { - unimplemented!() - } - - fn writev(&self, bufs: &[&[u8]]) -> Result { - unimplemented!() - } - - fn seek(&self, pos: SeekFrom) -> Result { - return_errno!(ESPIPE, "Epoll does not support seek") - } - - fn metadata(&self) -> Result { - unimplemented!() - } - - fn set_len(&self, len: u64) -> Result<()> { - unimplemented!() - } - - fn sync_all(&self) -> Result<()> { - unimplemented!() - } - - fn sync_data(&self) -> Result<()> { - unimplemented!() - } - - fn read_entry(&self) -> Result { - unimplemented!() - } - fn as_any(&self) -> &Any { self } diff --git a/src/libos/src/fs/pipe.rs b/src/libos/src/fs/pipe.rs index 5350b414..71e85f90 100644 --- a/src/libos/src/fs/pipe.rs +++ b/src/libos/src/fs/pipe.rs @@ -36,18 +36,6 @@ impl File for PipeReader { ringbuf.read(buf) } - fn write(&self, buf: &[u8]) -> Result { - return_errno!(EBADF, "PipeReader does not support write") - } - - fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result { - unimplemented!() - } - - fn write_at(&self, offset: usize, buf: &[u8]) -> Result { - unimplemented!() - } - fn readv(&self, bufs: &mut [&mut [u8]]) -> Result { let mut ringbuf = self.inner.lock().unwrap(); let mut total_bytes = 0; @@ -72,34 +60,6 @@ impl File for PipeReader { Ok(total_bytes) } - fn writev(&self, bufs: &[&[u8]]) -> Result { - return_errno!(EBADF, "PipeReader does not support write") - } - - fn seek(&self, pos: SeekFrom) -> Result { - return_errno!(ESPIPE, "Pipe does not support seek") - } - - fn metadata(&self) -> Result { - unimplemented!() - } - - fn set_len(&self, len: u64) -> Result<()> { - unimplemented!() - } - - fn sync_all(&self) -> Result<()> { - unimplemented!() - } - - fn sync_data(&self) -> Result<()> { - unimplemented!() - } - - fn read_entry(&self) -> Result { - unimplemented!() - } - fn as_any(&self) -> &Any { self } @@ -114,25 +74,10 @@ pub struct PipeWriter { } impl File for PipeWriter { - fn read(&self, buf: &mut [u8]) -> Result { - return_errno!(EBADF, "PipeWriter does not support read") - } - fn write(&self, buf: &[u8]) -> Result { let ringbuf = self.inner.lock().unwrap(); ringbuf.write(buf) } - fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result { - unimplemented!() - } - - fn write_at(&self, offset: usize, buf: &[u8]) -> Result { - unimplemented!() - } - - fn readv(&self, bufs: &mut [&mut [u8]]) -> Result { - return_errno!(EBADF, "PipeWriter does not support read") - } fn writev(&self, bufs: &[&[u8]]) -> Result { let ringbuf = self.inner.lock().unwrap(); @@ -158,30 +103,10 @@ impl File for PipeWriter { Ok(total_bytes) } - fn seek(&self, seek_pos: SeekFrom) -> Result { + fn seek(&self, pos: SeekFrom) -> Result { return_errno!(ESPIPE, "Pipe does not support seek") } - fn metadata(&self) -> Result { - unimplemented!() - } - - fn set_len(&self, len: u64) -> Result<()> { - unimplemented!() - } - - fn sync_all(&self) -> Result<()> { - unimplemented!() - } - - fn sync_data(&self) -> Result<()> { - unimplemented!() - } - - fn read_entry(&self) -> Result { - unimplemented!() - } - fn as_any(&self) -> &Any { self } diff --git a/src/libos/src/fs/socket_file.rs b/src/libos/src/fs/socket_file.rs index 510088bc..772fceca 100644 --- a/src/libos/src/fs/socket_file.rs +++ b/src/libos/src/fs/socket_file.rs @@ -119,22 +119,6 @@ impl File for SocketFile { }) } - fn set_len(&self, len: u64) -> Result<()> { - unimplemented!() - } - - fn sync_all(&self) -> Result<()> { - unimplemented!() - } - - fn sync_data(&self) -> Result<()> { - unimplemented!() - } - - fn read_entry(&self) -> Result { - unimplemented!() - } - fn as_any(&self) -> &Any { self } diff --git a/src/libos/src/fs/unix_socket.rs b/src/libos/src/fs/unix_socket.rs index 9aad9815..9d77f509 100644 --- a/src/libos/src/fs/unix_socket.rs +++ b/src/libos/src/fs/unix_socket.rs @@ -59,10 +59,6 @@ impl File for UnixSocketFile { Ok(total_len) } - fn seek(&self, pos: SeekFrom) -> Result { - return_errno!(ESPIPE, "UnixSocket does not support seek") - } - fn metadata(&self) -> Result { Ok(Metadata { dev: 0, @@ -82,22 +78,6 @@ impl File for UnixSocketFile { }) } - fn set_len(&self, len: u64) -> Result<()> { - unimplemented!() - } - - fn sync_all(&self) -> Result<()> { - unimplemented!() - } - - fn sync_data(&self) -> Result<()> { - unimplemented!() - } - - fn read_entry(&self) -> Result { - unimplemented!() - } - fn as_any(&self) -> &Any { self }