114 lines
3.4 KiB
Rust
114 lines
3.4 KiB
Rust
#![stable(feature = "os_fd", since = "1.66.0")]
|
|
#![allow(dead_code)]
|
|
|
|
mod net;
|
|
pub mod owned;
|
|
pub(crate) mod raw;
|
|
|
|
use crate::io::StdinLock;
|
|
|
|
use crate::mem::MaybeUninit;
|
|
use crate::path::Path;
|
|
use crate::sys::cvt_io;
|
|
use yggdrasil_rt::{
|
|
io::{FileMode, OpenOptions},
|
|
sys as syscall,
|
|
};
|
|
|
|
// Public exports
|
|
|
|
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
|
pub use yggdrasil_rt::io::{
|
|
DeviceRequest, MountOptions, TerminalInputOptions, TerminalLineOptions, TerminalOptions,
|
|
TerminalOutputOptions,
|
|
};
|
|
|
|
#[stable(feature = "io_safety", since = "1.63.0")]
|
|
pub use owned::*;
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
pub use raw::*;
|
|
|
|
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
|
pub trait FdDeviceRequest {
|
|
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
|
unsafe fn device_request(&self, req: &mut DeviceRequest) -> crate::io::Result<()>;
|
|
}
|
|
|
|
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
|
impl<T: AsRawFd> FdDeviceRequest for T {
|
|
unsafe fn device_request(&self, req: &mut DeviceRequest) -> crate::io::Result<()> {
|
|
cvt_io(syscall::device_request(self.as_raw_fd(), req))?;
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
impl<'a> AsRawFd for StdinLock<'a> {
|
|
fn as_raw_fd(&self) -> RawFd {
|
|
todo!()
|
|
}
|
|
}
|
|
|
|
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
|
pub unsafe fn set_terminal_options<F: raw::AsRawFd>(
|
|
fd: F,
|
|
opt: TerminalOptions,
|
|
) -> crate::io::Result<()> {
|
|
let mut req = DeviceRequest::SetTerminalOptions(opt);
|
|
cvt_io(syscall::device_request(fd.as_raw_fd(), &mut req))
|
|
}
|
|
|
|
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
|
pub unsafe fn get_terminal_options<F: raw::AsRawFd>(fd: F) -> crate::io::Result<TerminalOptions> {
|
|
let mut req = DeviceRequest::GetTerminalOptions(MaybeUninit::uninit());
|
|
cvt_io(syscall::device_request(fd.as_raw_fd(), &mut req))?;
|
|
let DeviceRequest::GetTerminalOptions(opt) = req else {
|
|
unreachable!();
|
|
};
|
|
Ok(opt.assume_init())
|
|
}
|
|
|
|
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
|
pub unsafe fn start_terminal_session<P: AsRef<Path>>(terminal: P) -> crate::io::Result<()> {
|
|
let terminal = terminal.as_ref().to_str().unwrap();
|
|
|
|
cvt_io(syscall::start_session())?;
|
|
|
|
// TODO implement open flags to explicitly set stdin/stdout/stderr
|
|
|
|
cvt_io(syscall::open(None, terminal, OpenOptions::READ, FileMode::empty()))?;
|
|
cvt_io(syscall::open(None, terminal, OpenOptions::WRITE, FileMode::empty()))?;
|
|
cvt_io(syscall::open(None, terminal, OpenOptions::WRITE, FileMode::empty()))?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
|
pub unsafe fn mount_raw(options: &MountOptions<'_>) -> crate::io::Result<()> {
|
|
cvt_io(syscall::mount(options))
|
|
}
|
|
|
|
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
|
pub fn create_pipe_pair() -> crate::io::Result<(RawFd, RawFd)> {
|
|
let mut buffer = MaybeUninit::uninit_array();
|
|
cvt_io(unsafe { syscall::create_pipe(&mut buffer) })?;
|
|
let read = unsafe { buffer[0].assume_init() };
|
|
let write = unsafe { buffer[1].assume_init() };
|
|
Ok((read, write))
|
|
}
|
|
|
|
#[unstable(feature = "yggdrasil_os", issue = "none")]
|
|
pub unsafe fn update_terminal_options<
|
|
F: raw::AsRawFd,
|
|
M: Fn(TerminalOptions) -> TerminalOptions,
|
|
>(
|
|
fd: F,
|
|
mutator: M,
|
|
) -> crate::io::Result<TerminalOptions> {
|
|
let fd = fd.as_raw_fd();
|
|
let old = get_terminal_options(fd)?;
|
|
let new = mutator(old);
|
|
set_terminal_options(fd, new)?;
|
|
Ok(old)
|
|
}
|