use crate::backend::c;
use crate::fd::{AsFd, OwnedFd};
use crate::fs::OFlags;
use crate::{backend, io};
#[cfg(any(apple, linux_like, target_os = "freebsd", target_os = "fuchsia"))]
use {crate::ffi::CString, alloc::vec::Vec};
bitflags::bitflags! {
#[repr(transparent)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub struct OpenptFlags: u32 {
const RDWR = c::O_RDWR as c::c_uint;
#[cfg(not(any(target_os = "espidf", target_os = "l4re", target_os = "redox")))]
const NOCTTY = c::O_NOCTTY as c::c_uint;
#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "netbsd"))]
const CLOEXEC = c::O_CLOEXEC as c::c_uint;
}
}
impl From<OpenptFlags> for OFlags {
#[inline]
fn from(flags: OpenptFlags) -> Self {
Self::from_bits_retain(flags.bits() as _)
}
}
#[inline]
#[doc(alias = "posix_openpt")]
pub fn openpt(flags: OpenptFlags) -> io::Result<OwnedFd> {
#[cfg(linux_kernel)]
{
use crate::fs::{open, Mode};
match open(cstr!("/dev/ptmx"), flags.into(), Mode::empty()) {
Err(io::Errno::NOSPC) => Err(io::Errno::AGAIN),
otherwise => otherwise,
}
}
#[cfg(not(linux_kernel))]
{
backend::pty::syscalls::openpt(flags)
}
}
#[inline]
#[doc(alias = "ptsname_r")]
#[cfg(any(apple, linux_like, target_os = "freebsd", target_os = "fuchsia"))]
pub fn ptsname<Fd: AsFd, B: Into<Vec<u8>>>(fd: Fd, reuse: B) -> io::Result<CString> {
backend::pty::syscalls::ptsname(fd.as_fd(), reuse.into())
}
#[inline]
pub fn unlockpt<Fd: AsFd>(fd: Fd) -> io::Result<()> {
backend::pty::syscalls::unlockpt(fd.as_fd())
}
#[inline]
pub fn grantpt<Fd: AsFd>(fd: Fd) -> io::Result<()> {
#[cfg(not(linux_kernel))]
{
backend::pty::syscalls::grantpt(fd.as_fd())
}
#[cfg(linux_kernel)]
{
let _ = fd;
Ok(())
}
}
#[cfg(target_os = "linux")]
#[inline]
pub fn ioctl_tiocgptpeer<Fd: AsFd>(fd: Fd, flags: OpenptFlags) -> io::Result<OwnedFd> {
backend::pty::syscalls::ioctl_tiocgptpeer(fd.as_fd(), flags)
}