Port shell_modes

The C++ one is still there but it's only used in dead code.
This commit is contained in:
Johannes Altmanninger 2024-01-01 19:02:33 +01:00
parent 6a64ba6638
commit c758765503
6 changed files with 26 additions and 33 deletions

View file

@ -30,7 +30,7 @@ use std::ops::{Deref, DerefMut};
use std::os::unix::prelude::*; use std::os::unix::prelude::*;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicI32, AtomicU32, Ordering}; use std::sync::atomic::{AtomicI32, AtomicU32, Ordering};
use std::sync::{Arc, Mutex, TryLockError}; use std::sync::{Arc, Mutex, MutexGuard, TryLockError};
use std::time; use std::time;
// Highest legal ASCII value. // Highest legal ASCII value.
@ -1011,14 +1011,8 @@ pub fn exit_without_destructors(code: libc::c_int) -> ! {
unsafe { libc::_exit(code) }; unsafe { libc::_exit(code) };
} }
pub fn shell_modes() -> &'static libc::termios { pub fn shell_modes() -> MutexGuard<'static, libc::termios> {
let modes = crate::ffi::shell_modes_ffi() as *const libc::termios; crate::reader::SHELL_MODES.lock().unwrap()
unsafe { &*modes }
}
pub fn shell_modes_mut() -> &'static mut libc::termios {
let modes = crate::ffi::shell_modes_ffi() as *mut libc::termios;
unsafe { &mut *modes }
} }
/// The character to use where the text has been truncated. Is an ellipsis on unicode system and a $ /// The character to use where the text has been truncated. Is an ellipsis on unicode system and a $

View file

@ -46,8 +46,6 @@ include_cpp! {
generate!("flog_setlinebuf_ffi") generate!("flog_setlinebuf_ffi")
generate!("activate_flog_categories_by_pattern") generate!("activate_flog_categories_by_pattern")
generate!("shell_modes_ffi")
generate!("log_extra_to_flog_file") generate!("log_extra_to_flog_file")
generate!("wgettext_ptr") generate!("wgettext_ptr")

View file

@ -44,13 +44,14 @@ fn should_exit(recent_chars: &mut Vec<u8>, c: char) -> bool {
recent_chars.push(c); recent_chars.push(c);
for evt in [VINTR, VEOF] { for evt in [VINTR, VEOF] {
if c == shell_modes().c_cc[evt] { let modes = shell_modes();
if recent_chars.iter().rev().nth(1) == Some(&shell_modes().c_cc[evt]) { if c == modes.c_cc[evt] {
if recent_chars.iter().rev().nth(1) == Some(&modes.c_cc[evt]) {
return true; return true;
} }
eprintf!( eprintf!(
"Press [ctrl-%c] again to exit\n", "Press [ctrl-%c] again to exit\n",
char::from(shell_modes().c_cc[evt] + 0x40) char::from(modes.c_cc[evt] + 0x40)
); );
return false; return false;
} }
@ -286,15 +287,16 @@ fn setup_and_process_keys(continuous_mode: bool, verbose: bool) -> ! {
signal_set_handlers(true); signal_set_handlers(true);
// We need to set the shell-modes for ICRNL, // We need to set the shell-modes for ICRNL,
// in fish-proper this is done once a command is run. // in fish-proper this is done once a command is run.
unsafe { libc::tcsetattr(STDIN_FILENO, TCSANOW, shell_modes()) }; unsafe { libc::tcsetattr(STDIN_FILENO, TCSANOW, &*shell_modes()) };
if continuous_mode { if continuous_mode {
eprintf!("\n"); eprintf!("\n");
eprintf!("To terminate this program type \"exit\" or \"quit\" in this window,\n"); eprintf!("To terminate this program type \"exit\" or \"quit\" in this window,\n");
let modes = shell_modes();
eprintf!( eprintf!(
"or press [ctrl-%c] or [ctrl-%c] twice in a row.\n", "or press [ctrl-%c] or [ctrl-%c] twice in a row.\n",
char::from(shell_modes().c_cc[VINTR] + 0x40), char::from(modes.c_cc[VINTR] + 0x40),
char::from(shell_modes().c_cc[VEOF] + 0x40) char::from(modes.c_cc[VEOF] + 0x40)
); );
eprintf!("\n"); eprintf!("\n");
} }

View file

@ -39,8 +39,8 @@ use crate::color::RgbColor;
use crate::common::{ use crate::common::{
escape, escape_string, exit_without_destructors, fish_reserved_codepoint, get_ellipsis_char, escape, escape_string, exit_without_destructors, fish_reserved_codepoint, get_ellipsis_char,
get_obfuscation_read_char, redirect_tty_output, scoped_push_replacer, scoped_push_replacer_ctx, get_obfuscation_read_char, redirect_tty_output, scoped_push_replacer, scoped_push_replacer_ctx,
shell_modes, shell_modes_mut, str2wcstring, wcs2string, write_loop, EscapeFlags, shell_modes, str2wcstring, wcs2string, write_loop, EscapeFlags, EscapeStringStyle, ScopeGuard,
EscapeStringStyle, ScopeGuard, PROGRAM_NAME, UTF8_BOM_WCHAR, PROGRAM_NAME, UTF8_BOM_WCHAR,
}; };
use crate::compat::MB_CUR_MAX; use crate::compat::MB_CUR_MAX;
use crate::complete::{ use crate::complete::{
@ -126,6 +126,9 @@ enum ExitState {
static EXIT_STATE: AtomicU8 = AtomicU8::new(ExitState::None as u8); static EXIT_STATE: AtomicU8 = AtomicU8::new(ExitState::None as u8);
pub static SHELL_MODES: Lazy<Mutex<libc::termios>> =
Lazy::new(|| Mutex::new(unsafe { std::mem::zeroed() }));
/// Mode on startup, which we restore on exit. /// Mode on startup, which we restore on exit.
static TERMINAL_MODE_ON_STARTUP: Lazy<Mutex<libc::termios>> = static TERMINAL_MODE_ON_STARTUP: Lazy<Mutex<libc::termios>> =
Lazy::new(|| Mutex::new(unsafe { std::mem::zeroed() })); Lazy::new(|| Mutex::new(unsafe { std::mem::zeroed() }));
@ -756,9 +759,9 @@ pub fn reader_init() {
tty_modes_for_external_cmds.c_iflag &= !IXOFF; tty_modes_for_external_cmds.c_iflag &= !IXOFF;
// Set the mode used for the terminal, initialized to the current mode. // Set the mode used for the terminal, initialized to the current mode.
*shell_modes_mut() = *tty_modes_for_external_cmds; *shell_modes() = *tty_modes_for_external_cmds;
term_fix_modes(shell_modes_mut()); term_fix_modes(&mut shell_modes());
drop(terminal_mode_on_startup); drop(terminal_mode_on_startup);
drop(tty_modes_for_external_cmds); drop(tty_modes_for_external_cmds);
@ -1695,7 +1698,7 @@ impl ReaderData {
} }
// Set the new modes. // Set the new modes.
if unsafe { libc::tcsetattr(zelf.conf.inputfd, TCSANOW, shell_modes()) } == -1 { if unsafe { libc::tcsetattr(zelf.conf.inputfd, TCSANOW, &*shell_modes()) } == -1 {
let err = errno().0; let err = errno().0;
if err == EIO { if err == EIO {
redirect_tty_output(); redirect_tty_output();
@ -1926,7 +1929,7 @@ impl ReaderData {
// tty alone, run the commands in shell mode, and then restore shell modes. // tty alone, run the commands in shell mode, and then restore shell modes.
let mut res; let mut res;
loop { loop {
res = unsafe { libc::tcsetattr(STDIN_FILENO, TCSANOW, shell_modes_mut()) }; res = unsafe { libc::tcsetattr(STDIN_FILENO, TCSANOW, &*shell_modes()) };
if res >= 0 || errno().0 != EINTR { if res >= 0 || errno().0 != EINTR {
break; break;
} }
@ -3323,21 +3326,21 @@ pub fn term_copy_modes() {
// Copy flow control settings to shell modes. // Copy flow control settings to shell modes.
if (tty_modes_for_external_cmds.c_iflag & IXON) != 0 { if (tty_modes_for_external_cmds.c_iflag & IXON) != 0 {
shell_modes_mut().c_iflag |= IXON; shell_modes().c_iflag |= IXON;
} else { } else {
shell_modes_mut().c_iflag &= !IXON; shell_modes().c_iflag &= !IXON;
} }
if (tty_modes_for_external_cmds.c_iflag & IXOFF) != 0 { if (tty_modes_for_external_cmds.c_iflag & IXOFF) != 0 {
shell_modes_mut().c_iflag |= IXOFF; shell_modes().c_iflag |= IXOFF;
} else { } else {
shell_modes_mut().c_iflag &= !IXOFF; shell_modes().c_iflag &= !IXOFF;
} }
} }
/// Grab control of terminal. /// Grab control of terminal.
fn term_steal() { fn term_steal() {
term_copy_modes(); term_copy_modes();
while unsafe { libc::tcsetattr(STDIN_FILENO, TCSANOW, shell_modes()) } == -1 { while unsafe { libc::tcsetattr(STDIN_FILENO, TCSANOW, &*shell_modes()) } == -1 {
if errno().0 == EIO { if errno().0 == EIO {
redirect_tty_output(); redirect_tty_output();
} }
@ -3484,7 +3487,7 @@ fn reader_interactive_init(parser: &Parser) {
} }
// Configure terminal attributes // Configure terminal attributes
if unsafe { libc::tcsetattr(STDIN_FILENO, TCSANOW, shell_modes_mut()) } == -1 { if unsafe { libc::tcsetattr(STDIN_FILENO, TCSANOW, &*shell_modes()) } == -1 {
if errno().0 == EIO { if errno().0 == EIO {
redirect_tty_output(); redirect_tty_output();
} }

View file

@ -58,8 +58,6 @@
struct termios shell_modes; struct termios shell_modes;
struct termios *shell_modes_ffi() { return &shell_modes; }
const wcstring g_empty_string{}; const wcstring g_empty_string{};
const std::vector<wcstring> g_empty_string_list{}; const std::vector<wcstring> g_empty_string_list{};

View file

@ -652,6 +652,4 @@ __attribute__((always_inline)) bool inline iswdigit(const wchar_t c) {
#include "common.rs.h" #include "common.rs.h"
#endif #endif
struct termios *shell_modes_ffi();
#endif // FISH_COMMON_H #endif // FISH_COMMON_H