pub mod fs;
pub mod mem;
pub mod pid;
pub mod pipe;
pub mod poll;
pub mod pty;
pub mod serial;
pub mod socket;
pub mod term;
pub mod time;
pub mod timer;

use std::{
    io,
    os::{fd::RawFd, yggdrasil::process::CommandExt},
    process::Command,
};

pub use mem::{FileMappingImpl, SharedMemoryImpl};
pub use pid::PidFdImpl;
pub use pipe::PipeImpl;
pub use poll::PollImpl;
pub use pty::{open as open_pty, PtyMasterImpl, PtySlaveImpl, TerminalOptionsImpl};
pub use serial::SerialPortImpl;
pub use socket::{BorrowedAddressImpl, LocalPacketSocketImpl, OwnedAddressImpl};
pub use term::RawStdinImpl;
pub use timer::TimerFdImpl;

use crate::process::CommandSpawnExt;

pub fn set_sigint_handler(_handler: fn()) {}

pub fn send_kill(pid: u32) -> io::Result<()> {
    use runtime::rt::{
        process::{ProcessId, Signal},
        sys as syscall,
    };

    let target = unsafe { ProcessId::from_raw(pid) };
    unsafe { syscall::send_signal(target, Signal::Killed) }.map_err(io::Error::from)?;
    Ok(())
}

pub fn clone_fd(fd: RawFd) -> io::Result<RawFd> {
    let fd = unsafe { runtime::rt::sys::clone_fd(fd, None) }?;
    Ok(fd)
}

impl CommandSpawnExt for Command {
    fn create_process_group(&mut self) -> io::Result<&mut Self> {
        let group = unsafe { runtime::rt::sys::create_process_group() };
        Ok(self.process_group(group))
    }

    fn create_session(&mut self) -> io::Result<&mut Self> {
        Ok(unsafe { self.gain_terminal(0) })
    }
}
