mirror of
https://git.proxmox.com/git/proxmox
synced 2025-07-09 19:57:39 +00:00
sys: deprecate Fd, add its methods as module functions
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
85c260f6b5
commit
8420c266af
@ -1,3 +1,5 @@
|
|||||||
|
#![allow(deprecated)]
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::os::unix::io::{AsRawFd, RawFd};
|
use std::os::unix::io::{AsRawFd, RawFd};
|
||||||
|
|
||||||
|
@ -9,8 +9,10 @@ use nix::NixPath;
|
|||||||
/// `RawFd` is required without the corresponding handler object (such as when only the file
|
/// `RawFd` is required without the corresponding handler object (such as when only the file
|
||||||
/// descriptor number is required in a closure which may be dropped instead of being executed).
|
/// descriptor number is required in a closure which may be dropped instead of being executed).
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[deprecated(note = "use std::os::unix::io::OwnedFd instead")]
|
||||||
pub struct Fd(pub RawFd);
|
pub struct Fd(pub RawFd);
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
impl Drop for Fd {
|
impl Drop for Fd {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
// `>= 0` instead of `!= -1` to also handle things like AT_FDCWD
|
// `>= 0` instead of `!= -1` to also handle things like AT_FDCWD
|
||||||
@ -22,11 +24,14 @@ impl Drop for Fd {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
impl Fd {
|
impl Fd {
|
||||||
|
#[deprecated(note = "use proxmox_sys::fd::cwd instead")]
|
||||||
pub const fn cwd() -> Self {
|
pub const fn cwd() -> Self {
|
||||||
Self(libc::AT_FDCWD)
|
Self(libc::AT_FDCWD)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deprecated(note = "use proxmox_sys::fd::open instead")]
|
||||||
pub fn open<P>(path: &P, oflag: OFlag, mode: Mode) -> Result<Self, nix::Error>
|
pub fn open<P>(path: &P, oflag: OFlag, mode: Mode) -> Result<Self, nix::Error>
|
||||||
where
|
where
|
||||||
P: ?Sized + NixPath,
|
P: ?Sized + NixPath,
|
||||||
@ -34,6 +39,7 @@ impl Fd {
|
|||||||
nix::fcntl::open(path, oflag, mode).map(Self)
|
nix::fcntl::open(path, oflag, mode).map(Self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deprecated(note = "use proxmox_sys::fd::openat instead")]
|
||||||
pub fn openat<D, P>(dirfd: &D, path: &P, oflag: OFlag, mode: Mode) -> Result<Self, nix::Error>
|
pub fn openat<D, P>(dirfd: &D, path: &P, oflag: OFlag, mode: Mode) -> Result<Self, nix::Error>
|
||||||
where
|
where
|
||||||
D: AsRawFd,
|
D: AsRawFd,
|
||||||
@ -48,18 +54,21 @@ impl Fd {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
impl FromRawFd for Fd {
|
impl FromRawFd for Fd {
|
||||||
unsafe fn from_raw_fd(fd: RawFd) -> Self {
|
unsafe fn from_raw_fd(fd: RawFd) -> Self {
|
||||||
Self(fd)
|
Self(fd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
impl AsRawFd for Fd {
|
impl AsRawFd for Fd {
|
||||||
fn as_raw_fd(&self) -> RawFd {
|
fn as_raw_fd(&self) -> RawFd {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
impl IntoRawFd for Fd {
|
impl IntoRawFd for Fd {
|
||||||
fn into_raw_fd(mut self) -> RawFd {
|
fn into_raw_fd(mut self) -> RawFd {
|
||||||
let fd = self.0;
|
let fd = self.0;
|
||||||
@ -68,18 +77,21 @@ impl IntoRawFd for Fd {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
impl AsRef<FdRef> for Fd {
|
impl AsRef<FdRef> for Fd {
|
||||||
fn as_ref(&self) -> &FdRef {
|
fn as_ref(&self) -> &FdRef {
|
||||||
self.as_fd_ref()
|
self.as_fd_ref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
impl Borrow<FdRef> for Fd {
|
impl Borrow<FdRef> for Fd {
|
||||||
fn borrow(&self) -> &FdRef {
|
fn borrow(&self) -> &FdRef {
|
||||||
self.as_fd_ref()
|
self.as_fd_ref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
impl std::ops::Deref for Fd {
|
impl std::ops::Deref for Fd {
|
||||||
type Target = FdRef;
|
type Target = FdRef;
|
||||||
|
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
//! Raw file descriptor related structures.
|
//! Raw file descriptor related structures.
|
||||||
|
|
||||||
|
use std::os::unix::io::AsRawFd;
|
||||||
|
|
||||||
|
use nix::fcntl::OFlag;
|
||||||
|
use nix::sys::stat::Mode;
|
||||||
|
use nix::NixPath;
|
||||||
|
|
||||||
mod fd_impl;
|
mod fd_impl;
|
||||||
pub use fd_impl::*;
|
pub use fd_impl::*;
|
||||||
|
|
||||||
@ -9,14 +15,39 @@ pub use raw_fd_num::*;
|
|||||||
mod borrowed_fd;
|
mod borrowed_fd;
|
||||||
pub use borrowed_fd::*;
|
pub use borrowed_fd::*;
|
||||||
|
|
||||||
use std::os::unix::io::RawFd;
|
use std::os::unix::io::{FromRawFd, OwnedFd, RawFd};
|
||||||
|
|
||||||
use nix::fcntl::{fcntl, FdFlag, F_GETFD, F_SETFD};
|
use nix::fcntl::{fcntl, FdFlag, F_GETFD, F_SETFD};
|
||||||
|
|
||||||
/// Change the `O_CLOEXEC` flag of an existing file descriptor.
|
/// Change the `O_CLOEXEC` flag of an existing file descriptor.
|
||||||
pub fn fd_change_cloexec(fd: RawFd, on: bool) -> Result<(), anyhow::Error> {
|
pub fn fd_change_cloexec(fd: RawFd, on: bool) -> Result<(), anyhow::Error> {
|
||||||
|
change_cloexec(fd, on)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Change the `O_CLOEXEC` flag of an existing file descriptor.
|
||||||
|
pub fn change_cloexec(fd: RawFd, on: bool) -> Result<(), anyhow::Error> {
|
||||||
let mut flags = unsafe { FdFlag::from_bits_unchecked(fcntl(fd, F_GETFD)?) };
|
let mut flags = unsafe { FdFlag::from_bits_unchecked(fcntl(fd, F_GETFD)?) };
|
||||||
flags.set(FdFlag::FD_CLOEXEC, on);
|
flags.set(FdFlag::FD_CLOEXEC, on);
|
||||||
fcntl(fd, F_SETFD(flags))?;
|
fcntl(fd, F_SETFD(flags))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn cwd() -> OwnedFd {
|
||||||
|
unsafe { OwnedFd::from_raw_fd(libc::AT_FDCWD) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn open<P>(path: &P, oflag: OFlag, mode: Mode) -> Result<OwnedFd, nix::Error>
|
||||||
|
where
|
||||||
|
P: ?Sized + NixPath,
|
||||||
|
{
|
||||||
|
nix::fcntl::open(path, oflag, mode).map(|fd| unsafe { OwnedFd::from_raw_fd(fd) })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn openat<D, P>(dirfd: &D, path: &P, oflag: OFlag, mode: Mode) -> Result<OwnedFd, nix::Error>
|
||||||
|
where
|
||||||
|
D: AsRawFd,
|
||||||
|
P: ?Sized + NixPath,
|
||||||
|
{
|
||||||
|
nix::fcntl::openat(dirfd.as_raw_fd(), path, oflag, mode)
|
||||||
|
.map(|fd| unsafe { OwnedFd::from_raw_fd(fd) })
|
||||||
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::{AsRawFd, OwnedFd};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use anyhow::{bail, Error};
|
use anyhow::{bail, Error};
|
||||||
@ -8,7 +8,6 @@ use nix::fcntl::OFlag;
|
|||||||
use nix::sys::stat;
|
use nix::sys::stat;
|
||||||
use nix::unistd;
|
use nix::unistd;
|
||||||
|
|
||||||
use crate::fd::Fd;
|
|
||||||
use crate::fs::{fchown, CreateOptions};
|
use crate::fs::{fchown, CreateOptions};
|
||||||
|
|
||||||
/// Creates directory at the provided path with specified ownership.
|
/// Creates directory at the provided path with specified ownership.
|
||||||
@ -66,11 +65,11 @@ fn create_path_do(
|
|||||||
use std::path::Component;
|
use std::path::Component;
|
||||||
|
|
||||||
let mut iter = path.components().peekable();
|
let mut iter = path.components().peekable();
|
||||||
let at: Fd = match iter.peek() {
|
let at: OwnedFd = match iter.peek() {
|
||||||
Some(Component::Prefix(_)) => bail!("illegal prefix path component encountered"),
|
Some(Component::Prefix(_)) => bail!("illegal prefix path component encountered"),
|
||||||
Some(Component::RootDir) => {
|
Some(Component::RootDir) => {
|
||||||
let _ = iter.next();
|
let _ = iter.next();
|
||||||
Fd::open(
|
crate::fd::open(
|
||||||
unsafe { CStr::from_bytes_with_nul_unchecked(b"/\0") },
|
unsafe { CStr::from_bytes_with_nul_unchecked(b"/\0") },
|
||||||
OFlag::O_DIRECTORY,
|
OFlag::O_DIRECTORY,
|
||||||
stat::Mode::empty(),
|
stat::Mode::empty(),
|
||||||
@ -78,11 +77,11 @@ fn create_path_do(
|
|||||||
}
|
}
|
||||||
Some(Component::CurDir) => {
|
Some(Component::CurDir) => {
|
||||||
let _ = iter.next();
|
let _ = iter.next();
|
||||||
Fd::cwd()
|
crate::fd::cwd()
|
||||||
}
|
}
|
||||||
Some(Component::ParentDir) => {
|
Some(Component::ParentDir) => {
|
||||||
let _ = iter.next();
|
let _ = iter.next();
|
||||||
Fd::open(
|
crate::fd::open(
|
||||||
unsafe { CStr::from_bytes_with_nul_unchecked(b"..\0") },
|
unsafe { CStr::from_bytes_with_nul_unchecked(b"..\0") },
|
||||||
OFlag::O_DIRECTORY,
|
OFlag::O_DIRECTORY,
|
||||||
stat::Mode::empty(),
|
stat::Mode::empty(),
|
||||||
@ -90,7 +89,7 @@ fn create_path_do(
|
|||||||
}
|
}
|
||||||
Some(Component::Normal(_)) => {
|
Some(Component::Normal(_)) => {
|
||||||
// simply do not advance the iterator, heavy lifting happens in create_path_at_do()
|
// simply do not advance the iterator, heavy lifting happens in create_path_at_do()
|
||||||
Fd::cwd()
|
crate::fd::cwd()
|
||||||
}
|
}
|
||||||
None => bail!("create_path on empty path?"),
|
None => bail!("create_path on empty path?"),
|
||||||
};
|
};
|
||||||
@ -99,7 +98,7 @@ fn create_path_do(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn create_path_at_do(
|
fn create_path_at_do(
|
||||||
mut at: Fd,
|
mut at: OwnedFd,
|
||||||
mut iter: std::iter::Peekable<std::path::Components>,
|
mut iter: std::iter::Peekable<std::path::Components>,
|
||||||
intermediate_opts: Option<CreateOptions>,
|
intermediate_opts: Option<CreateOptions>,
|
||||||
final_opts: Option<CreateOptions>,
|
final_opts: Option<CreateOptions>,
|
||||||
@ -112,7 +111,7 @@ fn create_path_at_do(
|
|||||||
None => return Ok(created),
|
None => return Ok(created),
|
||||||
|
|
||||||
Some(Component::ParentDir) => {
|
Some(Component::ParentDir) => {
|
||||||
at = Fd::openat(
|
at = crate::fd::openat(
|
||||||
&at,
|
&at,
|
||||||
unsafe { CStr::from_bytes_with_nul_unchecked(b"..\0") },
|
unsafe { CStr::from_bytes_with_nul_unchecked(b"..\0") },
|
||||||
OFlag::O_DIRECTORY,
|
OFlag::O_DIRECTORY,
|
||||||
@ -138,7 +137,7 @@ fn create_path_at_do(
|
|||||||
Err(e) => return Err(e.into()),
|
Err(e) => return Err(e.into()),
|
||||||
Ok(_) => true,
|
Ok(_) => true,
|
||||||
};
|
};
|
||||||
at = Fd::openat(&at, path, OFlag::O_DIRECTORY, stat::Mode::empty())?;
|
at = crate::fd::openat(&at, path, OFlag::O_DIRECTORY, stat::Mode::empty())?;
|
||||||
|
|
||||||
if let (true, Some(opts)) = (created, opts) {
|
if let (true, Some(opts)) = (created, opts) {
|
||||||
if opts.owner.is_some() || opts.group.is_some() {
|
if opts.owner.is_some() || opts.group.is_some() {
|
||||||
|
@ -32,6 +32,7 @@ macro_rules! identity {
|
|||||||
#[cfg(feature = "sortable-macro")]
|
#[cfg(feature = "sortable-macro")]
|
||||||
pub use proxmox_sortable_macro::sortable;
|
pub use proxmox_sortable_macro::sortable;
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
use fd::Fd;
|
use fd::Fd;
|
||||||
|
|
||||||
/// Returns the hosts node name (UTS node name)
|
/// Returns the hosts node name (UTS node name)
|
||||||
@ -57,6 +58,7 @@ pub fn nodename() -> &'static str {
|
|||||||
|
|
||||||
/// Safe wrapper for `nix::unistd::pipe2` defaulting to `O_CLOEXEC`
|
/// Safe wrapper for `nix::unistd::pipe2` defaulting to `O_CLOEXEC`
|
||||||
/// and guarding the file descriptors.
|
/// and guarding the file descriptors.
|
||||||
|
#[allow(deprecated)]
|
||||||
pub fn pipe() -> Result<(Fd, Fd), nix::Error> {
|
pub fn pipe() -> Result<(Fd, Fd), nix::Error> {
|
||||||
let (pin, pout) = nix::unistd::pipe2(nix::fcntl::OFlag::O_CLOEXEC)?;
|
let (pin, pout) = nix::unistd::pipe2(nix::fcntl::OFlag::O_CLOEXEC)?;
|
||||||
Ok((Fd(pin), Fd(pout)))
|
Ok((Fd(pin), Fd(pout)))
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
|
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
|
||||||
|
|
||||||
use nix::fcntl::OFlag;
|
use nix::fcntl::OFlag;
|
||||||
use nix::sys::signal::Signal;
|
use nix::sys::signal::Signal;
|
||||||
@ -14,7 +14,6 @@ use nix::NixPath;
|
|||||||
use proxmox_lang::{c_str, error::io_err_other};
|
use proxmox_lang::{c_str, error::io_err_other};
|
||||||
|
|
||||||
use crate::error::SysResult;
|
use crate::error::SysResult;
|
||||||
use crate::fd::Fd;
|
|
||||||
use crate::linux::procfs::{MountInfo, PidStat};
|
use crate::linux::procfs::{MountInfo, PidStat};
|
||||||
use crate::{c_result, c_try};
|
use crate::{c_result, c_try};
|
||||||
|
|
||||||
@ -41,7 +40,7 @@ unsafe fn pidfd_send_signal(
|
|||||||
|
|
||||||
/// File descriptor refernce to a process.
|
/// File descriptor refernce to a process.
|
||||||
pub struct PidFd {
|
pub struct PidFd {
|
||||||
fd: Fd,
|
fd: OwnedFd,
|
||||||
pid: Pid,
|
pid: Pid,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +52,7 @@ impl PidFd {
|
|||||||
|
|
||||||
/// Open a pidfd for the given process id.
|
/// Open a pidfd for the given process id.
|
||||||
pub fn open(pid: Pid) -> io::Result<Self> {
|
pub fn open(pid: Pid) -> io::Result<Self> {
|
||||||
let fd = unsafe { Fd::from_raw_fd(c_try!(pidfd_open(pid.as_raw(), 0)) as RawFd) };
|
let fd = unsafe { OwnedFd::from_raw_fd(c_try!(pidfd_open(pid.as_raw(), 0)) as RawFd) };
|
||||||
Ok(Self { fd, pid })
|
Ok(Self { fd, pid })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +84,7 @@ impl PidFd {
|
|||||||
/// Open a procfs file from. This is equivalent to opening `/proc/<pid>/<file>` using this
|
/// Open a procfs file from. This is equivalent to opening `/proc/<pid>/<file>` using this
|
||||||
/// process actual pid. This also works if the file descriptor has been sent over
|
/// process actual pid. This also works if the file descriptor has been sent over
|
||||||
pub fn open_file<P: ?Sized + NixPath>(&self, path: &P) -> io::Result<File> {
|
pub fn open_file<P: ?Sized + NixPath>(&self, path: &P) -> io::Result<File> {
|
||||||
Fd::openat(
|
crate::fd::openat(
|
||||||
self,
|
self,
|
||||||
path,
|
path,
|
||||||
OFlag::O_RDONLY | OFlag::O_CLOEXEC,
|
OFlag::O_RDONLY | OFlag::O_CLOEXEC,
|
||||||
@ -124,7 +123,7 @@ impl PidFd {
|
|||||||
/// This will attempt to read the pid number via the file descriptor.
|
/// This will attempt to read the pid number via the file descriptor.
|
||||||
pub fn try_from_raw_fd(fd: RawFd) -> io::Result<Self> {
|
pub fn try_from_raw_fd(fd: RawFd) -> io::Result<Self> {
|
||||||
let mut this = Self {
|
let mut this = Self {
|
||||||
fd: unsafe { Fd::from_raw_fd(fd) },
|
fd: unsafe { OwnedFd::from_raw_fd(fd) },
|
||||||
pid: Pid::from_raw(1),
|
pid: Pid::from_raw(1),
|
||||||
};
|
};
|
||||||
// Simple check first: is it a valid pid file descriptor:
|
// Simple check first: is it a valid pid file descriptor:
|
||||||
|
@ -10,8 +10,6 @@ use nix::sys::stat::Mode;
|
|||||||
use nix::unistd::{dup2, setsid};
|
use nix::unistd::{dup2, setsid};
|
||||||
use nix::{ioctl_write_int_bad, ioctl_write_ptr_bad, Result};
|
use nix::{ioctl_write_int_bad, ioctl_write_ptr_bad, Result};
|
||||||
|
|
||||||
use crate::fd::Fd;
|
|
||||||
|
|
||||||
ioctl_write_int_bad!(set_controlling_tty, libc::TIOCSCTTY);
|
ioctl_write_int_bad!(set_controlling_tty, libc::TIOCSCTTY);
|
||||||
ioctl_write_ptr_bad!(set_size, libc::TIOCSWINSZ, nix::pty::Winsize);
|
ioctl_write_ptr_bad!(set_size, libc::TIOCSWINSZ, nix::pty::Winsize);
|
||||||
|
|
||||||
@ -64,7 +62,7 @@ pub fn make_controlling_terminal(terminal: &str) -> Result<()> {
|
|||||||
| Mode::S_IWGRP
|
| Mode::S_IWGRP
|
||||||
| Mode::S_IROTH
|
| Mode::S_IROTH
|
||||||
| Mode::S_IWOTH; // 0666
|
| Mode::S_IWOTH; // 0666
|
||||||
let secondary_fd = Fd::open(terminal, OFlag::O_RDWR | OFlag::O_NOCTTY, mode)?;
|
let secondary_fd = crate::fd::open(terminal, OFlag::O_RDWR | OFlag::O_NOCTTY, mode)?;
|
||||||
let s_raw_fd = secondary_fd.as_raw_fd();
|
let s_raw_fd = secondary_fd.as_raw_fd();
|
||||||
unsafe { set_controlling_tty(s_raw_fd, 0) }?;
|
unsafe { set_controlling_tty(s_raw_fd, 0) }?;
|
||||||
dup2(s_raw_fd, 0)?;
|
dup2(s_raw_fd, 0)?;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::io::{self, Read, Write};
|
use std::io::{self, Read, Write};
|
||||||
use std::mem::MaybeUninit;
|
use std::mem::MaybeUninit;
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::{AsRawFd, OwnedFd};
|
||||||
|
|
||||||
use anyhow::{bail, format_err, Error};
|
use anyhow::{bail, format_err, Error};
|
||||||
use nix::fcntl::OFlag;
|
use nix::fcntl::OFlag;
|
||||||
@ -9,7 +9,6 @@ use nix::sys::stat::Mode;
|
|||||||
use proxmox_lang::try_block;
|
use proxmox_lang::try_block;
|
||||||
|
|
||||||
use crate::c_try;
|
use crate::c_try;
|
||||||
use crate::fd::Fd;
|
|
||||||
|
|
||||||
/// Get the current size of the terminal (for stdout).
|
/// Get the current size of the terminal (for stdout).
|
||||||
/// # Safety
|
/// # Safety
|
||||||
@ -44,7 +43,7 @@ pub fn stdin_isatty() -> bool {
|
|||||||
|
|
||||||
pub enum TtyOutput {
|
pub enum TtyOutput {
|
||||||
Stdout(std::io::Stdout),
|
Stdout(std::io::Stdout),
|
||||||
DevTty(Fd),
|
DevTty(OwnedFd),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Write for TtyOutput {
|
impl Write for TtyOutput {
|
||||||
@ -79,7 +78,7 @@ impl TtyOutput {
|
|||||||
if unsafe { libc::isatty(stdout.as_raw_fd()) } == 1 {
|
if unsafe { libc::isatty(stdout.as_raw_fd()) } == 1 {
|
||||||
Ok(Some(TtyOutput::Stdout(stdout)))
|
Ok(Some(TtyOutput::Stdout(stdout)))
|
||||||
} else {
|
} else {
|
||||||
match Fd::open(
|
match crate::fd::open(
|
||||||
"/dev/tty",
|
"/dev/tty",
|
||||||
OFlag::O_WRONLY | OFlag::O_CLOEXEC | OFlag::O_NOCTTY,
|
OFlag::O_WRONLY | OFlag::O_CLOEXEC | OFlag::O_NOCTTY,
|
||||||
Mode::empty(),
|
Mode::empty(),
|
||||||
|
Loading…
Reference in New Issue
Block a user