From d01db38d51ac5705e9416ab6f6e81e6a42d2dd26 Mon Sep 17 00:00:00 2001 From: Tim Stack Date: Mon, 22 Aug 2022 13:15:31 -0700 Subject: [PATCH] [init] fix handling of unknown TERM --- src/lnav.cc | 32 ++++++++++++++++++++++---------- src/view_curses.cc | 28 ++++++++++++++++++++++++++++ src/view_curses.hh | 32 ++++++++++++++++++++++++++++---- test/drive_mvwattrline.cc | 2 +- test/drive_readline_curses.cc | 3 +-- test/drive_vt52_curses.cc | 3 +-- 6 files changed, 81 insertions(+), 19 deletions(-) diff --git a/src/lnav.cc b/src/lnav.cc index 11879650..83045cb9 100644 --- a/src/lnav.cc +++ b/src/lnav.cc @@ -1006,13 +1006,6 @@ looper() static auto* filter_source = injector::get(); try { - auto_fd errpipe[2]; - auto_fd::pipe(errpipe); - - dup2(errpipe[1], STDERR_FILENO); - errpipe[1].reset(); - log_pipe_err(errpipe[0]); - auto* sql_cmd_map = injector::get(); auto& ec = lnav_data.ld_exec_context; @@ -1091,7 +1084,26 @@ looper() (void) signal(SIGWINCH, sigwinch); (void) signal(SIGCHLD, sigchld); - screen_curses sc; + auto create_screen_res = screen_curses::create(); + + if (create_screen_res.isErr()) { + log_error("create screen failed with: %s", + create_screen_res.unwrapErr().c_str()); + lnav::console::print( + stderr, + lnav::console::user_message::error("unable to open TUI") + .with_reason(create_screen_res.unwrapErr())); + return; + } + + auto sc = create_screen_res.unwrap(); + + auto_fd errpipe[2]; + auto_fd::pipe(errpipe); + + dup2(errpipe[1], STDERR_FILENO); + errpipe[1].reset(); + log_pipe_err(errpipe[0]); lnav_behavior lb; ui_periodic_timer::singleton(); @@ -1264,8 +1276,8 @@ looper() lnav_data.ld_status[LNS_TOP].set_enabled(false); lnav_data.ld_status[LNS_TOP].set_data_source(&lnav_data.ld_top_source); lnav_data.ld_status[LNS_BOTTOM].set_top(-(rlc->get_height() + 1)); - for (auto& sc : lnav_data.ld_status) { - sc.set_window(lnav_data.ld_window); + for (auto& stat_bar : lnav_data.ld_status) { + stat_bar.set_window(lnav_data.ld_window); } lnav_data.ld_status[LNS_BOTTOM].set_data_source( &lnav_data.ld_bottom_source); diff --git a/src/view_curses.cc b/src/view_curses.cc index 9e3f83a0..d3095a82 100644 --- a/src/view_curses.cc +++ b/src/view_curses.cc @@ -1203,3 +1203,31 @@ view_colors::roles::file() { return VC_ROLE.value(role_t::VCR_FILE); } + +#include + +Result +screen_curses::create() +{ + int errret = 0; + if (setupterm(nullptr, STDIN_FILENO, &errret) == ERR) { + switch (errret) { + case 1: + return Err(std::string("the terminal is a hardcopy, da fuq?!")); + case 0: + return Err( + fmt::format(FMT_STRING("the TERM environment variable is " + "set to an unknown value: {}"), + getenv("TERM"))); + case -1: + return Err( + std::string("the terminfo database could not be found")); + default: + return Err(std::string("setupterm() failed unexpectedly")); + } + } + + newterm(nullptr, stdout, stdin); + + return Ok(screen_curses{stdscr}); +} diff --git a/src/view_curses.hh b/src/view_curses.hh index 3b6802b8..a3a24bae 100644 --- a/src/view_curses.hh +++ b/src/view_curses.hh @@ -53,7 +53,6 @@ #else # error "SysV or X/Open-compatible Curses header file required" #endif - #include #include #include @@ -84,15 +83,40 @@ class view_curses; */ class screen_curses : public log_crash_recoverer { public: - void log_crash_recover() override { endwin(); } + static Result create(); - screen_curses() : sc_main_window(initscr()) {} + void log_crash_recover() override + { + if (this->sc_main_window != nullptr) { + endwin(); + } + } - virtual ~screen_curses() { endwin(); } + virtual ~screen_curses() + { + if (this->sc_main_window != nullptr) { + endwin(); + } + } + + screen_curses(screen_curses&& other) + : sc_main_window(std::exchange(other.sc_main_window, nullptr)) + { + } + + screen_curses(const screen_curses&) = delete; + + screen_curses& operator=(screen_curses&& other) + { + this->sc_main_window = std::exchange(other.sc_main_window, nullptr); + return *this; + } WINDOW* get_window() { return this->sc_main_window; } private: + screen_curses(WINDOW* win) : sc_main_window(win) {} + WINDOW* sc_main_window; }; diff --git a/test/drive_mvwattrline.cc b/test/drive_mvwattrline.cc index 92269e5a..340902c7 100644 --- a/test/drive_mvwattrline.cc +++ b/test/drive_mvwattrline.cc @@ -53,7 +53,7 @@ main(int argc, char* argv[]) setlocale(LC_ALL, ""); { - screen_curses sc; + auto sc = screen_curses::create().unwrap(); WINDOW* win = sc.get_window(); struct line_range lr(0, 40); attr_line_t al; diff --git a/test/drive_readline_curses.cc b/test/drive_readline_curses.cc index ab1484c1..54dfebc9 100644 --- a/test/drive_readline_curses.cc +++ b/test/drive_readline_curses.cc @@ -101,8 +101,7 @@ main(int argc, char* argv[]) drive_data.dd_rl_view = &rlc; - screen_curses sc; - + auto sc = screen_curses::create().unwrap(); keypad(stdscr, TRUE); nonl(); cbreak(); diff --git a/test/drive_vt52_curses.cc b/test/drive_vt52_curses.cc index 19b4a950..cc96ff2c 100644 --- a/test/drive_vt52_curses.cc +++ b/test/drive_vt52_curses.cc @@ -108,8 +108,7 @@ main(int argc, char* argv[]) "ab\bcdef", }; - screen_curses sc; - + auto sc = screen_curses::create().unwrap(); noecho(); vt.set_window(sc.get_window()); vt.set_width(10);