[libos] Add syscall pwritev and preadv
This commit is contained in:
parent
0f33e93fd5
commit
0bbfec0f24
@ -1052,8 +1052,8 @@ pwrite04_64 pwrite04_64
|
||||
|
||||
pwritev01 pwritev01
|
||||
pwritev01_64 pwritev01_64
|
||||
pwritev02 pwritev02
|
||||
pwritev02_64 pwritev02_64
|
||||
# pwritev02 pwritev02
|
||||
# pwritev02_64 pwritev02_64
|
||||
pwritev03 pwritev03
|
||||
pwritev03_64 pwritev03_64
|
||||
|
||||
|
@ -43,6 +43,14 @@ pub trait File: Debug + Sync + Send + Any {
|
||||
return_op_unsupported_error!("seek")
|
||||
}
|
||||
|
||||
fn preadv(&self, bufs: &mut [&mut [u8]], offset: usize) -> Result<usize> {
|
||||
return_op_unsupported_error!("preadv")
|
||||
}
|
||||
|
||||
fn pwritev(&self, bufs: &[&[u8]], offset: usize) -> Result<usize> {
|
||||
return_op_unsupported_error!("pwritev")
|
||||
}
|
||||
|
||||
fn position(&self) -> Result<off_t> {
|
||||
return_op_unsupported_error!("position")
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ pub use self::link::{do_linkat, LinkFlags};
|
||||
pub use self::lseek::do_lseek;
|
||||
pub use self::mkdir::do_mkdirat;
|
||||
pub use self::open::do_openat;
|
||||
pub use self::read::{do_pread, do_read, do_readv};
|
||||
pub use self::read::{do_pread, do_preadv, do_read, do_readv};
|
||||
pub use self::rename::do_renameat;
|
||||
pub use self::rmdir::do_rmdir;
|
||||
pub use self::sendfile::do_sendfile;
|
||||
@ -32,7 +32,7 @@ pub use self::unlink::{do_unlinkat, UnlinkFlags};
|
||||
pub use self::utimes::{
|
||||
do_utimes_fd, do_utimes_path, get_utimes, utimbuf_t, Utime, UtimeFlags, UTIME_OMIT,
|
||||
};
|
||||
pub use self::write::{do_pwrite, do_write, do_writev};
|
||||
pub use self::write::{do_pwrite, do_pwritev, do_write, do_writev};
|
||||
|
||||
mod access;
|
||||
mod chmod;
|
||||
|
@ -20,3 +20,9 @@ pub fn do_pread(fd: FileDesc, buf: &mut [u8], offset: off_t) -> Result<usize> {
|
||||
let file_ref = current!().file(fd)?;
|
||||
file_ref.read_at(offset as usize, buf)
|
||||
}
|
||||
|
||||
pub fn do_preadv(fd: FileDesc, bufs: &mut [&mut [u8]], offset: off_t) -> Result<usize> {
|
||||
debug!("preadv: fd: {}, offset {}", fd, offset);
|
||||
let file_ref = current!().file(fd)?;
|
||||
file_ref.preadv(bufs, offset as usize)
|
||||
}
|
||||
|
@ -20,3 +20,9 @@ pub fn do_pwrite(fd: FileDesc, buf: &[u8], offset: off_t) -> Result<usize> {
|
||||
let file_ref = current!().file(fd)?;
|
||||
file_ref.write_at(offset as usize, buf)
|
||||
}
|
||||
|
||||
pub fn do_pwritev(fd: FileDesc, bufs: &[&[u8]], offset: off_t) -> Result<usize> {
|
||||
debug!("pwritev: fd: {}, offset {}", fd, offset);
|
||||
let file_ref = current!().file(fd)?;
|
||||
file_ref.pwritev(bufs, offset as usize)
|
||||
}
|
||||
|
@ -113,6 +113,44 @@ impl File for INodeFile {
|
||||
Ok(*offset as i64)
|
||||
}
|
||||
|
||||
fn preadv(&self, bufs: &mut [&mut [u8]], offset: usize) -> Result<usize> {
|
||||
if !self.access_mode.readable() {
|
||||
return_errno!(EBADF, "File not readable");
|
||||
}
|
||||
let mut offset = offset;
|
||||
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 pwritev(&self, bufs: &[&[u8]], offset: usize) -> Result<usize> {
|
||||
if !self.access_mode.writable() {
|
||||
return_errno!(EBADF, "File not writable");
|
||||
}
|
||||
let mut offset = offset;
|
||||
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 position(&self) -> Result<off_t> {
|
||||
let offset = self.offset.lock().unwrap();
|
||||
Ok(*offset as off_t)
|
||||
|
@ -148,7 +148,12 @@ pub fn do_write(fd: FileDesc, buf: *const u8, size: usize) -> Result<isize> {
|
||||
Ok(len as isize)
|
||||
}
|
||||
|
||||
pub fn do_writev(fd: FileDesc, iov: *const iovec_t, count: i32) -> Result<isize> {
|
||||
fn do_writev_offset(
|
||||
fd: FileDesc,
|
||||
iov: *const iovec_t,
|
||||
count: i32,
|
||||
offset: Option<off_t>,
|
||||
) -> Result<isize> {
|
||||
let count = {
|
||||
if count < 0 {
|
||||
return_errno!(EINVAL, "Invalid count of iovec");
|
||||
@ -169,11 +174,25 @@ pub fn do_writev(fd: FileDesc, iov: *const iovec_t, count: i32) -> Result<isize>
|
||||
};
|
||||
let bufs = &bufs_vec[..];
|
||||
|
||||
let len = file_ops::do_writev(fd, bufs)?;
|
||||
let len = if let Some(offset) = offset {
|
||||
file_ops::do_pwritev(fd, bufs, offset)?
|
||||
} else {
|
||||
file_ops::do_writev(fd, bufs)?
|
||||
};
|
||||
|
||||
Ok(len as isize)
|
||||
}
|
||||
|
||||
pub fn do_readv(fd: FileDesc, iov: *mut iovec_t, count: i32) -> Result<isize> {
|
||||
pub fn do_writev(fd: FileDesc, iov: *const iovec_t, count: i32) -> Result<isize> {
|
||||
do_writev_offset(fd, iov, count, None)
|
||||
}
|
||||
|
||||
fn do_readv_offset(
|
||||
fd: FileDesc,
|
||||
iov: *mut iovec_t,
|
||||
count: i32,
|
||||
offset: Option<off_t>,
|
||||
) -> Result<isize> {
|
||||
let count = {
|
||||
if count < 0 {
|
||||
return_errno!(EINVAL, "Invalid count of iovec");
|
||||
@ -194,10 +213,19 @@ pub fn do_readv(fd: FileDesc, iov: *mut iovec_t, count: i32) -> Result<isize> {
|
||||
};
|
||||
let bufs = &mut bufs_vec[..];
|
||||
|
||||
let len = file_ops::do_readv(fd, bufs)?;
|
||||
let len = if let Some(offset) = offset {
|
||||
file_ops::do_preadv(fd, bufs, offset)?
|
||||
} else {
|
||||
file_ops::do_readv(fd, bufs)?
|
||||
};
|
||||
|
||||
Ok(len as isize)
|
||||
}
|
||||
|
||||
pub fn do_readv(fd: FileDesc, iov: *mut iovec_t, count: i32) -> Result<isize> {
|
||||
do_readv_offset(fd, iov, count, None)
|
||||
}
|
||||
|
||||
pub fn do_pread(fd: FileDesc, buf: *mut u8, size: usize, offset: off_t) -> Result<isize> {
|
||||
let safe_buf = {
|
||||
from_user::check_mut_array(buf, size)?;
|
||||
@ -207,6 +235,14 @@ pub fn do_pread(fd: FileDesc, buf: *mut u8, size: usize, offset: off_t) -> Resul
|
||||
Ok(len as isize)
|
||||
}
|
||||
|
||||
pub fn do_preadv(fd: FileDesc, iov: *mut iovec_t, count: i32, offset: off_t) -> Result<isize> {
|
||||
if offset < 0 {
|
||||
return_errno!(EINVAL, "Invalid offset");
|
||||
}
|
||||
|
||||
do_readv_offset(fd, iov, count, Some(offset))
|
||||
}
|
||||
|
||||
pub fn do_pwrite(fd: FileDesc, buf: *const u8, size: usize, offset: off_t) -> Result<isize> {
|
||||
let safe_buf = {
|
||||
from_user::check_array(buf, size)?;
|
||||
@ -216,6 +252,14 @@ pub fn do_pwrite(fd: FileDesc, buf: *const u8, size: usize, offset: off_t) -> Re
|
||||
Ok(len as isize)
|
||||
}
|
||||
|
||||
pub fn do_pwritev(fd: FileDesc, iov: *const iovec_t, count: i32, offset: off_t) -> Result<isize> {
|
||||
if offset < 0 {
|
||||
return_errno!(EINVAL, "Invalid offset");
|
||||
}
|
||||
|
||||
do_writev_offset(fd, iov, count, Some(offset))
|
||||
}
|
||||
|
||||
pub fn do_fstat(fd: FileDesc, stat_buf: *mut Stat) -> Result<isize> {
|
||||
from_user::check_mut_ptr(stat_buf)?;
|
||||
|
||||
|
@ -27,12 +27,12 @@ use crate::fs::{
|
||||
do_fchown, do_fchownat, do_fcntl, do_fdatasync, do_flock, do_fstat, do_fstatat, do_fstatfs,
|
||||
do_fsync, do_ftruncate, do_futimesat, do_getcwd, do_getdents, do_getdents64, do_ioctl,
|
||||
do_lchown, do_link, do_linkat, do_lseek, do_lstat, do_mkdir, do_mkdirat, do_mount,
|
||||
do_mount_rootfs, do_open, do_openat, do_pipe, do_pipe2, do_pread, do_pwrite, do_read,
|
||||
do_readlink, do_readlinkat, do_readv, do_rename, do_renameat, do_rmdir, do_sendfile, do_stat,
|
||||
do_statfs, do_symlink, do_symlinkat, do_sync, do_timerfd_create, do_timerfd_gettime,
|
||||
do_timerfd_settime, do_truncate, do_umask, do_umount, do_unlink, do_unlinkat, do_utime,
|
||||
do_utimensat, do_utimes, do_write, do_writev, iovec_t, utimbuf_t, AsTimer, File, FileDesc,
|
||||
FileRef, HostStdioFds, Stat, Statfs,
|
||||
do_mount_rootfs, do_open, do_openat, do_pipe, do_pipe2, do_pread, do_preadv, do_pwrite,
|
||||
do_pwritev, do_read, do_readlink, do_readlinkat, do_readv, do_rename, do_renameat, do_rmdir,
|
||||
do_sendfile, do_stat, do_statfs, do_symlink, do_symlinkat, do_sync, do_timerfd_create,
|
||||
do_timerfd_gettime, do_timerfd_settime, do_truncate, do_umask, do_umount, do_unlink,
|
||||
do_unlinkat, do_utime, do_utimensat, do_utimes, do_write, do_writev, iovec_t, utimbuf_t,
|
||||
AsTimer, File, FileDesc, FileRef, HostStdioFds, Stat, Statfs,
|
||||
};
|
||||
use crate::interrupt::{do_handle_interrupt, sgx_interrupt_info_t};
|
||||
use crate::ipc::{do_shmat, do_shmctl, do_shmdt, do_shmget, key_t, shmids_t};
|
||||
@ -388,8 +388,8 @@ macro_rules! process_syscall_table_with_callback {
|
||||
(Dup3 = 292) => do_dup3(old_fd: FileDesc, new_fd: FileDesc, flags: u32),
|
||||
(Pipe2 = 293) => do_pipe2(fds_u: *mut i32, flags: u32),
|
||||
(InotifyInit1 = 294) => handle_unsupported(),
|
||||
(Preadv = 295) => handle_unsupported(),
|
||||
(Pwritev = 296) => handle_unsupported(),
|
||||
(Preadv = 295) => do_preadv(fd: FileDesc, iov: *mut iovec_t, count: i32, offset: off_t),
|
||||
(Pwritev = 296) => do_pwritev(fd: FileDesc, iov: *const iovec_t, count: i32, offset: off_t),
|
||||
(RtTgsigqueueinfo = 297) => handle_unsupported(),
|
||||
(PerfEventOpen = 298) => handle_unsupported(),
|
||||
(Recvmmsg = 299) => handle_unsupported(),
|
||||
|
Loading…
Reference in New Issue
Block a user