aboutsummaryrefslogtreecommitdiff
path: root/ttwhy
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@gmail.com>2026-06-18 17:19:35 +0200
committerFelix Morgner <felix.morgner@gmail.com>2026-06-18 17:19:35 +0200
commit324af400623a336eb74f51360822d134cad97537 (patch)
treeddca9a6f5337db5ba37a5886e0667d86c23f5856 /ttwhy
parenta7aadafc8d6842fb960786d4840dc29c490d3071 (diff)
downloadttwhy-324af400623a336eb74f51360822d134cad97537.tar.xz
ttwhy-324af400623a336eb74f51360822d134cad97537.zip
lib: improve signal handling
Diffstat (limited to 'ttwhy')
-rw-r--r--ttwhy/io.cppm47
-rw-r--r--ttwhy/main.cpp10
2 files changed, 46 insertions, 11 deletions
diff --git a/ttwhy/io.cppm b/ttwhy/io.cppm
index fd84dfd..be87d36 100644
--- a/ttwhy/io.cppm
+++ b/ttwhy/io.cppm
@@ -14,19 +14,48 @@ import :scanner;
namespace ttwhy::io
{
- export template<typename Stream>
- auto handle_signals(Stream & stream) -> asio::awaitable<std::error_code>
+ export template<typename Stream, typename TerminalAttributes>
+ auto handle_signals(Stream & stream, TerminalAttributes & attributes) -> asio::awaitable<std::error_code>
{
auto executor = co_await asio::this_coro::executor;
auto signals = asio::signal_set{executor, SIGINT, SIGTERM};
+ signals.add(SIGTSTP);
+ signals.add(SIGCONT);
- auto [error, signal] = co_await signals.async_wait(asio::as_tuple(asio::use_awaitable));
- if (!error)
+ while (true)
{
- auto message = std::format("Received signal {}, exiting ...\n", signal);
- co_await asio::async_write(stream, asio::buffer(message), asio::use_awaitable);
+ auto [error, signal] = co_await signals.async_wait(asio::as_tuple(asio::use_awaitable));
+ if (error)
+ {
+ co_return error;
+ }
+
+ switch (signal)
+ {
+ case SIGINT:
+ case SIGTERM:
+ {
+ auto message = std::format("Received signal {}, exiting ...\n", signal);
+ co_await asio::async_write(stream, asio::buffer(message), asio::use_awaitable);
+ co_return asio::error_code{};
+ }
+ case SIGTSTP:
+ {
+ attributes.canonical_mode(true).echo(true);
+ ::raise(SIGSTOP);
+ break;
+ }
+ case SIGCONT:
+ {
+ attributes.canonical_mode(false).echo(false);
+ break;
+ }
+ }
+
+ if (!error)
+ {
+ }
}
- co_return error;
}
export template<typename InputStream, typename AppRouter>
@@ -45,6 +74,10 @@ namespace ttwhy::io
if (error)
{
+ if (error == asio::error::interrupted)
+ {
+ continue;
+ }
co_return;
}
diff --git a/ttwhy/main.cpp b/ttwhy/main.cpp
index 6a813c0..53cf16d 100644
--- a/ttwhy/main.cpp
+++ b/ttwhy/main.cpp
@@ -10,6 +10,10 @@ auto app(int in, int out, int error) -> asio::awaitable<void>
{
using namespace asio::experimental::awaitable_operators;
+ auto terminal_attributes = ttwhy::scoped_attributes{fileno(stdin)} //
+ .canonical_mode(false)
+ .echo(false);
+
auto executor = co_await asio::this_coro::executor;
auto input_stream = asio::posix::stream_descriptor{executor, in};
@@ -18,14 +22,12 @@ auto app(int in, int out, int error) -> asio::awaitable<void>
auto router = ttwhy::routers::echo{input_stream};
- co_await (ttwhy::io::handle_signals(error_stream) || ttwhy::io::read_events(input_stream, router));
+ co_await (ttwhy::io::handle_signals(error_stream, terminal_attributes) ||
+ ttwhy::io::read_events(input_stream, router));
}
auto main() -> int
{
- auto terminal_attributes = ttwhy::scoped_attributes{fileno(stdin)} //
- .canonical_mode(false)
- .echo(false);
auto context = asio::io_context{};
asio::co_spawn(context, app(::fileno(::stdin), ::fileno(::stdout), ::fileno(::stderr)), asio::detached);