1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-29 20:17:45 +00:00

head: -c allocate memory as needed (#5704)

* head: -c allocate memory as needed

Improve the execution of tests/head/head-c.sh

* simplify the code

Co-authored-by: Daniel Hofstetter <daniel.hofstetter@42dh.com>

---------

Co-authored-by: Daniel Hofstetter <daniel.hofstetter@42dh.com>
This commit is contained in:
Sylvestre Ledru 2023-12-28 07:15:01 +01:00 committed by GitHub
parent 4e9dbe3aa4
commit ad16313c59
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -252,43 +252,37 @@ fn read_but_last_n_bytes(input: &mut impl std::io::BufRead, n: usize) -> std::io
let stdout = std::io::stdout(); let stdout = std::io::stdout();
let mut stdout = stdout.lock(); let mut stdout = stdout.lock();
let mut ring_buffer = vec![0u8; n]; let mut ring_buffer = Vec::new();
// first we fill the ring buffer
if let Err(e) = input.read_exact(&mut ring_buffer) {
if e.kind() == ErrorKind::UnexpectedEof {
return Ok(());
} else {
return Err(e);
}
}
let mut buffer = [0u8; BUF_SIZE]; let mut buffer = [0u8; BUF_SIZE];
let mut total_read = 0;
loop { loop {
let read = loop { let read = match input.read(&mut buffer) {
match input.read(&mut buffer) { Ok(0) => break,
Ok(n) => break n, Ok(read) => read,
Err(e) => match e.kind() { Err(e) => match e.kind() {
ErrorKind::Interrupted => {} ErrorKind::Interrupted => continue,
_ => return Err(e), _ => return Err(e),
}, },
}
}; };
if read == 0 {
return Ok(()); total_read += read;
} else if read >= n {
stdout.write_all(&ring_buffer)?; if total_read <= n {
stdout.write_all(&buffer[..read - n])?; // Fill the ring buffer without exceeding n bytes
for i in 0..n { let overflow = total_read - n;
ring_buffer[i] = buffer[read - n + i]; ring_buffer.extend_from_slice(&buffer[..read - overflow]);
}
} else { } else {
stdout.write_all(&ring_buffer[..read])?; // Write the ring buffer and the part of the buffer that exceeds n
for i in 0..n - read { stdout.write_all(&ring_buffer)?;
ring_buffer[i] = ring_buffer[read + i]; stdout.write_all(&buffer[..read - n + ring_buffer.len()])?;
} ring_buffer.clear();
ring_buffer[n - read..].copy_from_slice(&buffer[..read]); ring_buffer.extend_from_slice(&buffer[read - n + ring_buffer.len()..read]);
} }
} }
Ok(())
} }
fn read_but_last_n_lines( fn read_but_last_n_lines(