From 2f6c99dce5f91a766a6d76c58700dca2707737be Mon Sep 17 00:00:00 2001 From: Karol Kosek Date: Wed, 31 May 2023 18:54:38 +0200 Subject: [PATCH] dd: Show statistics also after receiving an interrupt signal --- Userland/Utilities/dd.cpp | 49 +++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/Userland/Utilities/dd.cpp b/Userland/Utilities/dd.cpp index 5f9b149097a..7e81a9773e6 100644 --- a/Userland/Utilities/dd.cpp +++ b/Userland/Utilities/dd.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2021, János Tóth + * Copyright (c) 2023, Karol Kosek * * SPDX-License-Identifier: BSD-2-Clause */ @@ -8,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +38,22 @@ enum Status { Noxfer }; +struct { + Status status = Default; + size_t total_bytes_copied = 0; + size_t total_blocks_in = 0, partial_blocks_in = 0; + size_t total_blocks_out = 0, partial_blocks_out = 0; +} statistics; + +static void closing_statistics() +{ + if (statistics.status != Default) + return; + warnln("{}+{} blocks in", statistics.total_blocks_in, statistics.partial_blocks_in); + warnln("{}+{} blocks out", statistics.total_blocks_out, statistics.partial_blocks_out); + warnln("{} bytes copied.", statistics.total_bytes_copied); +} + static StringView split_at_equals(StringView argument) { auto values = argument.split_view('=', SplitBehavior::KeepEmpty); @@ -134,11 +152,7 @@ ErrorOr serenity_main(Main::Arguments arguments) size_t count = 0; size_t skip = 0; size_t seek = 0; - Status status = Default; - size_t total_bytes_copied = 0; - size_t total_blocks_in = 0, partial_blocks_in = 0; - size_t total_blocks_out = 0, partial_blocks_out = 0; uint8_t* buffer = nullptr; ssize_t nread = 0, nwritten = 0; @@ -173,7 +187,7 @@ ErrorOr serenity_main(Main::Arguments arguments) return 1; } } else if (argument.starts_with("status="sv)) { - if (handle_status_arguments(status, argument) < 0) { + if (handle_status_arguments(statistics.status, argument) < 0) { return 1; } } else { @@ -194,6 +208,11 @@ ErrorOr serenity_main(Main::Arguments arguments) } } + TRY(Core::System::signal(SIGINT, [](int status) { + closing_statistics(); + exit(status); + })); + while (1) { nread = read(input_fd, buffer, block_size); if (nread < 0) { @@ -203,12 +222,12 @@ ErrorOr serenity_main(Main::Arguments arguments) break; } else { if ((size_t)nread != block_size) { - partial_blocks_in++; + statistics.partial_blocks_in++; } else { - total_blocks_in++; + statistics.total_blocks_in++; } - if (partial_blocks_in + total_blocks_in <= skip) { + if (statistics.partial_blocks_in + statistics.total_blocks_in <= skip) { continue; } @@ -220,25 +239,21 @@ ErrorOr serenity_main(Main::Arguments arguments) break; } else { if ((size_t)nwritten < block_size) { - partial_blocks_out++; + statistics.partial_blocks_out++; } else { - total_blocks_out++; + statistics.total_blocks_out++; } - total_bytes_copied += nwritten; + statistics.total_bytes_copied += nwritten; - if (count > 0 && (partial_blocks_out + total_blocks_out) >= count) { + if (count > 0 && (statistics.partial_blocks_out + statistics.total_blocks_out) >= count) { break; } } } } - if (status == Default) { - warnln("{}+{} blocks in", total_blocks_in, partial_blocks_in); - warnln("{}+{} blocks out", total_blocks_out, partial_blocks_out); - warnln("{} bytes copied.", total_bytes_copied); - } + closing_statistics(); free(buffer);