diff --git a/src/libos/src/fs/file.rs b/src/libos/src/fs/file.rs index a237d330..79d0e415 100644 --- a/src/libos/src/fs/file.rs +++ b/src/libos/src/fs/file.rs @@ -205,7 +205,7 @@ impl SgxFileInner { Ok(self.pos as off_t) } - pub fn writev<'a, 'b>(&mut self, bufs: &'a [&'b [u8]]) -> Result { + pub fn writev(&mut self, bufs: &[&[u8]]) -> Result { if !self.is_writable { return Err(Error::new(Errno::EINVAL, "File not writable")); } @@ -245,7 +245,7 @@ impl SgxFileInner { Ok(total_bytes) } - fn readv<'a, 'b>(&mut self, bufs: &'a mut [&'b mut [u8]]) -> Result { + fn readv(&mut self, bufs: &mut [&mut [u8]]) -> Result { if !self.is_readable { return Err(Error::new(Errno::EINVAL, "File not readable")); } diff --git a/src/libos/src/fs/inode_file.rs b/src/libos/src/fs/inode_file.rs index 0dac3a1f..d3b37a4e 100644 --- a/src/libos/src/fs/inode_file.rs +++ b/src/libos/src/fs/inode_file.rs @@ -71,11 +71,45 @@ impl File for INodeFile { fn readv(&self, bufs: &mut [&mut [u8]]) -> Result { - Err(Error::new(Errno::ENOSYS, "Not implemented")) + if !self.options.read { + return Err(Error::new(Errno::EBADF, "File not readable")); + } + let mut offset = self.offset.lock().unwrap(); + let mut total_len = 0; + for buf in bufs { + match self.inode.read_at(*offset, buf) { + Ok(len) => { + total_len += len; + *offset += len; + }, + Err(_) if total_len != 0 => break, + Err(e) => return Err(e.into()), + } + } + Ok(total_len) } fn writev(&self, bufs: &[&[u8]]) -> Result { - Err(Error::new(Errno::ENOSYS, "Not implemented")) + if !self.options.write { + return Err(Error::new(Errno::EBADF, "File not writable")); + } + let mut offset = self.offset.lock().unwrap(); + if self.options.append { + let info = self.inode.metadata()?; + *offset = info.size; + } + let mut total_len = 0; + for buf in bufs { + match self.inode.write_at(*offset, buf) { + Ok(len) => { + total_len += len; + *offset += len; + }, + Err(_) if total_len != 0 => break, + Err(e) => return Err(e.into()), + } + } + Ok(total_len) } fn seek(&self, pos: SeekFrom) -> Result { diff --git a/src/libos/src/fs/mod.rs b/src/libos/src/fs/mod.rs index 2941fafd..2da790c1 100644 --- a/src/libos/src/fs/mod.rs +++ b/src/libos/src/fs/mod.rs @@ -62,6 +62,7 @@ pub fn do_open(path: &str, flags: u32, mode: u32) -> Result { } pub fn do_write(fd: FileDesc, buf: &[u8]) -> Result { + info!("write: fd: {}", fd); let current_ref = process::get_current(); let current_process = current_ref.lock().unwrap(); let file_ref = current_process.get_files().get(fd)?; @@ -69,6 +70,7 @@ pub fn do_write(fd: FileDesc, buf: &[u8]) -> Result { } pub fn do_read(fd: FileDesc, buf: &mut [u8]) -> Result { + info!("read: fd: {}", fd); let current_ref = process::get_current(); let current_process = current_ref.lock().unwrap(); let file_ref = current_process.get_files().get(fd)?; @@ -76,6 +78,7 @@ pub fn do_read(fd: FileDesc, buf: &mut [u8]) -> Result { } pub fn do_writev(fd: FileDesc, bufs: &[&[u8]]) -> Result { + info!("writev: fd: {}", fd); let current_ref = process::get_current(); let current_process = current_ref.lock().unwrap(); let file_ref = current_process.get_files().get(fd)?; @@ -83,6 +86,7 @@ pub fn do_writev(fd: FileDesc, bufs: &[&[u8]]) -> Result { } pub fn do_readv(fd: FileDesc, bufs: &mut [&mut [u8]]) -> Result { + info!("readv: fd: {}", fd); let current_ref = process::get_current(); let current_process = current_ref.lock().unwrap(); let file_ref = current_process.get_files().get(fd)?; @@ -90,6 +94,7 @@ pub fn do_readv(fd: FileDesc, bufs: &mut [&mut [u8]]) -> Result { } pub fn do_pwrite(fd: FileDesc, buf: &[u8], offset: usize) -> Result { + info!("pwrite: fd: {}, offset: {}", fd, offset); let current_ref = process::get_current(); let current_process = current_ref.lock().unwrap(); let file_ref = current_process.get_files().get(fd)?; @@ -97,6 +102,7 @@ pub fn do_pwrite(fd: FileDesc, buf: &[u8], offset: usize) -> Result Result { + info!("pread: fd: {}, offset: {}", fd, offset); let current_ref = process::get_current(); let current_process = current_ref.lock().unwrap(); let file_ref = current_process.get_files().get(fd)?; diff --git a/test/file/main.c b/test/file/main.c index dc649ba1..5e494153 100644 --- a/test/file/main.c +++ b/test/file/main.c @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include @@ -8,6 +8,7 @@ int main(int argc, const char* argv[]) { const char* file_name = "tmp.txt"; int fd, flags, mode, len; + off_t offset; const char* write_msg = "Hello World\n"; char read_buf[128] = {0}; @@ -39,6 +40,45 @@ int main(int argc, const char* argv[]) { return -1; } - printf("File write and read succesfully\n"); + + flags = O_RDWR; + if ((fd = open(file_name, flags)) < 0) { + printf("ERROR: failed to open a file for read and write\n"); + return -1; + } + + const char* iov_msg[2] = {"hello ", "world!"}; + struct iovec iov[2]; + for(int i=0; i<2; ++i) { + iov[i].iov_base = (void*)iov_msg[i]; + iov[i].iov_len = strlen(iov_msg[i]); + } + if ((len = writev(fd, iov, 2)) != 12) { + printf("ERROR: failed to write vectors to the file\n"); + return -1; + } + + if ((offset = lseek(fd, 0, SEEK_SET)) != 0) { + printf("ERROR: failed to lseek the file\n"); + return -1; + } + + iov[0].iov_base = read_buf; + iov[0].iov_len = 3; + iov[1].iov_base = read_buf + 5; + iov[1].iov_len = 20; + if ((len = readv(fd, iov, 2)) != 12) { + printf("ERROR: failed to read vectors from the file\n"); + return -1; + } + + if (memcmp(read_buf, "hel", 3) != 0 + || memcmp(read_buf + 5, "lo world!", 9) != 0) { + printf("ERROR: the message read from the file is not as it was written\n"); + return -1; + } + close(fd); + + printf("File write and read successfully\n"); return 0; }