/** Terminal handling. * * @author Steffen Vogel * @copyright 2014-2022, Institute for Automation of Complex Power Systems, EONERC * @license GNU General Public License (version 3) * * VILLAScommon * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ #include #include #include #include using namespace villas; class Terminal * Terminal::current = nullptr; Terminal::Terminal() { int ret; window.ws_row = 0; window.ws_col = 0; isTty = isatty(STDERR_FILENO); Logger logger = logging.get("terminal"); if (isTty) { struct sigaction sa_resize; sa_resize.sa_flags = SA_SIGINFO; sa_resize.sa_sigaction = resize; sigemptyset(&sa_resize.sa_mask); ret = sigaction(SIGWINCH, &sa_resize, nullptr); if (ret) throw SystemError("Failed to register signal handler"); /* Try to get initial terminal dimensions */ ret = ioctl(STDERR_FILENO, TIOCGWINSZ, &window); if (ret) logger->warn("Failed to get terminal dimensions"); } else { logger->info("stderr is not associated with a terminal! Using fallback values for window size..."); } /* Fallback if for some reason we can not determine a prober window size */ if (window.ws_col == 0) window.ws_col = 150; if (window.ws_row == 0) window.ws_row = 50; } void Terminal::resize(int, siginfo_t *, void *) { if (!current) current = new Terminal(); Logger logger = logging.get("terminal"); int ret; ret = ioctl(STDERR_FILENO, TIOCGWINSZ, ¤t->window); if (ret) throw SystemError("Failed to get terminal dimensions"); logger->debug("New terminal size: {}x{}", current->window.ws_row, current->window.ws_col); };