tac: avoid mmap on regular files to prevent SIGBUS on truncation
When a file is memory-mapped and then truncated by another process
while tac is reading it, accessing the now-invalid mapped region
triggers SIGBUS and crashes the process. This is particularly
problematic for log rotation scenarios where tac might read logs
that are being rotated/truncated concurrently.
Replace the mmap-based file reading with read_to_end(), which reads
the entire file into a heap buffer. This matches how GNU tac avoids
the issue. The mmap path is retained for stdin (via temp files we
own), where external truncation is not a concern.
Fixes #9748
Co-Authored-By: Claude (claude-opus-4-6) <noreply@anthropic.com>