Open files to hash without blocking and reject non-regular ones (closes #100) #107

Merged
clawbot merged 1 commits from issue-100-fifo-open into next 2026-10-14 20:18:33 +02:00
Collaborator

Fixes #100.

A regular file replaced by a FIFO after the walk statted it made the hash phase's open wait forever for a writer, so the scan never ended and kept its lock.

Both the hash phase and the content phase now open each file through openRegularFile. It opens with O_NONBLOCK, then checks with fstat on the open file that it is still a regular file. Anything else is closed and reported as not a regular file, which both phases already handle as a per-path error: one warning, counted as skipped, no record written. O_NONBLOCK stays set on the regular files that pass, and reads of a regular file ignore it.

TestHashPhaseSkipsFileReplacedByFIFO walks a one-file tree, swaps the file for a FIFO, and runs the hash phase on what the walk found. Without the fix it does not fail an assertion; it hangs until the test binary's timeout.

  • Judgement call: the test runs the walk and the hash phase directly, not a whole scan, because nothing in a full run pauses between the walk and the read. "Exit 0" from the definition of done is checked as the hash phase returning no error.
  • The content phase is covered by a direct call of hashContentOnly on the FIFO, not by a scan.
  • Unverified: device nodes (making one needs root) and macOS, which runs the same code.

Model: opus-5-5

Fixes https://git.eeqj.de/sneak/sfdupes/issues/100. A regular file replaced by a FIFO after the walk statted it made the hash phase's open wait forever for a writer, so the scan never ended and kept its lock. Both the hash phase and the content phase now open each file through `openRegularFile`. It opens with `O_NONBLOCK`, then checks with `fstat` on the open file that it is still a regular file. Anything else is closed and reported as `not a regular file`, which both phases already handle as a per-path error: one warning, counted as skipped, no record written. `O_NONBLOCK` stays set on the regular files that pass, and reads of a regular file ignore it. `TestHashPhaseSkipsFileReplacedByFIFO` walks a one-file tree, swaps the file for a FIFO, and runs the hash phase on what the walk found. Without the fix it does not fail an assertion; it hangs until the test binary's timeout. - Judgement call: the test runs the walk and the hash phase directly, not a whole `scan`, because nothing in a full run pauses between the walk and the read. "Exit 0" from the definition of done is checked as the hash phase returning no error. - The content phase is covered by a direct call of `hashContentOnly` on the FIFO, not by a scan. - Unverified: device nodes (making one needs root) and macOS, which runs the same code. Model: opus-5-5
clawbot added the needs-review label 2026-10-14 19:50:56 +02:00
clawbot self-assigned this 2026-10-14 19:50:56 +02:00
Author
Collaborator
  1. The branch no longer merges into next: its Completed Steps entry at TODO.md:32 conflicts with the entry for #102, which landed at the same place on next in a4d76af. Acceptable: the commit rebased onto the current next, with both entries kept at the top of Completed Steps and this one first.

Model: opus-5-5

1. The branch no longer merges into `next`: its Completed Steps entry at `TODO.md:32` conflicts with the entry for https://git.eeqj.de/sneak/sfdupes/issues/102, which landed at the same place on `next` in `a4d76af`. Acceptable: the commit rebased onto the current `next`, with both entries kept at the top of Completed Steps and this one first. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-14 20:02:13 +02:00
clawbot force-pushed issue-100-fifo-open from 2bd4a3c057 to 5b7a611113 2026-10-14 20:05:14 +02:00 Compare
Author
Collaborator

Rebased onto the current next. The Completed Steps entry for #100 now sits first, above the one for #102; nothing else changed.

Model: opus-5-5

Rebased onto the current `next`. The Completed Steps entry for https://git.eeqj.de/sneak/sfdupes/issues/100 now sits first, above the one for https://git.eeqj.de/sneak/sfdupes/issues/102; nothing else changed. Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-10-14 20:05:27 +02:00
Author
Collaborator
  1. The branch no longer merges into next: its Completed Steps entry at TODO.md:32 conflicts with the entry for #101, which landed at the same place on next in 1b26b5c. Acceptable: the commit rebased onto the current next, with both entries kept at the top of Completed Steps and this one first.

Model: opus-5-5

1. The branch no longer merges into `next`: its Completed Steps entry at `TODO.md:32` conflicts with the entry for https://git.eeqj.de/sneak/sfdupes/issues/101, which landed at the same place on `next` in `1b26b5c`. Acceptable: the commit rebased onto the current `next`, with both entries kept at the top of Completed Steps and this one first. Model: opus-5-5
clawbot added needs-rebase and removed needs-review labels 2026-10-14 20:13:58 +02:00
clawbot added 1 commit 2026-10-14 20:16:20 +02:00
A regular file replaced by a FIFO after the walk statted it made the
hash phase's open wait forever for a writer, so the scan never ended
and kept the lock. The hash and content phases now open each file with
O_NONBLOCK and check with fstat that it is still a regular file;
anything else is a per-path error, warned about and skipped. The new
test replaces a walked file with a FIFO before the hash phase reads it.

Model: opus-5-5
clawbot force-pushed issue-100-fifo-open from 5b7a611113 to 2ff22964f5 2026-10-14 20:16:20 +02:00 Compare
clawbot merged commit 5dc6bfb6b7 into next 2026-10-14 20:18:33 +02:00
clawbot deleted branch issue-100-fifo-open 2026-10-14 20:18:34 +02:00
Sign in to join this conversation.