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:
parent
4e9dbe3aa4
commit
ad16313c59
1 changed files with 24 additions and 30 deletions
|
@ -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(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue