1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 06:58:11 +00:00

dd: Show statistics also after receiving an interrupt signal

This commit is contained in:
Karol Kosek 2023-05-31 18:54:38 +02:00 committed by Jelle Raaijmakers
parent f12dc8b7f5
commit 2f6c99dce5

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2021, János Tóth <toth-janos@outlook.com> * Copyright (c) 2021, János Tóth <toth-janos@outlook.com>
* Copyright (c) 2023, Karol Kosek <krkk@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -8,6 +9,7 @@
#include <AK/DeprecatedString.h> #include <AK/DeprecatedString.h>
#include <AK/Optional.h> #include <AK/Optional.h>
#include <AK/Vector.h> #include <AK/Vector.h>
#include <LibCore/System.h>
#include <LibMain/Main.h> #include <LibMain/Main.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdint.h> #include <stdint.h>
@ -36,6 +38,22 @@ enum Status {
Noxfer 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) static StringView split_at_equals(StringView argument)
{ {
auto values = argument.split_view('=', SplitBehavior::KeepEmpty); auto values = argument.split_view('=', SplitBehavior::KeepEmpty);
@ -134,11 +152,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
size_t count = 0; size_t count = 0;
size_t skip = 0; size_t skip = 0;
size_t seek = 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; uint8_t* buffer = nullptr;
ssize_t nread = 0, nwritten = 0; ssize_t nread = 0, nwritten = 0;
@ -173,7 +187,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
return 1; return 1;
} }
} else if (argument.starts_with("status="sv)) { } else if (argument.starts_with("status="sv)) {
if (handle_status_arguments(status, argument) < 0) { if (handle_status_arguments(statistics.status, argument) < 0) {
return 1; return 1;
} }
} else { } else {
@ -194,6 +208,11 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
} }
} }
TRY(Core::System::signal(SIGINT, [](int status) {
closing_statistics();
exit(status);
}));
while (1) { while (1) {
nread = read(input_fd, buffer, block_size); nread = read(input_fd, buffer, block_size);
if (nread < 0) { if (nread < 0) {
@ -203,12 +222,12 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
break; break;
} else { } else {
if ((size_t)nread != block_size) { if ((size_t)nread != block_size) {
partial_blocks_in++; statistics.partial_blocks_in++;
} else { } 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; continue;
} }
@ -220,25 +239,21 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
break; break;
} else { } else {
if ((size_t)nwritten < block_size) { if ((size_t)nwritten < block_size) {
partial_blocks_out++; statistics.partial_blocks_out++;
} else { } 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; break;
} }
} }
} }
} }
if (status == Default) { closing_statistics();
warnln("{}+{} blocks in", total_blocks_in, partial_blocks_in);
warnln("{}+{} blocks out", total_blocks_out, partial_blocks_out);
warnln("{} bytes copied.", total_bytes_copied);
}
free(buffer); free(buffer);