1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-08-01 13:37:48 +00:00

stty: adapt to API change in nix 0.27.x

tcgetattr(fd: RawFd) changed to tcgetattr<Fd: AsFd>(fd: Fd), with RawFd
not implementing AsFd. A similar change was applied to tcsetattr.
This commit is contained in:
Daniel Hofstetter 2023-09-07 15:07:20 +02:00
parent 2c96a0d741
commit 36d5013fac

View file

@ -14,10 +14,12 @@ use nix::sys::termios::{
OutputFlags, SpecialCharacterIndices, Termios, OutputFlags, SpecialCharacterIndices, Termios,
}; };
use nix::{ioctl_read_bad, ioctl_write_ptr_bad}; use nix::{ioctl_read_bad, ioctl_write_ptr_bad};
use std::io::{self, stdout}; use std::fs::File;
use std::io::{self, stdout, Stdout};
use std::ops::ControlFlow; use std::ops::ControlFlow;
use std::os::fd::{AsFd, BorrowedFd};
use std::os::unix::fs::OpenOptionsExt; use std::os::unix::fs::OpenOptionsExt;
use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd}; use std::os::unix::io::{AsRawFd, RawFd};
use uucore::error::{UResult, USimpleError}; use uucore::error::{UResult, USimpleError};
use uucore::{format_usage, help_about, help_usage}; use uucore::{format_usage, help_about, help_usage};
@ -91,10 +93,33 @@ mod options {
struct Options<'a> { struct Options<'a> {
all: bool, all: bool,
save: bool, save: bool,
file: RawFd, file: Device,
settings: Option<Vec<&'a str>>, settings: Option<Vec<&'a str>>,
} }
enum Device {
File(File),
Stdout(Stdout),
}
impl AsFd for Device {
fn as_fd(&self) -> BorrowedFd<'_> {
match self {
Self::File(f) => f.as_fd(),
Self::Stdout(stdout) => stdout.as_fd(),
}
}
}
impl AsRawFd for Device {
fn as_raw_fd(&self) -> RawFd {
match self {
Self::File(f) => f.as_raw_fd(),
Self::Stdout(stdout) => stdout.as_raw_fd(),
}
}
}
impl<'a> Options<'a> { impl<'a> Options<'a> {
fn from(matches: &'a ArgMatches) -> io::Result<Self> { fn from(matches: &'a ArgMatches) -> io::Result<Self> {
Ok(Self { Ok(Self {
@ -110,12 +135,13 @@ impl<'a> Options<'a> {
// will clean up the FD for us on exit, so it doesn't // will clean up the FD for us on exit, so it doesn't
// matter. The alternative would be to have an enum of // matter. The alternative would be to have an enum of
// BorrowedFd/OwnedFd to handle both cases. // BorrowedFd/OwnedFd to handle both cases.
Some(f) => std::fs::OpenOptions::new() Some(f) => Device::File(
.read(true) std::fs::OpenOptions::new()
.custom_flags(O_NONBLOCK) .read(true)
.open(f)? .custom_flags(O_NONBLOCK)
.into_raw_fd(), .open(f)?,
None => stdout().as_raw_fd(), ),
None => Device::Stdout(stdout()),
}, },
settings: matches settings: matches
.get_many::<String>(options::SETTINGS) .get_many::<String>(options::SETTINGS)
@ -175,7 +201,7 @@ fn stty(opts: &Options) -> UResult<()> {
} }
// TODO: Figure out the right error message for when tcgetattr fails // TODO: Figure out the right error message for when tcgetattr fails
let mut termios = tcgetattr(opts.file).expect("Could not get terminal attributes"); let mut termios = tcgetattr(opts.file.as_fd()).expect("Could not get terminal attributes");
if let Some(settings) = &opts.settings { if let Some(settings) = &opts.settings {
for setting in settings { for setting in settings {
@ -187,8 +213,12 @@ fn stty(opts: &Options) -> UResult<()> {
} }
} }
tcsetattr(opts.file, nix::sys::termios::SetArg::TCSANOW, &termios) tcsetattr(
.expect("Could not write terminal attributes"); opts.file.as_fd(),
nix::sys::termios::SetArg::TCSANOW,
&termios,
)
.expect("Could not write terminal attributes");
} else { } else {
print_settings(&termios, opts).expect("TODO: make proper error here from nix error"); print_settings(&termios, opts).expect("TODO: make proper error here from nix error");
} }
@ -228,7 +258,7 @@ fn print_terminal_size(termios: &Termios, opts: &Options) -> nix::Result<()> {
if opts.all { if opts.all {
let mut size = TermSize::default(); let mut size = TermSize::default();
unsafe { tiocgwinsz(opts.file, &mut size as *mut _)? }; unsafe { tiocgwinsz(opts.file.as_raw_fd(), &mut size as *mut _)? };
print!("rows {}; columns {}; ", size.rows, size.columns); print!("rows {}; columns {}; ", size.rows, size.columns);
} }