aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.clang-format10
-rw-r--r--.clang-tidy2
-rw-r--r--.lazy.lua1
-rw-r--r--CMakeLists.txt3
-rw-r--r--ttwhy/io.cppm84
-rw-r--r--ttwhy/lib.cppm1
-rw-r--r--ttwhy/main.cpp28
-rw-r--r--ttwhy/scoped_attributes.cppm5
8 files changed, 114 insertions, 20 deletions
diff --git a/.clang-format b/.clang-format
index 48fb8b3..3bbbb4a 100644
--- a/.clang-format
+++ b/.clang-format
@@ -55,12 +55,14 @@ DerivePointerAlignment: "false"
FixNamespaceComments: "true"
IncludeBlocks: Regroup
IncludeCategories:
- # Project Headers
- - Regex: 'ttwhy/[[:alnum:]._\/]+\.hpp'
- Priority: 100
# Standard Headers
- - Regex: '<[[:alnum:]._]+>'
+ - Regex: '(asio|asio/.*)\.hpp'
+ Priority: 500
+ # Standard Headers
+ - Regex: '[[:alnum:]._]+.h'
Priority: 900
+ - Regex: '[[:alnum:]._]+'
+ Priority: 910
# Fallback
- Regex: '.*'
Priority: 800
diff --git a/.clang-tidy b/.clang-tidy
index 0be16fb..6794ba6 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -87,7 +87,5 @@ CheckOptions:
readability-magic-numbers.IgnoreTypeAliases: true
FormatStyle: file
-HeaderFilterRegex: "(.*/kstd/kstd/.*)|(arch|kernel|kapi)/.*\\.hpp"
-SystemHeaders: true
RemovedArgs:
- -fcondition-coverage
diff --git a/.lazy.lua b/.lazy.lua
index 49182ed..1f0ff28 100644
--- a/.lazy.lua
+++ b/.lazy.lua
@@ -44,6 +44,7 @@ return {
action = "copy",
target = workspace_folder .. "/build",
},
+ cmake_use_presets = true,
},
},
{
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3091b9e..316b655 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -23,7 +23,7 @@ find_package("Threads")
add_library("asio" INTERFACE)
add_library("ext::asio" ALIAS "asio")
-target_include_directories("asio" INTERFACE
+target_include_directories("asio" SYSTEM INTERFACE
"${asio_SOURCE_DIR}/asio/include"
)
@@ -40,6 +40,7 @@ target_sources("ttwhy-core" PUBLIC
FILE_SET CXX_MODULES
FILES
+ "ttwhy/io.cppm"
"ttwhy/lib.cppm"
"ttwhy/scoped_attributes.cppm"
)
diff --git a/ttwhy/io.cppm b/ttwhy/io.cppm
new file mode 100644
index 0000000..cbd3902
--- /dev/null
+++ b/ttwhy/io.cppm
@@ -0,0 +1,84 @@
+module;
+
+#include <asio.hpp>
+
+#include <expected>
+#include <format>
+#include <string>
+
+export module ttwhy:io;
+
+namespace ttwhy::io
+{
+
+ export template<typename Stream>
+ auto handle_signals(Stream & stream) -> asio::awaitable<std::error_code>
+ {
+ auto executor = co_await asio::this_coro::executor;
+ auto signals = asio::signal_set{executor, SIGINT, SIGTERM};
+
+ auto [error, signal] = co_await signals.async_wait(asio::as_tuple(asio::use_awaitable));
+ if (!error)
+ {
+ auto message = std::format("Received signal {}, exiting ...\n", signal);
+ co_await asio::async_write(stream, asio::buffer(message), asio::use_awaitable);
+ }
+ co_return error;
+ }
+
+ export template<typename InputStream, typename ErrorStream>
+ auto read(InputStream & input_stream, ErrorStream & error_stream)
+ -> asio::awaitable<std::expected<std::string, asio::error_code>>
+ {
+ auto data = std::string{15, '\0'};
+
+ auto [error, read] = co_await input_stream.async_read_some(asio::buffer(data), asio::as_tuple(asio::use_awaitable));
+
+ if (error)
+ {
+ auto message = std::format("{}, exiting ...\n", error.message());
+ co_await asio::async_write(error_stream, asio::buffer(message), asio::use_awaitable);
+ co_return std::unexpected{error};
+ }
+
+ data.resize(read);
+ co_return data;
+ }
+
+ export template<typename OutputStream, typename ErrorStream>
+ auto write(std::string const & string, OutputStream & output_stream, ErrorStream & error_stream)
+ -> asio::awaitable<asio::error_code>
+ {
+ auto [error, written] =
+ co_await asio::async_write(output_stream, asio::buffer(string), asio::as_tuple(asio::use_awaitable));
+
+ if (error)
+ {
+ auto message = std::format("{}, exiting ...\n", error.message());
+ co_await asio::async_write(error_stream, asio::buffer(message), asio::use_awaitable);
+ }
+
+ co_return error;
+ }
+
+ export template<typename InputStream, typename OutputStream, typename ErrorStream>
+ auto echo(InputStream & input_stream, OutputStream & output_stream, ErrorStream & error_stream)
+ -> asio::awaitable<asio::error_code>
+ {
+ while (true)
+ {
+ auto input = co_await read(input_stream, error_stream);
+ if (!input.has_value())
+ {
+ co_return input.error();
+ }
+
+ auto write_error = co_await write(input.value(), output_stream, error_stream);
+ if (write_error)
+ {
+ co_return write_error;
+ }
+ }
+ }
+
+} // namespace ttwhy::io
diff --git a/ttwhy/lib.cppm b/ttwhy/lib.cppm
index fe7486f..14e0d5c 100644
--- a/ttwhy/lib.cppm
+++ b/ttwhy/lib.cppm
@@ -1,3 +1,4 @@
export module ttwhy;
+export import :io;
export import :scoped_attributes;
diff --git a/ttwhy/main.cpp b/ttwhy/main.cpp
index c210bee..649d01d 100644
--- a/ttwhy/main.cpp
+++ b/ttwhy/main.cpp
@@ -1,23 +1,30 @@
#include <asio.hpp>
+#include <asio/experimental/awaitable_operators.hpp>
+
#include <stdio.h>
+#include <format>
+
import ttwhy;
-auto handle_signals(asio::cancellation_signal & cancellation_signal) -> asio::awaitable<void>
+auto app(int in, int out, int error) -> asio::awaitable<void>
{
- co_await asio::this_coro::reset_cancellation_state(asio::disable_cancellation());
- co_await asio::this_coro::throw_if_cancelled(false);
+ using namespace asio::experimental::awaitable_operators;
auto executor = co_await asio::this_coro::executor;
- auto signals = asio::signal_set{executor, SIGINT, SIGTERM};
- auto log_stream = asio::posix::stream_descriptor{executor, fileno(stdout)};
- auto [error, signal] = co_await signals.async_wait(asio::as_tuple(asio::use_awaitable));
+ 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 (!error)
+ if (final_error && final_error != asio::error::operation_aborted)
{
- co_await asio::async_write(log_stream, asio::buffer("shutting down...\n"), asio::as_tuple(asio::use_awaitable));
- cancellation_signal.emit(asio::cancellation_type::all);
+ auto message = std::format("Terminated with error: {}\n", final_error.message());
+ co_await asio::async_write(error_stream, asio::buffer(message), asio::use_awaitable);
}
}
@@ -27,9 +34,8 @@ auto main() -> int
.canonical_mode(false)
.echo(false);
auto context = asio::io_context{};
- auto cancellation_signal = asio::cancellation_signal{};
- asio::co_spawn(context, handle_signals(cancellation_signal), asio::detached);
+ asio::co_spawn(context, app(fileno(stdin), fileno(stdout), fileno(stderr)), asio::detached);
context.run();
}
diff --git a/ttwhy/scoped_attributes.cppm b/ttwhy/scoped_attributes.cppm
index 7c32ddf..b49dd18 100644
--- a/ttwhy/scoped_attributes.cppm
+++ b/ttwhy/scoped_attributes.cppm
@@ -1,9 +1,10 @@
module;
-#include <cerrno>
-#include <system_error>
#include <termios.h>
#include <unistd.h>
+
+#include <cerrno>
+#include <system_error>
#include <utility>
export module ttwhy:scoped_attributes;