Userland: Use getline instead of Core::File::standard_input in grep

Core::IODevice (which Core::File inherits from) does not have a
reasonable way to block for a line. grep was spinning on
IODevice::read_line, passing endless empty strings to the matcher
lambda. Use getline instead, which will at least block in the Kernel for
characters to be available on stdin and only return full lines (or eof)
This commit is contained in:
Andrew Kaster 2021-01-23 21:58:14 -07:00 committed by Andreas Kling
commit 036828ff43
Notes: sideshowbarker 2024-07-18 22:53:12 +09:00

View file

@ -25,6 +25,7 @@
*/ */
#include <AK/ByteBuffer.h> #include <AK/ByteBuffer.h>
#include <AK/ScopeGuard.h>
#include <AK/String.h> #include <AK/String.h>
#include <AK/Utf8View.h> #include <AK/Utf8View.h>
#include <AK/Vector.h> #include <AK/Vector.h>
@ -186,15 +187,19 @@ int main(int argc, char** argv)
}; };
if (!files.size() && !recursive) { if (!files.size() && !recursive) {
auto stdin_file = Core::File::standard_input(); char* line = nullptr;
while (!stdin_file->eof()) { size_t line_len = 0;
auto line = stdin_file->read_line(); ssize_t nread = 0;
bool is_binary = line.bytes().contains_slow(0); ScopeGuard free_line = [line] { free(line); };
while ((nread = getline(&line, &line_len, stdin)) != -1) {
ASSERT(nread > 0);
StringView line_view(line, nread - 1);
bool is_binary = line_view.contains(0);
if (is_binary && binary_mode == BinaryFileMode::Skip) if (is_binary && binary_mode == BinaryFileMode::Skip)
return 1; return 1;
if (matches(line, "stdin", false, is_binary) && is_binary && binary_mode == BinaryFileMode::Binary) if (matches(line_view, "stdin", false, is_binary) && is_binary && binary_mode == BinaryFileMode::Binary)
return 0; return 0;
} }
} else { } else {