Skip to content

Commit e1c9f2a

Browse files
willshuttleworthsylvestre
authored andcommitted
reworked arg processing. control character mappings are correctly grouped now, ie 'stty erase ^H'
1 parent a7b005c commit e1c9f2a

File tree

1 file changed

+39
-6
lines changed

1 file changed

+39
-6
lines changed

src/uu/stty/src/stty.rs

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@
88
mod flags;
99

1010
use clap::{Arg, ArgAction, ArgMatches, Command};
11-
use nix::libc::{O_NONBLOCK, TIOCGWINSZ, TIOCSWINSZ, c_ushort};
11+
use nix::libc::{c_ushort, O_NONBLOCK, TIOCGWINSZ, TIOCSWINSZ};
1212
use nix::sys::termios::{
13-
ControlFlags, InputFlags, LocalFlags, OutputFlags, SpecialCharacterIndices, Termios,
14-
cfgetospeed, cfsetospeed, tcgetattr, tcsetattr,
13+
cfgetospeed, cfsetospeed, tcgetattr, tcsetattr, ControlFlags, InputFlags, LocalFlags,
14+
OutputFlags, SpecialCharacterIndices, Termios,
1515
};
1616
use nix::{ioctl_read_bad, ioctl_write_ptr_bad};
1717
use std::fs::File;
18-
use std::io::{self, Stdout, stdout};
18+
use std::io::{self, stdout, Stdout};
1919
use std::ops::ControlFlow;
2020
use std::os::fd::{AsFd, BorrowedFd};
2121
use std::os::unix::fs::OpenOptionsExt;
@@ -203,8 +203,27 @@ fn stty(opts: &Options) -> UResult<()> {
203203
let mut termios = tcgetattr(opts.file.as_fd()).expect("Could not get terminal attributes");
204204

205205
if let Some(settings) = &opts.settings {
206-
for setting in settings {
207-
if let ControlFlow::Break(false) = apply_setting(&mut termios, setting) {
206+
let mut settings_iter = settings.into_iter();
207+
while let Some(setting) = settings_iter.next() {
208+
if is_control_char(setting) {
209+
let new_cc = match settings_iter.next() {
210+
Some(cc) => cc,
211+
None => {
212+
return Err(USimpleError::new(
213+
1,
214+
format!("no mapping specified for '{setting}'"),
215+
));
216+
}
217+
};
218+
if let ControlFlow::Break(false) = apply_char_mapping(&mut termios, setting, new_cc)
219+
{
220+
return Err(USimpleError::new(
221+
1,
222+
format!("invalid mapping '{setting}' => '{new_cc}'"),
223+
));
224+
}
225+
}
226+
else if let ControlFlow::Break(false) = apply_setting(&mut termios, setting) {
208227
return Err(USimpleError::new(
209228
1,
210229
format!("invalid argument '{setting}'"),
@@ -274,6 +293,15 @@ fn print_terminal_size(termios: &Termios, opts: &Options) -> nix::Result<()> {
274293
Ok(())
275294
}
276295

296+
fn is_control_char(option: &str) -> bool {
297+
for cc in CONTROL_CHARS {
298+
if option == cc.0 {
299+
return true;
300+
}
301+
}
302+
false
303+
}
304+
277305
fn control_char_to_string(cc: nix::libc::cc_t) -> nix::Result<String> {
278306
if cc == 0 {
279307
return Ok("<undef>".to_string());
@@ -462,6 +490,11 @@ fn apply_baud_rate_flag(termios: &mut Termios, input: &str) -> ControlFlow<bool>
462490
ControlFlow::Continue(())
463491
}
464492

493+
fn apply_char_mapping(termios: &mut Termios, cc: &str, new_cc: &str) -> ControlFlow<bool> {
494+
println!("{cc} {new_cc}");
495+
ControlFlow::Break(true)
496+
}
497+
465498
pub fn uu_app() -> Command {
466499
Command::new(uucore::util_name())
467500
.version(uucore::crate_version!())

0 commit comments

Comments
 (0)