mirror of
https://github.com/fish-shell/fish-shell.git
synced 2025-02-22 04:51:54 +08:00
Eliminate fish_key_reader signal handlers
They call wgettext, wfprintf, etc. and are so wildly unsafe.
This commit is contained in:
parent
6cccfa7cf4
commit
89644911a1
@ -43,7 +43,6 @@ static const wchar_t *ctrl_symbolic_names[] = {
|
||||
L"\\b", L"\\t", L"\\n", L"\\v", L"\\f", L"\\r", nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, L"\\e", nullptr, nullptr, nullptr, nullptr};
|
||||
static bool keep_running = true;
|
||||
|
||||
/// Return true if the recent sequence of characters indicates the user wants to exit the program.
|
||||
static bool should_exit(wchar_t wc) {
|
||||
@ -205,7 +204,7 @@ static void process_input(bool continuous_mode) {
|
||||
std::vector<wchar_t> bind_chars;
|
||||
|
||||
std::fwprintf(stderr, L"Press a key\n\n");
|
||||
while (keep_running) {
|
||||
for (;;) {
|
||||
char_event_t evt{0};
|
||||
if (reader_test_and_clear_interrupted()) {
|
||||
evt = char_event_t{shell_modes.c_cc[VINTR]};
|
||||
@ -242,56 +241,19 @@ static void process_input(bool continuous_mode) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Make sure we cleanup before exiting if we receive a signal that should cause us to exit.
|
||||
/// Otherwise just report receipt of the signal.
|
||||
static struct sigaction old_sigactions[32];
|
||||
static void signal_handler(int signo, siginfo_t *siginfo, void *siginfo_arg) {
|
||||
std::fwprintf(stdout, _(L"signal #%d (%ls) received\n"), signo, sig2wcs(signo));
|
||||
if (signo == SIGHUP || signo == SIGTERM || signo == SIGABRT || signo == SIGSEGV) {
|
||||
keep_running = false;
|
||||
}
|
||||
|
||||
if (old_sigactions[signo].sa_handler != SIG_IGN &&
|
||||
old_sigactions[signo].sa_handler != SIG_DFL) {
|
||||
int needs_siginfo = old_sigactions[signo].sa_flags & SA_SIGINFO;
|
||||
if (needs_siginfo) {
|
||||
old_sigactions[signo].sa_sigaction(signo, siginfo, siginfo_arg);
|
||||
} else {
|
||||
old_sigactions[signo].sa_handler(signo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Install a handler for every signal. This allows us to restore the tty modes so the terminal is
|
||||
/// still usable when we die. If the signal already has a handler arrange to invoke it from within
|
||||
/// our handler.
|
||||
static void install_our_signal_handlers() {
|
||||
struct sigaction new_sa, old_sa;
|
||||
sigemptyset(&new_sa.sa_mask);
|
||||
new_sa.sa_flags = SA_SIGINFO;
|
||||
new_sa.sa_sigaction = signal_handler;
|
||||
|
||||
for (int signo = 1; signo < 32; signo++) {
|
||||
if (sigaction(signo, &new_sa, &old_sa) != -1) {
|
||||
std::memcpy(&old_sigactions[signo], &old_sa, sizeof(old_sa));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Setup our environment (e.g., tty modes), process key strokes, then reset the environment.
|
||||
static void setup_and_process_keys(bool continuous_mode) {
|
||||
set_interactive_session(
|
||||
session_interactivity_t::implied); // by definition this program is interactive
|
||||
set_interactive_session(session_interactivity_t::implied);
|
||||
set_main_thread();
|
||||
setup_fork_guards();
|
||||
env_init();
|
||||
reader_init();
|
||||
parser_t &parser = parser_t::principal_parser();
|
||||
scoped_push<bool> interactive{&parser.libdata().is_interactive, true};
|
||||
signal_set_handlers(true);
|
||||
// We need to set the shell-modes for ICRNL,
|
||||
// in fish-proper this is done once a command is run.
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &shell_modes);
|
||||
install_our_signal_handlers();
|
||||
|
||||
if (continuous_mode) {
|
||||
std::fwprintf(stderr, L"\n");
|
||||
@ -304,7 +266,7 @@ static void setup_and_process_keys(bool continuous_mode) {
|
||||
|
||||
process_input(continuous_mode);
|
||||
restore_term_mode();
|
||||
restore_term_foreground_process_group();
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
static bool parse_debug_level_flag() {
|
||||
@ -400,5 +362,6 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
setup_and_process_keys(continuous_mode);
|
||||
return 0;
|
||||
exit_without_destructors(0);
|
||||
return EXIT_FAILURE; // above should exit
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user