WIP: use upper fd table
This commit is contained in:
@@ -419,7 +419,10 @@ unsafe fn find_env(search: *const c_char) -> Option<(usize, *mut c_char)> {
|
||||
let mut search = search;
|
||||
loop {
|
||||
let end_of_query = *search == 0 || *search == b'=' as c_char;
|
||||
assert_ne!(*item, 0, "environ has an item without value");
|
||||
if *item == 0 {
|
||||
//TODO: environ has an item without value, is this a problem?
|
||||
break;
|
||||
}
|
||||
if *item == b'=' as c_char || end_of_query {
|
||||
if *item == b'=' as c_char && end_of_query {
|
||||
// Both keys env here
|
||||
|
||||
@@ -41,17 +41,13 @@ pub const SIOCATMARK: c_ulong = 0x8905;
|
||||
// TODO: some of the structs passed as T have padding bytes, so casting to a byte slice is UB
|
||||
|
||||
fn dup_read<T>(fd: c_int, name: &str, t: &mut T) -> syscall::Result<usize> {
|
||||
let dup = syscall::dup(fd as usize, name.as_bytes())?;
|
||||
let dup = FdGuard::new(syscall::dup(fd as usize, name.as_bytes())?);
|
||||
|
||||
let size = mem::size_of::<T>();
|
||||
|
||||
let res = syscall::read(dup, unsafe {
|
||||
slice::from_raw_parts_mut(t as *mut T as *mut u8, size)
|
||||
});
|
||||
let bytes = dup.read(unsafe { slice::from_raw_parts_mut(t as *mut T as *mut u8, size) })?;
|
||||
|
||||
let _ = syscall::close(dup);
|
||||
|
||||
res.map(|bytes| bytes / size)
|
||||
Ok(bytes / size)
|
||||
}
|
||||
|
||||
// FIXME: unsound
|
||||
@@ -60,11 +56,9 @@ fn dup_write<T>(fd: c_int, name: &str, t: &T) -> Result<usize> {
|
||||
|
||||
let size = mem::size_of::<T>();
|
||||
|
||||
let bytes_written = syscall::write(*dup, unsafe {
|
||||
slice::from_raw_parts(t as *const T as *const u8, size)
|
||||
})?;
|
||||
let bytes = dup.write(unsafe { slice::from_raw_parts(t as *const T as *const u8, size) })?;
|
||||
|
||||
Ok(bytes_written / size)
|
||||
Ok(bytes / size)
|
||||
}
|
||||
|
||||
unsafe fn ioctl_inner(fd: c_int, request: c_ulong, out: *mut c_void) -> Result<c_int> {
|
||||
|
||||
+5
-5
@@ -579,14 +579,14 @@ impl DSO {
|
||||
}
|
||||
}
|
||||
};
|
||||
let voff = ph.p_vaddr(endian) % ph.p_align(endian);
|
||||
let vsize = ((ph.p_memsz(endian) + voff) as usize)
|
||||
let _voff = ph.p_vaddr(endian) % ph.p_align(endian);
|
||||
let _vsize = ((ph.p_memsz(endian) + _voff) as usize)
|
||||
.next_multiple_of(ph.p_align(endian) as usize);
|
||||
trace!(
|
||||
" copy {:#x}, {:#x}: {:#x}, {:#x}",
|
||||
ph.p_vaddr(endian) - voff,
|
||||
vsize,
|
||||
voff,
|
||||
ph.p_vaddr(endian) - _voff,
|
||||
_vsize,
|
||||
_voff,
|
||||
obj_data.len()
|
||||
);
|
||||
mmap_data.copy_from_slice(obj_data);
|
||||
|
||||
+14
-12
@@ -40,7 +40,7 @@ static mut STATIC_TCB_MASTER: Master = Master {
|
||||
#[inline(never)]
|
||||
pub fn static_init(
|
||||
sp: &'static Stack,
|
||||
#[cfg(target_os = "redox")] thr_fd: redox_rt::proc::FdGuard,
|
||||
#[cfg(target_os = "redox")] thr_fd: redox_rt::proc::FdGuardUpper,
|
||||
) {
|
||||
const SIZEOF_PHDR64: usize = mem::size_of::<ProgramHeader64<Endianness>>();
|
||||
const SIZEOF_PHDR32: usize = mem::size_of::<ProgramHeader32<Endianness>>();
|
||||
@@ -135,7 +135,7 @@ pub fn static_init(
|
||||
#[cfg(any(target_os = "linux", target_os = "redox"))]
|
||||
pub unsafe fn init(
|
||||
sp: &'static Stack,
|
||||
#[cfg(target_os = "redox")] thr_fd: redox_rt::proc::FdGuard,
|
||||
#[cfg(target_os = "redox")] thr_fd: redox_rt::proc::FdGuardUpper,
|
||||
) {
|
||||
let tp: usize;
|
||||
|
||||
@@ -157,12 +157,13 @@ pub unsafe fn init(
|
||||
{
|
||||
let mut env = syscall::EnvRegisters::default();
|
||||
|
||||
let file = syscall::dup(*thr_fd, b"regs/env")
|
||||
.expect_notls("failed to open handle for process registers");
|
||||
{
|
||||
let file = thr_fd
|
||||
.dup(b"regs/env")
|
||||
.expect_notls("failed to open handle for process registers");
|
||||
|
||||
let _ = syscall::read(file, &mut env).expect_notls("failed to read gsbase");
|
||||
|
||||
let _ = syscall::close(file);
|
||||
file.read(&mut env).expect_notls("failed to read gsbase");
|
||||
}
|
||||
|
||||
tp = env.gsbase as usize;
|
||||
}
|
||||
@@ -170,12 +171,13 @@ pub unsafe fn init(
|
||||
{
|
||||
let mut env = syscall::EnvRegisters::default();
|
||||
|
||||
let file = syscall::dup(*thr_fd, b"regs/env")
|
||||
.expect_notls("failed to open handle for process registers");
|
||||
{
|
||||
let file = thr_fd
|
||||
.dup(b"regs/env")
|
||||
.expect_notls("failed to open handle for process registers");
|
||||
|
||||
let _ = syscall::read(file, &mut env).expect_notls("failed to read fsbase");
|
||||
|
||||
let _ = syscall::close(file);
|
||||
file.read(&mut env).expect_notls("failed to read fsbase");
|
||||
}
|
||||
|
||||
tp = env.fsbase as usize;
|
||||
}
|
||||
|
||||
+8
-2
@@ -163,7 +163,9 @@ pub unsafe extern "C" fn relibc_ld_so_start(sp: &'static mut Stack, ld_entry: us
|
||||
let tcb = Tcb::new(0).expect_notls("ld.so: failed to allocate bootstrap TCB");
|
||||
tcb.activate(
|
||||
#[cfg(target_os = "redox")]
|
||||
redox_rt::proc::FdGuard::new(thr_fd),
|
||||
redox_rt::proc::FdGuard::new(thr_fd)
|
||||
.to_upper()
|
||||
.expect_notls("failed to move thread fd to upper table"),
|
||||
);
|
||||
#[cfg(target_os = "redox")]
|
||||
{
|
||||
@@ -173,7 +175,11 @@ pub unsafe extern "C" fn relibc_ld_so_start(sp: &'static mut Stack, ld_entry: us
|
||||
)
|
||||
.expect_notls("no proc fd present");
|
||||
|
||||
redox_rt::initialize(redox_rt::proc::FdGuard::new(proc_fd));
|
||||
redox_rt::initialize(
|
||||
redox_rt::proc::FdGuard::new(proc_fd)
|
||||
.to_upper()
|
||||
.expect_notls("failed to move proc fd to upper table"),
|
||||
);
|
||||
redox_rt::signal::setup_sighandler(&tcb.os_specific, true);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-2
@@ -205,7 +205,10 @@ impl Tcb {
|
||||
}
|
||||
|
||||
/// Activate TLS
|
||||
pub unsafe fn activate(&mut self, #[cfg(target_os = "redox")] thr_fd: redox_rt::proc::FdGuard) {
|
||||
pub unsafe fn activate(
|
||||
&mut self,
|
||||
#[cfg(target_os = "redox")] thr_fd: redox_rt::proc::FdGuardUpper,
|
||||
) {
|
||||
unsafe {
|
||||
Self::os_arch_activate(
|
||||
&self.os_specific,
|
||||
@@ -345,7 +348,7 @@ impl Tcb {
|
||||
os: &OsSpecific,
|
||||
tls_end: usize,
|
||||
tls_len: usize,
|
||||
thr_fd: redox_rt::proc::FdGuard,
|
||||
thr_fd: redox_rt::proc::FdGuardUpper,
|
||||
) {
|
||||
unsafe {
|
||||
os.thr_fd.get().write(Some(thr_fd));
|
||||
|
||||
+1
-1
@@ -334,7 +334,7 @@ pub unsafe fn init(auxvs: Box<[[usize; 2]]>) {
|
||||
let Some(proc_fd) = get_auxv(&auxvs, AT_REDOX_PROC_FD) else {
|
||||
panic!("Missing proc and thread fd!");
|
||||
};
|
||||
redox_rt::initialize(FdGuard::new(proc_fd));
|
||||
redox_rt::initialize(FdGuard::new(proc_fd).to_upper().unwrap());
|
||||
|
||||
// TODO: Is it safe to assume setup_sighandler has been called at this point?
|
||||
redox_rt::sys::this_proc_call(
|
||||
|
||||
@@ -16,13 +16,13 @@ use crate::{
|
||||
|
||||
use redox_rt::{
|
||||
RtTcb,
|
||||
proc::{ExtraInfo, FdGuard, FexecResult, InterpOverride},
|
||||
proc::{ExtraInfo, FdGuard, FdGuardUpper, FexecResult, InterpOverride},
|
||||
sys::Resugid,
|
||||
};
|
||||
use syscall::{data::Stat, error::*, flag::*};
|
||||
|
||||
fn fexec_impl(
|
||||
exec_file: FdGuard,
|
||||
exec_file: FdGuardUpper,
|
||||
path: &[u8],
|
||||
args: &[&[u8]],
|
||||
envs: &[&[u8]],
|
||||
@@ -30,7 +30,7 @@ fn fexec_impl(
|
||||
extrainfo: &ExtraInfo,
|
||||
interp_override: Option<InterpOverride>,
|
||||
) -> Result<Infallible> {
|
||||
let memory = FdGuard::new(syscall::open("/scheme/memory", 0)?);
|
||||
let memory = FdGuard::open("/scheme/memory", 0)?.to_upper()?;
|
||||
|
||||
let addrspace_selection_fd = match redox_rt::proc::fexec_impl(
|
||||
exec_file,
|
||||
@@ -231,8 +231,13 @@ pub fn execve(
|
||||
// scenarios. While execve() is undefined according to POSIX if there exist sibling
|
||||
// threads, it could still be allowed by keeping certain file descriptors and instead
|
||||
// set the active file table.
|
||||
let files_fd =
|
||||
File::new(syscall::dup(**RtTcb::current().thread_fd(), b"filetable")? as c_int);
|
||||
let files_fd = File::new(
|
||||
c_int::try_from(syscall::dup(
|
||||
RtTcb::current().thread_fd().as_raw_fd(),
|
||||
b"filetable",
|
||||
)?)
|
||||
.unwrap(),
|
||||
);
|
||||
for line in BufReader::new(files_fd).lines() {
|
||||
let line = match line {
|
||||
Ok(l) => l,
|
||||
@@ -252,7 +257,7 @@ pub fn execve(
|
||||
}
|
||||
|
||||
// TODO: Convert image_file to FdGuard earlier?
|
||||
let exec_fd_guard = FdGuard::new(image_file.fd as usize);
|
||||
let exec_fd_guard = FdGuard::new(image_file.fd as usize).to_upper().unwrap();
|
||||
core::mem::forget(image_file);
|
||||
|
||||
let sigprocmask = redox_rt::signal::get_sigmask().unwrap();
|
||||
@@ -263,8 +268,8 @@ pub fn execve(
|
||||
sigignmask: redox_rt::signal::get_sigignmask_to_inherit(),
|
||||
sigprocmask,
|
||||
umask: redox_rt::sys::get_umask(),
|
||||
thr_fd: **RtTcb::current().thread_fd(),
|
||||
proc_fd: **redox_rt::current_proc_fd(),
|
||||
thr_fd: RtTcb::current().thread_fd().as_raw_fd(),
|
||||
proc_fd: redox_rt::current_proc_fd().as_raw_fd(),
|
||||
};
|
||||
fexec_impl(
|
||||
exec_fd_guard,
|
||||
|
||||
@@ -22,14 +22,14 @@ pub unsafe extern "C" fn redox_fpath(fd: c_int, buf: *mut c_void, count: size_t)
|
||||
pub fn pipe2(flags: usize) -> syscall::error::Result<[c_int; 2]> {
|
||||
let read_flags = flags | O_RDONLY;
|
||||
let write_flags = flags | O_WRONLY;
|
||||
let mut read_fd = FdGuard::new(syscall::open("/scheme/pipe", read_flags)?);
|
||||
let mut write_fd = FdGuard::new(syscall::dup(*read_fd, b"write")?);
|
||||
syscall::fcntl(*write_fd, F_SETFL, write_flags)?;
|
||||
syscall::fcntl(*write_fd, F_SETFD, write_flags)?;
|
||||
let mut read_fd = FdGuard::open("/scheme/pipe", read_flags)?;
|
||||
let mut write_fd = read_fd.dup(b"write")?;
|
||||
write_fd.fcntl(F_SETFL, write_flags)?;
|
||||
write_fd.fcntl(F_SETFD, write_flags)?;
|
||||
|
||||
let fds = [
|
||||
c_int::try_from(*read_fd).map_err(|_| Error::new(EMFILE))?,
|
||||
c_int::try_from(*write_fd).map_err(|_| Error::new(EMFILE))?,
|
||||
c_int::try_from(read_fd.as_raw_fd()).map_err(|_| Error::new(EMFILE))?,
|
||||
c_int::try_from(write_fd.as_raw_fd()).map_err(|_| Error::new(EMFILE))?,
|
||||
];
|
||||
|
||||
read_fd.take();
|
||||
|
||||
@@ -146,6 +146,7 @@ pub unsafe extern "C" fn redox_openat_v1(
|
||||
fd,
|
||||
str::from_utf8_unchecked(slice::from_raw_parts(path_base, path_len)),
|
||||
flags as usize,
|
||||
0, //TODO: openat fcntl_flags
|
||||
))
|
||||
}
|
||||
#[unsafe(no_mangle)]
|
||||
@@ -386,12 +387,12 @@ pub unsafe extern "C" fn redox_mkns_v1(
|
||||
// ABI-UNSTABLE
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn redox_cur_procfd_v0() -> usize {
|
||||
**redox_rt::current_proc_fd()
|
||||
redox_rt::current_proc_fd().as_raw_fd()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn redox_cur_thrfd_v0() -> usize {
|
||||
**redox_rt::RtTcb::current().thread_fd()
|
||||
redox_rt::RtTcb::current().thread_fd().as_raw_fd()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
|
||||
@@ -112,7 +112,7 @@ impl Pal for Sys {
|
||||
|
||||
let mut stat = syscall::Stat::default();
|
||||
|
||||
syscall::fstat(*fd as usize, &mut stat)?;
|
||||
fd.fstat(&mut stat)?;
|
||||
|
||||
let Resugid { ruid, rgid, .. } = redox_rt::sys::posix_getresugid();
|
||||
|
||||
@@ -500,8 +500,8 @@ impl Pal for Sys {
|
||||
}
|
||||
|
||||
//TODO: store fd internally
|
||||
let fd = FdGuard::new(syscall::open(path, open_flags)?);
|
||||
Ok(syscall::read(*fd, buf)?)
|
||||
let fd = FdGuard::open(path, open_flags)?;
|
||||
Ok(fd.read(buf)?)
|
||||
}
|
||||
|
||||
fn getresgid(
|
||||
@@ -578,8 +578,8 @@ impl Pal for Sys {
|
||||
fn gettid() -> pid_t {
|
||||
// This is used by pthread mutexes for reentrant checks and must be nonzero
|
||||
// and unique for each thread in the same process (but not cross-process)
|
||||
Self::current_os_tid()
|
||||
.thread_fd
|
||||
let thread_fd = Self::current_os_tid().thread_fd;
|
||||
(thread_fd & !syscall::UPPER_FDTBL_TAG)
|
||||
.checked_add(1)
|
||||
.unwrap()
|
||||
.try_into()
|
||||
@@ -861,7 +861,7 @@ impl Pal for Sys {
|
||||
}
|
||||
fn current_os_tid() -> crate::pthread::OsTid {
|
||||
crate::pthread::OsTid {
|
||||
thread_fd: **RtTcb::current().thread_fd(),
|
||||
thread_fd: RtTcb::current().thread_fd().as_raw_fd(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1070,7 +1070,7 @@ impl Pal for Sys {
|
||||
}
|
||||
|
||||
let path = format!("/scheme/time/{clock_id}");
|
||||
let timerfd = FdGuard::new(libredox::open(&path, O_RDWR, 0)?);
|
||||
let timerfd = FdGuard::open(&path, syscall::O_RDWR)?;
|
||||
let eventfd = FdGuard::new(Error::demux(unsafe {
|
||||
event::redox_event_queue_create_v1(0)
|
||||
})?);
|
||||
|
||||
@@ -156,7 +156,7 @@ pub fn open(path: &str, flags: usize) -> Result<usize> {
|
||||
let resolve_flags = O_CLOEXEC | O_SYMLINK | O_RDONLY;
|
||||
let resolve_fd = FdGuard::new(syscall::open(&*canon, resolve_flags)?);
|
||||
|
||||
let bytes_read = syscall::read(*resolve_fd, &mut resolve_buf)?;
|
||||
let bytes_read = resolve_fd.read(&mut resolve_buf)?;
|
||||
// TODO: make resolve_buf PATH_MAX + 1 bytes?
|
||||
if bytes_read == resolve_buf.len() {
|
||||
return Err(Error::new(ENAMETOOLONG));
|
||||
|
||||
@@ -281,7 +281,7 @@ unsafe fn serialize_ancillary_data_to_stream(
|
||||
let fds_slice = slice::from_raw_parts(fds_ptr, fd_count);
|
||||
for &fd in fds_slice.iter() {
|
||||
let fd_to_send = FdGuard::new(syscall::dup(fd as usize, b"")?);
|
||||
syscall::sendfd(socket as usize, *fd_to_send as usize, 0, 0)?;
|
||||
syscall::sendfd(socket as usize, fd_to_send.as_raw_fd(), 0, 0)?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -562,12 +562,12 @@ impl PalSocket for Sys {
|
||||
)?;
|
||||
|
||||
let fs_bind_result = (|| -> Result<()> {
|
||||
let dirfd = FdGuard::new(syscall::open(
|
||||
let dirfd = FdGuard::open(
|
||||
&dir_path,
|
||||
syscall::O_RDONLY | syscall::O_DIRECTORY | syscall::O_CLOEXEC,
|
||||
)?);
|
||||
)?;
|
||||
let fd_to_send = FdGuard::new(syscall::dup(socket as usize, &[])?);
|
||||
let _ = syscall::sendfd(*dirfd, *fd_to_send, 0, 0)?;
|
||||
syscall::sendfd(dirfd.as_raw_fd(), fd_to_send.as_raw_fd(), 0, 0)?;
|
||||
Ok(())
|
||||
})();
|
||||
|
||||
@@ -628,14 +628,14 @@ impl PalSocket for Sys {
|
||||
let (_, fd_path) = dir_path_and_fd_path(&path)?;
|
||||
|
||||
let target_path = format!("/{fd_path}");
|
||||
let socket_file_fd = FdGuard::new(syscall::open(&target_path, syscall::O_RDWR)?);
|
||||
let socket_file_fd = FdGuard::open(&target_path, syscall::O_RDWR)?;
|
||||
|
||||
const TOKEN_BUF_SIZE: usize = 16;
|
||||
|
||||
let mut token_buf = [0u8; TOKEN_BUF_SIZE];
|
||||
|
||||
redox_rt::sys::sys_call(
|
||||
*socket_file_fd,
|
||||
socket_file_fd.as_raw_fd(),
|
||||
&mut token_buf,
|
||||
CallFlags::empty(),
|
||||
&[FsCall::Connect as u64],
|
||||
@@ -809,9 +809,11 @@ impl PalSocket for Sys {
|
||||
Self::read(socket, slice::from_raw_parts_mut(buf as *mut u8, len))
|
||||
} else {
|
||||
let fd = FdGuard::new(syscall::dup(socket as usize, b"listen")?);
|
||||
Self::getpeername(*fd as c_int, address, address_len)?;
|
||||
|
||||
Self::read(*fd as c_int, slice::from_raw_parts_mut(buf as *mut u8, len))
|
||||
Self::getpeername(fd.as_c_fd().unwrap(), address, address_len)?;
|
||||
Self::read(
|
||||
fd.as_c_fd().unwrap(),
|
||||
slice::from_raw_parts_mut(buf as *mut u8, len),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -976,7 +978,10 @@ impl PalSocket for Sys {
|
||||
Self::write(socket, slice::from_raw_parts(buf as *const u8, len))
|
||||
} else {
|
||||
let fd = FdGuard::new(bind_or_connect!(connect copy, socket, dest_addr, dest_len)?);
|
||||
Self::write(*fd as c_int, slice::from_raw_parts(buf as *const u8, len))
|
||||
Self::write(
|
||||
fd.as_c_fd().unwrap(),
|
||||
slice::from_raw_parts(buf as *const u8, len),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1009,7 +1014,7 @@ impl PalSocket for Sys {
|
||||
tv_nsec,
|
||||
};
|
||||
|
||||
Self::write(*fd as c_int, ×pec)?;
|
||||
Self::write(fd.as_c_fd().unwrap(), ×pec)?;
|
||||
Ok(())
|
||||
};
|
||||
|
||||
@@ -1078,28 +1083,27 @@ impl PalSocket for Sys {
|
||||
|
||||
match (domain, kind) {
|
||||
(AF_UNIX, SOCK_STREAM) => {
|
||||
let listener = FdGuard::new(syscall::open("/scheme/uds_stream", flags | O_CREAT)?);
|
||||
let listener = FdGuard::open("/scheme/uds_stream", flags | O_CREAT)?;
|
||||
|
||||
// For now, uds_stream: lets connects be instant, and instead blocks
|
||||
// on any I/O performed. So we don't need to mark this as
|
||||
// nonblocking.
|
||||
|
||||
let mut fd0 = FdGuard::new(syscall::dup(*listener, b"connect")?);
|
||||
|
||||
let mut fd1 = FdGuard::new(syscall::dup(*listener, b"listen")?);
|
||||
let mut fd0 = listener.dup(b"connect")?;
|
||||
let mut fd1 = listener.dup(b"listen")?;
|
||||
|
||||
sv[0] = fd0.take() as c_int;
|
||||
sv[1] = fd1.take() as c_int;
|
||||
Ok(())
|
||||
}
|
||||
(AF_UNIX, SOCK_DGRAM) => {
|
||||
let listener = FdGuard::new(syscall::open("/scheme/uds_dgram", flags | O_CREAT)?);
|
||||
let listener = FdGuard::open("/scheme/uds_dgram", flags | O_CREAT)?;
|
||||
|
||||
// For now, uds_dgram: lets connects be instant, and instead blocks
|
||||
// on any I/O performed. So we don't need to mark this as
|
||||
// nonblocking.
|
||||
|
||||
let mut fd0 = FdGuard::new(syscall::dup(*listener, b"connect")?);
|
||||
let mut fd0 = listener.dup(b"connect")?;
|
||||
|
||||
sv[0] = fd0.take() as c_int;
|
||||
sv[1] = listener.take() as c_int;
|
||||
|
||||
+5
-1
@@ -229,7 +229,11 @@ unsafe extern "C" fn new_thread_shim(
|
||||
}
|
||||
#[cfg(target_os = "redox")]
|
||||
{
|
||||
tcb.activate(redox_rt::proc::FdGuard::new(tid.thread_fd));
|
||||
tcb.activate(
|
||||
redox_rt::proc::FdGuard::new(tid.thread_fd)
|
||||
.to_upper()
|
||||
.unwrap(),
|
||||
);
|
||||
redox_rt::signal::setup_sighandler(&tcb.os_specific, false);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -153,7 +153,9 @@ pub unsafe extern "C" fn relibc_start_v1(
|
||||
let thr_fd = redox_rt::proc::FdGuard::new(
|
||||
crate::platform::get_auxv_raw(sp.auxv().cast(), redox_rt::auxv_defs::AT_REDOX_THR_FD)
|
||||
.expect_notls("no thread fd present"),
|
||||
);
|
||||
)
|
||||
.to_upper()
|
||||
.expect_notls("failed to move thread fd to upper table");
|
||||
|
||||
// Initialize TLS, if necessary
|
||||
ld_so::init(
|
||||
|
||||
Reference in New Issue
Block a user