aboutsummaryrefslogtreecommitdiff
path: root/ttwhy/main.cpp
blob: 649d01dfebd8b9240b1529d9d4530200129c3c7a (plain)
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();
}