Implement pread and pwrite using the syscalls.
This commit is contained in:
@@ -6,6 +6,7 @@ use crate::{
|
||||
},
|
||||
io,
|
||||
platform::{types::*, Pal, Sys},
|
||||
pthread::ResultExt,
|
||||
};
|
||||
use core::ops::Deref;
|
||||
|
||||
@@ -72,7 +73,7 @@ impl File {
|
||||
|
||||
impl io::Read for &File {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
match Sys::read(self.fd, buf) {
|
||||
match Sys::read(self.fd, buf).or_minus_one_errno() /* TODO */ {
|
||||
-1 => Err(io::last_os_error()),
|
||||
ok => Ok(ok as usize),
|
||||
}
|
||||
@@ -81,7 +82,7 @@ impl io::Read for &File {
|
||||
|
||||
impl io::Write for &File {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
match Sys::write(self.fd, buf) {
|
||||
match Sys::write(self.fd, buf).or_minus_one_errno() {
|
||||
-1 => Err(io::last_os_error()),
|
||||
ok => Ok(ok as usize),
|
||||
}
|
||||
|
||||
+25
-41
@@ -17,6 +17,7 @@ use crate::{
|
||||
time::timespec,
|
||||
},
|
||||
platform::{self, types::*, Pal, Sys},
|
||||
pthread::ResultExt,
|
||||
};
|
||||
use alloc::collections::LinkedList;
|
||||
|
||||
@@ -577,24 +578,18 @@ pub unsafe extern "C" fn pipe2(fildes: *mut c_int, flags: c_int) -> c_int {
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn pread(fildes: c_int, buf: *mut c_void, nbyte: size_t, offset: off_t) -> ssize_t {
|
||||
//TODO: better pread using system calls
|
||||
|
||||
let previous = lseek(fildes, offset, SEEK_SET);
|
||||
if previous == -1 {
|
||||
return -1;
|
||||
}
|
||||
|
||||
let res = read(fildes, buf, nbyte);
|
||||
if res < 0 {
|
||||
return res;
|
||||
}
|
||||
|
||||
if lseek(fildes, previous, SEEK_SET) == -1 {
|
||||
return -1;
|
||||
}
|
||||
|
||||
res
|
||||
pub unsafe extern "C" fn pread(
|
||||
fildes: c_int,
|
||||
buf: *mut c_void,
|
||||
nbyte: size_t,
|
||||
offset: off_t,
|
||||
) -> ssize_t {
|
||||
Sys::pread(
|
||||
fildes,
|
||||
slice::from_raw_parts_mut(buf.cast::<u8>(), nbyte),
|
||||
offset,
|
||||
)
|
||||
.or_minus_one_errno()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -617,36 +612,25 @@ pub extern "C" fn pthread_atfork(
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn pwrite(
|
||||
pub unsafe extern "C" fn pwrite(
|
||||
fildes: c_int,
|
||||
buf: *const c_void,
|
||||
nbyte: size_t,
|
||||
offset: off_t,
|
||||
) -> ssize_t {
|
||||
//TODO: better pwrite using system calls
|
||||
|
||||
let previous = lseek(fildes, offset, SEEK_SET);
|
||||
if previous == -1 {
|
||||
return -1;
|
||||
}
|
||||
|
||||
let res = write(fildes, buf, nbyte);
|
||||
if res < 0 {
|
||||
return res;
|
||||
}
|
||||
|
||||
if lseek(fildes, previous, SEEK_SET) == -1 {
|
||||
return -1;
|
||||
}
|
||||
|
||||
res
|
||||
Sys::pwrite(
|
||||
fildes,
|
||||
slice::from_raw_parts(buf.cast::<u8>(), nbyte),
|
||||
offset,
|
||||
)
|
||||
.or_minus_one_errno()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn read(fildes: c_int, buf: *const c_void, nbyte: size_t) -> ssize_t {
|
||||
pub unsafe extern "C" fn read(fildes: c_int, buf: *const c_void, nbyte: size_t) -> ssize_t {
|
||||
let buf = unsafe { slice::from_raw_parts_mut(buf as *mut u8, nbyte as usize) };
|
||||
trace_expr!(
|
||||
Sys::read(fildes, buf),
|
||||
Sys::read(fildes, buf).or_minus_one_errno(),
|
||||
"read({}, {:p}, {})",
|
||||
fildes,
|
||||
buf,
|
||||
@@ -853,7 +837,7 @@ pub extern "C" fn vfork() -> pid_t {
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn write(fildes: c_int, buf: *const c_void, nbyte: size_t) -> ssize_t {
|
||||
let buf = unsafe { slice::from_raw_parts(buf as *const u8, nbyte as usize) };
|
||||
Sys::write(fildes, buf)
|
||||
pub unsafe extern "C" fn write(fildes: c_int, buf: *const c_void, nbyte: size_t) -> ssize_t {
|
||||
let buf = slice::from_raw_parts(buf as *const u8, nbyte as usize);
|
||||
Sys::write(fildes, buf).or_minus_one_errno()
|
||||
}
|
||||
|
||||
+5
-1
@@ -4,7 +4,11 @@ use goblin::error::{Error, Result};
|
||||
|
||||
use super::ExpectTlsFree;
|
||||
use crate::{
|
||||
header::sys_mman, ld_so::linker::Linker, platform::{Dlmalloc, Pal, Sys}, pthread::{OsTid, Pthread}, sync::{mutex::Mutex, waitval::Waitval}
|
||||
header::sys_mman,
|
||||
ld_so::linker::Linker,
|
||||
platform::{Dlmalloc, Pal, Sys},
|
||||
pthread::{OsTid, Pthread},
|
||||
sync::{mutex::Mutex, waitval::Waitval},
|
||||
};
|
||||
|
||||
#[repr(C)]
|
||||
|
||||
+25
-22
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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, ×pec);
|
||||
let ret = Self::write(fd as c_int, ×pec).or_minus_one_errno();
|
||||
|
||||
let _ = syscall::close(fd);
|
||||
|
||||
|
||||
+5
-2
@@ -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;
|
||||
|
||||
|
||||
+27
-2
@@ -12,7 +12,8 @@ use crate::{
|
||||
header::{errno::*, pthread as header, sched::sched_param, sys_mman},
|
||||
ld_so::{
|
||||
linker::Linker,
|
||||
tcb::{Master, Tcb}, ExpectTlsFree,
|
||||
tcb::{Master, Tcb},
|
||||
ExpectTlsFree,
|
||||
},
|
||||
platform::{types::*, Pal, Sys},
|
||||
};
|
||||
@@ -23,7 +24,9 @@ const MAIN_PTHREAD_ID: usize = 1;
|
||||
|
||||
/// Called only by the main thread, as part of relibc_start.
|
||||
pub unsafe fn init() {
|
||||
Tcb::current().expect_notls("no TCB present for main thread").pthread = Pthread {
|
||||
Tcb::current()
|
||||
.expect_notls("no TCB present for main thread")
|
||||
.pthread = Pthread {
|
||||
waitval: Waitval::new(),
|
||||
has_enabled_cancelation: AtomicBool::new(false),
|
||||
has_queued_cancelation: AtomicBool::new(false),
|
||||
@@ -83,6 +86,28 @@ unsafe impl Sync for Pthread {}
|
||||
// TODO: Move to a more generic place.
|
||||
pub struct Errno(pub c_int);
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
impl From<syscall::Error> for Errno {
|
||||
fn from(value: syscall::Error) -> Self {
|
||||
Errno(value.errno)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ResultExt<T> {
|
||||
fn or_minus_one_errno(self) -> T;
|
||||
}
|
||||
impl<T: From<i8>> ResultExt<T> for Result<T, Errno> {
|
||||
fn or_minus_one_errno(self) -> T {
|
||||
match self {
|
||||
Self::Ok(v) => v,
|
||||
Self::Err(Errno(errno)) => unsafe {
|
||||
crate::platform::ERRNO.set(errno);
|
||||
T::from(-1)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct Retval(pub *mut c_void);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user