diff --git a/userspace/sysutils/src/grep.rs b/userspace/sysutils/src/grep.rs index beb46a00..1a126024 100644 --- a/userspace/sysutils/src/grep.rs +++ b/userspace/sysutils/src/grep.rs @@ -3,7 +3,7 @@ use std::{ fs::File, - io::{self, stdout, Seek, Write}, + io::{self, stdout, Seek, Stdin, Write}, path::{Path, PathBuf}, process::ExitCode, }; @@ -29,6 +29,22 @@ struct FileInput { position: usize, } +struct StdinInput { + stdin: Stdin, + buffer: String, + eof: bool, +} + +impl StdinInput { + pub fn new() -> Self { + Self { + stdin: io::stdin(), + buffer: String::new(), + eof: false, + } + } +} + impl FileInput { pub fn open>(path: P) -> io::Result { let mut file = File::open(path)?; @@ -39,6 +55,22 @@ impl FileInput { } } +impl Input for StdinInput { + fn next_line(&mut self) -> io::Result> { + if self.eof { + return Ok(None); + } + + self.buffer.clear(); + if self.stdin.read_line(&mut self.buffer)? == 0 { + self.eof = true; + return Ok(None); + } + + Ok(Some(self.buffer.trim_end_matches('\n').as_bytes())) + } +} + impl Input for FileInput { fn next_line(&mut self) -> io::Result> { if self.position >= self.mmap.len() { @@ -57,7 +89,7 @@ impl Input for FileInput { } } -fn run_on(input: &mut I, regex: &Regex) -> io::Result { +fn run_on(input: &mut I, regex: &Regex) -> Result { let mut any = false; loop { let Some(line) = input.next_line()? else { @@ -76,14 +108,18 @@ fn run_on(input: &mut I, regex: &Regex) -> io::Result { #[derive(Debug, Parser)] struct Args { expression: String, - filename: PathBuf, + filename: Option, } fn run(args: &Args) -> Result { let regex = Regex::new(&args.expression)?; - let mut input = FileInput::open(&args.filename)?; - let any = run_on(&mut input, ®ex)?; - Ok(any) + if let Some(filename) = args.filename.as_deref() { + let mut input = FileInput::open(filename)?; + run_on(&mut input, ®ex) + } else { + let mut input = StdinInput::new(); + run_on(&mut input, ®ex) + } } fn main() -> ExitCode {