From c5df5e504cb2cb5093e85bbe7b00e551f6e69ed6 Mon Sep 17 00:00:00 2001 From: LuK1337 Date: Sat, 31 Jul 2021 19:01:47 +0200 Subject: [PATCH] cksum: Don't read the entire input file in memory Same as `checksum`, in some cases we just can't load whole file into memory. --- Userland/Utilities/cksum.cpp | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/Userland/Utilities/cksum.cpp b/Userland/Utilities/cksum.cpp index 4710c9ab8d..b432af7973 100644 --- a/Userland/Utilities/cksum.cpp +++ b/Userland/Utilities/cksum.cpp @@ -41,18 +41,39 @@ int main(int argc, char** argv) bool fail = false; for (auto& path : paths) { - auto file = Core::File::construct((StringView(path) == "-") ? "/dev/stdin" : path); + auto filepath = (StringView(path) == "-") ? "/dev/stdin" : path; + auto file = Core::File::construct(filepath); if (!file->open(Core::OpenMode::ReadOnly)) { warnln("{}: {}: {}", argv[0], path, file->error_string()); fail = true; continue; } - auto file_buffer = file->read_all(); - auto bytes = file_buffer.bytes().size(); + struct stat st; + if (fstat(file->fd(), &st) < 0) { + warnln("{}: Failed to fstat {}: {}", argv[0], filepath, strerror(errno)); + fail = true; + continue; + } if (algorithm == "crc32") { - outln("{} {} {}", Crypto::Checksum::CRC32 { file_buffer.bytes() }.digest(), bytes, path); + Crypto::Checksum::CRC32 crc32; + while (!file->eof() && !file->has_error()) + crc32.update(file->read(PAGE_SIZE)); + if (file->has_error()) { + warnln("Failed to read {}: {}", filepath, file->error_string()); + fail = true; + continue; + } + outln("{} {} {}", crc32.digest(), st.st_size, path); } else if (algorithm == "adler32") { - outln("{} {} {}", Crypto::Checksum::Adler32 { file_buffer.bytes() }.digest(), bytes, path); + Crypto::Checksum::Adler32 adler32; + while (!file->eof() && !file->has_error()) + adler32.update(file->read(PAGE_SIZE)); + if (file->has_error()) { + warnln("Failed to read {}: {}", filepath, file->error_string()); + fail = true; + continue; + } + outln("{} {} {}", adler32.digest(), st.st_size, path); } else { warnln("{}: Unknown checksum algorithm: {}", argv[0], algorithm); exit(1);