1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
#include <asio.hpp>
#include <asio/experimental/awaitable_operators.hpp>
#include <stdio.h>
#include <format>
import ttwhy;
auto app(int in, int out, int error) -> asio::awaitable<void>
{
using namespace asio::experimental::awaitable_operators;
auto executor = co_await asio::this_coro::executor;
auto input_stream = asio::posix::stream_descriptor{executor, in};
auto output_stream = asio::posix::stream_descriptor{executor, out};
auto error_stream = asio::posix::stream_descriptor{executor, error};
auto result =
co_await (ttwhy::io::handle_signals(error_stream) || ttwhy::io::echo(input_stream, output_stream, error_stream));
auto final_error = result.index() == 0 ? std::get<0>(result) : std::get<1>(result);
if (final_error && final_error != asio::error::operation_aborted)
{
auto message = std::format("Terminated with error: {}\n", final_error.message());
co_await asio::async_write(error_stream, asio::buffer(message), asio::use_awaitable);
}
}
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);
context.run();
}
|