Implement pread and pwrite using the syscalls.

This commit is contained in:
4lDO2
2024-06-13 17:08:32 +02:00
parent ac08f016cd
commit 4c11b607de
12 changed files with 188 additions and 126 deletions
+25 -22
View File
@@ -14,7 +14,10 @@ use crate::header::{
sys_time::{timeval, timezone},
};
// use header::sys_times::tms;
use crate::header::{sys_utsname::utsname, time::timespec};
use crate::{
header::{sys_utsname::utsname, time::timespec},
pthread::Errno,
};
mod epoll;
mod ptrace;
@@ -52,9 +55,9 @@ struct linux_statfs {
// TODO
const ERRNO_MAX: usize = 4095;
pub fn e_raw(sys: usize) -> Result<usize, usize> {
pub fn e_raw(sys: usize) -> Result<usize, Errno> {
if sys > ERRNO_MAX.wrapping_neg() {
Err(sys.wrapping_neg())
Err(Errno(sys.wrapping_neg() as _))
} else {
Ok(sys)
}
@@ -62,7 +65,7 @@ pub fn e_raw(sys: usize) -> Result<usize, usize> {
pub fn e(sys: usize) -> usize {
match e_raw(sys) {
Ok(value) => value,
Err(errcode) => {
Err(Errno(errcode)) => {
ERRNO.set(errcode as c_int);
!0
}
@@ -251,15 +254,13 @@ impl Pal for Sys {
0xffffffff // val3: FUTEX_BITSET_MATCH_ANY
)
})
.map_err(|e| crate::pthread::Errno(e as c_int))
.map(|_| ())
}
#[inline]
unsafe fn futex_wake(addr: *mut u32, num: u32) -> Result<c_int, crate::pthread::Errno> {
unsafe fn futex_wake(addr: *mut u32, num: u32) -> Result<c_int, Errno> {
e_raw(unsafe {
syscall!(FUTEX, addr, 1 /* FUTEX_WAKE */, num)
})
.map_err(|e| crate::pthread::Errno(e as c_int))
.map(|n| n as c_int)
}
@@ -457,9 +458,7 @@ impl Pal for Sys {
}
#[cfg(target_arch = "x86_64")]
unsafe fn rlct_clone(
stack: *mut usize,
) -> Result<crate::pthread::OsTid, crate::pthread::Errno> {
unsafe fn rlct_clone(stack: *mut usize) -> Result<crate::pthread::OsTid, Errno> {
let flags = CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD;
let pid;
asm!("
@@ -508,18 +507,13 @@ impl Pal for Sys {
out("r14") _,
out("r15") _,
);
let tid = e_raw(pid).map_err(|err| crate::pthread::Errno(err as c_int))?;
let tid = e_raw(pid)?;
Ok(crate::pthread::OsTid { thread_id: tid })
}
unsafe fn rlct_kill(
os_tid: crate::pthread::OsTid,
signal: usize,
) -> Result<(), crate::pthread::Errno> {
unsafe fn rlct_kill(os_tid: crate::pthread::OsTid, signal: usize) -> Result<(), Errno> {
let tgid = Self::getpid();
e_raw(unsafe { syscall!(TGKILL, tgid, os_tid.thread_id, signal) })
.map(|_| ())
.map_err(|err| crate::pthread::Errno(err as c_int))
e_raw(unsafe { syscall!(TGKILL, tgid, os_tid.thread_id, signal) }).map(|_| ())
}
fn current_os_tid() -> crate::pthread::OsTid {
crate::pthread::OsTid {
@@ -527,8 +521,14 @@ impl Pal for Sys {
}
}
fn read(fildes: c_int, buf: &mut [u8]) -> ssize_t {
e(unsafe { syscall!(READ, fildes, buf.as_mut_ptr(), buf.len()) }) as ssize_t
fn read(fildes: c_int, buf: &mut [u8]) -> Result<ssize_t, Errno> {
Ok(e_raw(unsafe { syscall!(READ, fildes, buf.as_mut_ptr(), buf.len()) })? as ssize_t)
}
fn pread(fildes: c_int, buf: &mut [u8], off: off_t) -> Result<ssize_t, Errno> {
Ok(
e_raw(unsafe { syscall!(PREAD64, fildes, buf.as_mut_ptr(), buf.len(), off) })?
as ssize_t,
)
}
fn readlink(pathname: CStr, out: &mut [u8]) -> ssize_t {
@@ -603,8 +603,11 @@ impl Pal for Sys {
e(unsafe { syscall!(WAIT4, pid, stat_loc, options, 0) }) as pid_t
}
fn write(fildes: c_int, buf: &[u8]) -> ssize_t {
e(unsafe { syscall!(WRITE, fildes, buf.as_ptr(), buf.len()) }) as ssize_t
fn write(fildes: c_int, buf: &[u8]) -> Result<ssize_t, Errno> {
Ok(e_raw(unsafe { syscall!(WRITE, fildes, buf.as_ptr(), buf.len()) })? as ssize_t)
}
fn pwrite(fildes: c_int, buf: &[u8], off: off_t) -> Result<ssize_t, Errno> {
Ok(e_raw(unsafe { syscall!(PWRITE64, fildes, buf.as_ptr(), buf.len(), off) })? as ssize_t)
}
fn verify() -> bool {
+7 -4
View File
@@ -1,4 +1,7 @@
use crate::io::{self, Read, Write};
use crate::{
io::{self, Read, Write},
pthread::ResultExt,
};
use alloc::{boxed::Box, vec::Vec};
use core::{cell::Cell, fmt, ptr};
@@ -83,7 +86,7 @@ pub struct FileWriter(pub c_int);
impl FileWriter {
pub fn write(&mut self, buf: &[u8]) -> isize {
Sys::write(self.0, buf)
Sys::write(self.0, buf).or_minus_one_errno()
}
}
@@ -105,13 +108,13 @@ pub struct FileReader(pub c_int);
impl FileReader {
pub fn read(&mut self, buf: &mut [u8]) -> isize {
Sys::read(self.0, buf)
Sys::read(self.0, buf).or_minus_one_errno()
}
}
impl Read for FileReader {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let i = Sys::read(self.0, buf);
let i = Sys::read(self.0, buf).or_minus_one_errno(); // TODO
if i >= 0 {
Ok(i as usize)
} else {
+5 -3
View File
@@ -10,7 +10,7 @@ use crate::{
sys_utsname::utsname,
time::timespec,
},
pthread,
pthread::{self, Errno},
};
pub use self::epoll::PalEpoll;
@@ -190,7 +190,8 @@ pub trait Pal {
) -> Result<(), crate::pthread::Errno>;
fn current_os_tid() -> crate::pthread::OsTid;
fn read(fildes: c_int, buf: &mut [u8]) -> ssize_t;
fn read(fildes: c_int, buf: &mut [u8]) -> Result<ssize_t, Errno>;
fn pread(fildes: c_int, buf: &mut [u8], offset: off_t) -> Result<ssize_t, Errno>;
fn readlink(pathname: CStr, out: &mut [u8]) -> ssize_t;
@@ -224,7 +225,8 @@ pub trait Pal {
fn waitpid(pid: pid_t, stat_loc: *mut c_int, options: c_int) -> pid_t;
fn write(fildes: c_int, buf: &[u8]) -> ssize_t;
fn write(fildes: c_int, buf: &[u8]) -> Result<ssize_t, Errno>;
fn pwrite(fildes: c_int, buf: &[u8], offset: off_t) -> Result<ssize_t, Errno>;
fn verify() -> bool;
}
+12 -4
View File
@@ -8,6 +8,7 @@ use crate::{
header::{errno::*, fcntl::*, signal::sigset_t, sys_epoll::*},
io::prelude::*,
platform,
pthread::ResultExt,
};
use core::{mem, slice};
use syscall::{
@@ -67,7 +68,9 @@ impl PalEpoll for Sys {
// systems. If this is needed, use a box or something
data: unsafe { (*event).data.u64 as usize },
},
) < 0
)
.or_minus_one_errno()
< 0
{
-1
} else {
@@ -83,7 +86,9 @@ impl PalEpoll for Sys {
//TODO: Is data required?
data: 0,
},
) < 0
)
.or_minus_one_errno()
< 0
{
-1
} else {
@@ -123,7 +128,9 @@ impl PalEpoll for Sys {
flags: EVENT_READ,
data: 0,
},
) == -1
)
.or_minus_one_errno()
== -1
{
return -1;
}
@@ -150,7 +157,8 @@ impl PalEpoll for Sys {
events as *mut u8,
maxevents as usize * mem::size_of::<syscall::Event>(),
)
});
})
.or_minus_one_errno(); // TODO
if bytes_read == -1 {
return -1;
}
+30 -6
View File
@@ -24,7 +24,7 @@ use crate::{
unistd::{F_OK, R_OK, W_OK, X_OK},
},
io::{self, prelude::*, BufReader},
pthread,
pthread::{self, Errno, ResultExt},
};
pub use redox_exec::FdGuard;
@@ -823,8 +823,20 @@ impl Pal for Sys {
}
}
fn read(fd: c_int, buf: &mut [u8]) -> ssize_t {
e(syscall::read(fd as usize, buf)) as ssize_t
fn read(fd: c_int, buf: &mut [u8]) -> Result<ssize_t, Errno> {
Ok(syscall::read(fd as usize, buf)? as ssize_t)
}
fn pread(fd: c_int, buf: &mut [u8], offset: off_t) -> Result<ssize_t, Errno> {
unsafe {
Ok(syscall::syscall5(
syscall::SYS_READ2,
fd as usize,
buf.as_mut_ptr() as usize,
buf.len(),
offset as usize,
!0,
)? as ssize_t)
}
}
fn fpath(fildes: c_int, out: &mut [u8]) -> ssize_t {
@@ -870,7 +882,7 @@ impl Pal for Sys {
pathname,
fcntl::O_RDONLY | fcntl::O_SYMLINK | fcntl::O_CLOEXEC,
) {
Ok(file) => Self::read(*file, out),
Ok(file) => Self::read(*file, out).or_minus_one_errno(),
Err(_) => return -1,
}
}
@@ -1111,8 +1123,20 @@ impl Pal for Sys {
res as pid_t
}
fn write(fd: c_int, buf: &[u8]) -> ssize_t {
e(syscall::write(fd as usize, buf)) as ssize_t
fn write(fd: c_int, buf: &[u8]) -> Result<ssize_t, Errno> {
Ok(syscall::write(fd as usize, buf)? as ssize_t)
}
fn pwrite(fd: c_int, buf: &[u8], offset: off_t) -> Result<ssize_t, Errno> {
unsafe {
Ok(syscall::syscall5(
syscall::SYS_WRITE2,
fd as usize,
buf.as_ptr() as usize,
buf.len(),
offset as usize,
!0,
)? as ssize_t)
}
}
fn verify() -> bool {
+17 -12
View File
@@ -6,13 +6,16 @@ use super::{
super::{types::*, Pal, PalSocket, ERRNO},
e, Sys,
};
use crate::header::{
arpa_inet::inet_aton,
netinet_in::{in_addr, in_port_t, sockaddr_in},
string::strnlen,
sys_socket::{constants::*, msghdr, sa_family_t, sockaddr, socklen_t},
sys_time::timeval,
sys_un::sockaddr_un,
use crate::{
header::{
arpa_inet::inet_aton,
netinet_in::{in_addr, in_port_t, sockaddr_in},
string::strnlen,
sys_socket::{constants::*, msghdr, sa_family_t, sockaddr, socklen_t},
sys_time::timeval,
sys_un::sockaddr_un,
},
pthread::ResultExt,
};
macro_rules! bind_or_connect {
@@ -299,7 +302,7 @@ impl PalSocket for Sys {
return -1;
}
if address == ptr::null_mut() || address_len == ptr::null_mut() {
Self::read(socket, slice::from_raw_parts_mut(buf as *mut u8, len))
Self::read(socket, slice::from_raw_parts_mut(buf as *mut u8, len)).or_minus_one_errno()
} else {
let fd = e(syscall::dup(socket as usize, b"listen"));
if fd == !0 {
@@ -310,7 +313,8 @@ impl PalSocket for Sys {
return -1;
}
let ret = Self::read(fd as c_int, slice::from_raw_parts_mut(buf as *mut u8, len));
let ret = Self::read(fd as c_int, slice::from_raw_parts_mut(buf as *mut u8, len))
.or_minus_one_errno();
let _ = syscall::close(fd);
ret
}
@@ -343,10 +347,11 @@ impl PalSocket for Sys {
return -1;
}
if dest_addr == ptr::null() || dest_len == 0 {
Self::write(socket, slice::from_raw_parts(buf as *const u8, len))
Self::write(socket, slice::from_raw_parts(buf as *const u8, len)).or_minus_one_errno()
} else {
let fd = bind_or_connect!(connect copy, socket, dest_addr, dest_len);
let ret = Self::write(fd as c_int, slice::from_raw_parts(buf as *const u8, len));
let ret = Self::write(fd as c_int, slice::from_raw_parts(buf as *const u8, len))
.or_minus_one_errno();
let _ = syscall::close(fd);
ret
}
@@ -380,7 +385,7 @@ impl PalSocket for Sys {
tv_nsec: timeval.tv_usec * 1000,
};
let ret = Self::write(fd as c_int, &timespec);
let ret = Self::write(fd as c_int, &timespec).or_minus_one_errno();
let _ = syscall::close(fd);
+5 -2
View File
@@ -2,7 +2,10 @@ use alloc::vec::Vec;
use crate::platform::{types::*, Pal, Sys};
use crate::header::unistd::{lseek, SEEK_SET};
use crate::{
header::unistd::{lseek, SEEK_SET},
pthread::ResultExt,
};
/// Implements an `Iterator` which returns on either newline or EOF.
#[derive(Clone)]
pub struct RawLineBuffer {
@@ -58,7 +61,7 @@ impl RawLineBuffer {
self.buf.set_len(capacity);
}
let read = Sys::read(self.fd, &mut self.buf[len..]);
let read = Sys::read(self.fd, &mut self.buf[len..]).or_minus_one_errno();
let read_usize = read.max(0) as usize;