Pass si_pid to all realtime signals.
This commit is contained in:
@@ -97,11 +97,7 @@ unsafe extern "sysv64" fn fork_impl(initial_rsp: *mut usize) -> usize {
|
||||
|
||||
unsafe extern "sysv64" fn child_hook(cur_filetable_fd: usize, new_pid_fd: usize) {
|
||||
let _ = syscall::close(cur_filetable_fd);
|
||||
// TODO: Currently pidfd == threadfd, but this will not be the case later.
|
||||
RtTcb::current()
|
||||
.thr_fd
|
||||
.get()
|
||||
.write(Some(FdGuard::new(new_pid_fd)));
|
||||
crate::child_hook_common(FdGuard::new(new_pid_fd));
|
||||
}
|
||||
|
||||
asmfunction!(__relibc_internal_fork_wrapper -> usize: ["
|
||||
@@ -425,11 +421,7 @@ extern "C" {
|
||||
fn __relibc_internal_sigentry_crit_third();
|
||||
}
|
||||
/// Fixes some edge cases, and calculates the value for uc_stack.
|
||||
pub unsafe fn arch_pre(
|
||||
stack: &mut SigStack,
|
||||
area: &mut SigArea,
|
||||
targeted_thread: bool,
|
||||
) -> PosixStackt {
|
||||
pub unsafe fn arch_pre(stack: &mut SigStack, area: &mut SigArea) -> PosixStackt {
|
||||
// It is impossible to update RSP and RIP atomically on x86_64, without using IRETQ, which is
|
||||
// almost as slow as calling a SIGRETURN syscall would be. Instead, we abuse the fact that
|
||||
// signals are disabled in the prologue of the signal trampoline, which allows us to emulate
|
||||
@@ -451,14 +443,6 @@ pub unsafe fn arch_pre(
|
||||
stack.regs.rip = area.tmp_rip;
|
||||
}
|
||||
|
||||
stack.sig_code = if (stack.sig_num - 1) / 32 == 1 && !targeted_thread {
|
||||
area.tmp_inf.code as u32
|
||||
} else {
|
||||
// TODO: SIGCHLD information when applicable
|
||||
0
|
||||
};
|
||||
stack.sival = area.tmp_inf.arg;
|
||||
|
||||
PosixStackt {
|
||||
sp: stack.regs.rsp as *mut (),
|
||||
size: 0, // TODO
|
||||
|
||||
+19
-3
@@ -9,7 +9,7 @@
|
||||
)]
|
||||
#![forbid(unreachable_patterns)]
|
||||
|
||||
use core::cell::UnsafeCell;
|
||||
use core::cell::{SyncUnsafeCell, UnsafeCell};
|
||||
|
||||
use generic_rt::{ExpectTlsFree, GenericTcb};
|
||||
use syscall::{Sigcontrol, O_CLOEXEC};
|
||||
@@ -120,13 +120,13 @@ pub unsafe fn tcb_activate(tcb: &RtTcb, tls_end_and_tcb_start: usize, _tls_len:
|
||||
}
|
||||
|
||||
/// Initialize redox-rt in situations where relibc is not used
|
||||
pub fn initialize_freestanding() {
|
||||
pub unsafe fn initialize_freestanding() {
|
||||
// TODO: This code is a hack! Integrate the ld_so TCB code into generic-rt, and then use that
|
||||
// (this function will need pointers to the ELF structs normally passed in auxvs), so the TCB
|
||||
// is initialized properly.
|
||||
|
||||
// TODO: TLS
|
||||
let page = unsafe {
|
||||
let page = {
|
||||
&mut *(syscall::fmap(
|
||||
!0,
|
||||
&syscall::Map {
|
||||
@@ -155,4 +155,20 @@ pub fn initialize_freestanding() {
|
||||
let abi_ptr = core::ptr::addr_of_mut!(page.tcb_ptr);
|
||||
core::arch::asm!("msr tpidr_el0, {}", in(reg) abi_ptr);
|
||||
}
|
||||
initialize();
|
||||
}
|
||||
pub unsafe fn initialize() {
|
||||
THIS_PID
|
||||
.get()
|
||||
.write(Some(syscall::getpid().unwrap().try_into().unwrap()).unwrap());
|
||||
}
|
||||
|
||||
static THIS_PID: SyncUnsafeCell<u32> = SyncUnsafeCell::new(0);
|
||||
|
||||
unsafe fn child_hook_common(new_pid_fd: FdGuard) {
|
||||
// TODO: Currently pidfd == threadfd, but this will not be the case later.
|
||||
RtTcb::current().thr_fd.get().write(Some(new_pid_fd));
|
||||
THIS_PID
|
||||
.get()
|
||||
.write(Some(syscall::getpid().unwrap().try_into().unwrap()).unwrap());
|
||||
}
|
||||
|
||||
+18
-4
@@ -81,13 +81,27 @@ unsafe fn inner(stack: &mut SigStack) {
|
||||
|
||||
// asm counts from 0
|
||||
stack.sig_num += 1;
|
||||
stack.old_stack = arch_pre(stack, &mut *os.arch.get(), targeted_thread_not_process);
|
||||
|
||||
let (sender_pid, sender_uid) = {
|
||||
let area = &mut *os.arch.get();
|
||||
|
||||
stack.sival = area.tmp_inf.arg;
|
||||
stack.old_stack = arch_pre(stack, area);
|
||||
|
||||
if (stack.sig_num - 1) / 32 == 1 && !targeted_thread_not_process {
|
||||
stack.sig_code = area.tmp_inf.code as u32;
|
||||
(area.tmp_inf.pid, area.tmp_inf.uid)
|
||||
} else {
|
||||
// TODO: SIGCHLD information when applicable
|
||||
stack.sig_code = 0;
|
||||
(0, 0) // TODO
|
||||
}
|
||||
};
|
||||
|
||||
let sigaction = {
|
||||
let guard = SIGACTIONS_LOCK.lock();
|
||||
let action = convert_old(&PROC_CONTROL_STRUCT.actions[stack.sig_num as usize - 1]);
|
||||
if action.flags.contains(SigactionFlags::RESETHAND) {
|
||||
// TODO: other things that must be set
|
||||
drop(guard);
|
||||
sigaction(
|
||||
stack.sig_num as u8,
|
||||
@@ -159,9 +173,9 @@ unsafe fn inner(stack: &mut SigStack) {
|
||||
si_addr: core::ptr::null_mut(),
|
||||
si_code: stack.sig_code as i32,
|
||||
si_errno: 0,
|
||||
si_pid: 0, // TODO
|
||||
si_pid: sender_pid as i32,
|
||||
si_status: 0,
|
||||
si_uid: 0, // TODO
|
||||
si_uid: sender_uid as i32,
|
||||
si_value: stack.sival,
|
||||
};
|
||||
sigaction(
|
||||
|
||||
+8
-1
@@ -49,7 +49,9 @@ pub fn posix_kill(pid: usize, sig: usize) -> Result<()> {
|
||||
pub fn posix_sigqueue(pid: usize, sig: usize, arg: usize) -> Result<()> {
|
||||
let siginf = RtSigInfo {
|
||||
arg,
|
||||
code: usize::wrapping_neg(1), // TODO: SI_QUEUE
|
||||
code: -1, // TODO: SI_QUEUE constant
|
||||
uid: 0, // TODO
|
||||
pid: posix_getpid(),
|
||||
};
|
||||
match wrapper(false, || unsafe {
|
||||
syscall::syscall3(syscall::SYS_SIGENQUEUE, pid, sig, addr_of!(siginf) as usize)
|
||||
@@ -59,6 +61,11 @@ pub fn posix_sigqueue(pid: usize, sig: usize, arg: usize) -> Result<()> {
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
pub fn posix_getpid() -> u32 {
|
||||
// SAFETY: read-only except during program/fork child initialization
|
||||
unsafe { crate::THIS_PID.get().read() }
|
||||
}
|
||||
#[inline]
|
||||
pub fn posix_killpg(pgrp: usize, sig: usize) -> Result<()> {
|
||||
match wrapper(false, || syscall::kill(usize::wrapping_neg(pgrp), sig)) {
|
||||
Ok(_) | Err(Error { errno: EINTR }) => Ok(()),
|
||||
|
||||
+4
-1
@@ -141,6 +141,7 @@ fn resolve_path_name(
|
||||
}
|
||||
None
|
||||
}
|
||||
// TODO: Make unsafe
|
||||
#[no_mangle]
|
||||
pub extern "C" fn relibc_ld_so_start(sp: &'static mut Stack, ld_entry: usize) -> usize {
|
||||
// We get the arguments, the environment, and the auxilary vector
|
||||
@@ -184,7 +185,9 @@ pub extern "C" fn relibc_ld_so_start(sp: &'static mut Stack, ld_entry: usize) ->
|
||||
}
|
||||
|
||||
// TODO: Fix memory leak, although minimal.
|
||||
crate::platform::init(auxv.clone());
|
||||
unsafe {
|
||||
crate::platform::init(auxv.clone());
|
||||
}
|
||||
|
||||
// Some variables that will be overridden by environment and auxiliary vectors
|
||||
let ld_library_path = envs.get("LD_LIBRARY_PATH").map(|s| s.to_owned());
|
||||
|
||||
+5
-3
@@ -283,15 +283,17 @@ pub fn get_auxv(auxvs: &[[usize; 2]], key: usize) -> Option<usize> {
|
||||
|
||||
#[cold]
|
||||
#[cfg(target_os = "redox")]
|
||||
pub fn init(auxvs: Box<[[usize; 2]]>) {
|
||||
// SAFETY: Must only be called when only one thread exists.
|
||||
pub unsafe fn init(auxvs: Box<[[usize; 2]]>) {
|
||||
redox_rt::initialize();
|
||||
|
||||
use self::auxv_defs::*;
|
||||
|
||||
if let (Some(cwd_ptr), Some(cwd_len)) = (
|
||||
get_auxv(&auxvs, AT_REDOX_INITIAL_CWD_PTR),
|
||||
get_auxv(&auxvs, AT_REDOX_INITIAL_CWD_LEN),
|
||||
) {
|
||||
let cwd_bytes: &'static [u8] =
|
||||
unsafe { core::slice::from_raw_parts(cwd_ptr as *const u8, cwd_len) };
|
||||
let cwd_bytes: &'static [u8] = core::slice::from_raw_parts(cwd_ptr as *const u8, cwd_len);
|
||||
if let Ok(cwd) = core::str::from_utf8(cwd_bytes) {
|
||||
self::sys::path::set_cwd_manual(cwd.into());
|
||||
}
|
||||
|
||||
@@ -470,7 +470,7 @@ impl Pal for Sys {
|
||||
}
|
||||
|
||||
fn getpid() -> pid_t {
|
||||
e(syscall::getpid()) as pid_t
|
||||
redox_rt::sys::posix_getpid() as pid_t
|
||||
}
|
||||
|
||||
fn getppid() -> pid_t {
|
||||
|
||||
@@ -39,6 +39,7 @@ pub struct ucontext_t {
|
||||
}
|
||||
|
||||
const _: () = {
|
||||
#[track_caller]
|
||||
const fn assert_eq(a: usize, b: usize) {
|
||||
if a != b {
|
||||
panic!("compile-time struct verification failed");
|
||||
|
||||
@@ -12,12 +12,15 @@
|
||||
|
||||
volatile sig_atomic_t num = 1;
|
||||
|
||||
int parent;
|
||||
|
||||
void action(int sig, siginfo_t *info, void *context) {
|
||||
(void)context;
|
||||
assert(sig == THE_SIG);
|
||||
assert(info->si_signo == THE_SIG);
|
||||
assert(info->si_value.sival_int == num);
|
||||
assert(info->si_code == SI_QUEUE);
|
||||
assert(info->si_pid == parent);
|
||||
num++;
|
||||
write(1, "action\n", 7);
|
||||
}
|
||||
@@ -28,6 +31,9 @@ int main(void) {
|
||||
status = pipe(fds);
|
||||
ERROR_IF(pipe, status, == -1);
|
||||
|
||||
parent = getpid();
|
||||
assert(parent != 0);
|
||||
|
||||
int child = fork();
|
||||
ERROR_IF(fork, child, == -1);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user