22// SPDX-License-Identifier: Apache-2.0
33#include " PosixBackend.hpp"
44
5+
6+ #include " PosixSignalDispatcher.hpp"
7+
58#include < fcntl.h>
69#include < sys/ioctl.h>
710#include < sys/select.h>
811#include < unistd.h>
912
10- #include < array>
11- #include < csignal>
1213#include < iostream>
1314#include < thread>
1415
1516
1617namespace erbsland ::cterm {
1718
18- auto Backend::createPlatformDefault () -> BackendPtr {
19- return impl::PosixBackend::getOrCreate ();
19+ auto Backend::createPlatformDefault (const TerminalFlags terminalFlags ) -> BackendPtr {
20+ return impl::PosixBackend::getOrCreate (terminalFlags );
2021}
2122
2223}
@@ -25,17 +26,19 @@ namespace erbsland::cterm::impl {
2526
2627std::mutex PosixBackend::_instanceMutex;
2728PosixBackend *PosixBackend::_instance = nullptr ;
28- std::array<struct sigaction , PosixBackend::cSignals.size()> PosixBackend::_previousSignalActions{};
2929
30- PosixBackend::PosixBackend () {
30+ PosixBackend::PosixBackend (TerminalFlags terminalFlags) : _terminalFlags{terminalFlags} {
3131 // called once per application.
3232 _instance = this ;
33- registerExitHandlers ();
33+ if (!_terminalFlags.has (TerminalFlag::NoSignalHandling)) {
34+ _signalHandler = std::make_unique<PosixSignalDispatcher>(
35+ [this ](const int signalNumber) -> void { handleProcessSignal (signalNumber); });
36+ }
3437}
3538
3639PosixBackend::~PosixBackend () {
37- unregisterExitHandlers ();
38- std::lock_guard lock{_instanceMutex};
40+ _signalHandler. reset ();
41+ std::scoped_lock lock{_instanceMutex};
3942 if (_instance != nullptr ) {
4043 _instance->restorePlatform ();
4144 _instance = nullptr ;
@@ -57,9 +60,9 @@ void PosixBackend::restorePlatform() {
5760 if (_isAlternateScreenActive) {
5861 std::cout << " \x1b [?1049l" ; // disable alternative screen buffer
5962 }
60- std::cout << " \x1b [0m" ; // restore to default color
61- std::cout << " \x1b [?25h" ; // make the cursor visible.
62- std::cout << " \n " ; // add a newline for compatibility.
63+ std::cout << " \x1b [0m" ; // restore to default color
64+ std::cout << " \x1b [?25h" ; // make the cursor visible.
65+ std::cout << " \n " ; // add a newline for compatibility.
6366 std::cout.flush ();
6467 }
6568 if (_keyInputSessionActive) {
@@ -191,21 +194,21 @@ auto PosixBackend::readLine() -> std::string {
191194 return input;
192195}
193196
194- auto PosixBackend::getOrCreate () noexcept -> BackendPtr {
195- std::lock_guard lock{_instanceMutex};
197+ auto PosixBackend::getOrCreate (const TerminalFlags terminalFlags ) noexcept -> BackendPtr {
198+ std::scoped_lock lock{_instanceMutex};
196199 if (_instance == nullptr ) {
197- return std::make_shared<PosixBackend>();
200+ return std::make_shared<PosixBackend>(terminalFlags );
198201 }
199202 return _instance->shared_from_this ();
200203}
201204
202205auto PosixBackend::instance () noexcept -> PosixBackend * {
203- std::lock_guard lock (_instanceMutex);
206+ std::scoped_lock lock (_instanceMutex);
204207 return _instance;
205208}
206209
207210void PosixBackend::restoreGlobalPlatform () noexcept {
208- std::lock_guard lock (_instanceMutex);
211+ std::scoped_lock lock (_instanceMutex);
209212 if (_instance == nullptr ) {
210213 return ;
211214 }
@@ -300,31 +303,14 @@ void PosixBackend::restoreKeyInputSession() {
300303 _keyInputSessionActive = false ;
301304}
302305
303- void PosixBackend::registerExitHandlers () {
304- std::atexit (&PosixBackend::onExit );
306+ void PosixBackend::handleProcessSignal ( const int signalNumber) noexcept {
307+ restoreGlobalPlatform ( );
305308 struct sigaction action{};
306- action.sa_handler = &PosixBackend::onSignal ;
309+ action.sa_handler = SIG_DFL ;
307310 sigemptyset (&action.sa_mask );
308311 action.sa_flags = 0 ;
309- for (std::size_t index = 0 ; index < cSignals.size (); ++index) {
310- sigaction (cSignals[index], &action, &_previousSignalActions[index]);
311- }
312- }
313-
314- void PosixBackend::unregisterExitHandlers () {
315- for (std::size_t index = 0 ; index < cSignals.size (); ++index) {
316- sigaction (cSignals[index], &_previousSignalActions[index], nullptr );
317- }
318- }
319-
320- void PosixBackend::onExit () noexcept {
321- restoreGlobalPlatform ();
322- }
323-
324- void PosixBackend::onSignal (const int signalNumber) noexcept {
325- restoreGlobalPlatform ();
326- std::signal (signalNumber, SIG_DFL );
327- std::raise (signalNumber);
312+ sigaction (signalNumber, &action, nullptr );
313+ kill (getpid (), signalNumber);
328314 std::_Exit (128 + signalNumber);
329315}
330316
0 commit comments