Skip to content

Commit 977c752

Browse files
committed
tac: fall back to memory when TMPDIR is invalid, add to root tests
1 parent ffc61cc commit 977c752

4 files changed

Lines changed: 23 additions & 13 deletions

File tree

.vscode/cspell.dictionaries/jargon.wordlist.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,3 +215,4 @@ TUNABLES
215215
tunables
216216
VMULL
217217
vmull
218+
tmpfs

src/uu/tac/src/tac.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -310,13 +310,22 @@ fn try_mmap_stdin() -> Option<Mmap> {
310310
}
311311

312312
/// Copy stdin to a temp file, then read it into a buffer.
313+
/// Falls back to reading directly into memory if temp file creation fails.
313314
fn read_stdin_to_buf() -> std::io::Result<Vec<u8>> {
314-
let mut tmp = tempfile::tempfile()?;
315-
copy(&mut stdin(), &mut tmp)?;
316-
tmp.rewind()?;
317-
let mut buf = Vec::new();
318-
tmp.read_to_end(&mut buf)?;
319-
Ok(buf)
315+
// Try to create a temp file (respects TMPDIR)
316+
if let Ok(mut tmp) = tempfile::tempfile() {
317+
// Temp file created - copy stdin to it, then read back
318+
copy(&mut stdin(), &mut tmp)?;
319+
tmp.rewind()?;
320+
let mut buf = Vec::new();
321+
tmp.read_to_end(&mut buf)?;
322+
Ok(buf)
323+
} else {
324+
// Fall back to reading directly into memory (e.g., bad TMPDIR)
325+
let mut buf = Vec::new();
326+
stdin().read_to_end(&mut buf)?;
327+
Ok(buf)
328+
}
320329
}
321330

322331
fn try_mmap_path(path: &Path) -> Option<Mmap> {

tests/by-util/test_tac.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -338,14 +338,12 @@ fn test_failed_write_is_reported() {
338338

339339
#[cfg(target_os = "linux")]
340340
#[test]
341-
fn test_stdin_tempfile_error_continues() {
342-
// Set TMPDIR to a non-writable location to force temp file creation to fail
341+
fn test_stdin_bad_tmpdir_fallback() {
342+
// When TMPDIR is invalid, tac falls back to reading stdin directly into memory
343343
new_ucmd!()
344-
.env("TMPDIR", "/proc")
344+
.env("TMPDIR", "/nonexistent/dir")
345345
.arg("-")
346-
.arg("prime_per_line.txt")
347346
.pipe_in("a\nb\nc\n")
348-
.fails()
349-
.stderr_contains("stdin")
350-
.stdout_is_fixture("prime_per_line.expected");
347+
.succeeds()
348+
.stdout_is("c\nb\na\n");
351349
}

util/fetch-gnu.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@ curl -L ${repo}/raw/refs/heads/master/tests/csplit/csplit-io-err.sh > tests/cspl
1111
# Avoid incorrect PASS
1212
curl -L ${repo}/raw/refs/heads/master/tests/runcon/runcon-compute.sh > tests/runcon/runcon-compute.sh
1313
curl -L ${repo}/raw/refs/heads/master/tests/tac/tac-continue.sh > tests/tac/tac-continue.sh
14+
# Add tac-continue.sh to root tests (it requires root to mount tmpfs)
15+
sed -i 's|tests/split/l-chunk-root.sh.*|tests/split/l-chunk-root.sh\t\t\t\\\n tests/tac/tac-continue.sh\t\t\t\\|' tests/local.mk

0 commit comments

Comments
 (0)