| `unixapp.c`, `mingwapp.c` | Platform-specific implementations of system info, process management, and services |
| `thermal.h` / `thermal.c` | Temperature monitoring to prevent hardware overheating |
| `selftest.c`, `speed.c` | Self-test command (`test`) and CPU RAID parity performance benchmark (`-T`) |
| `mktest.c`, `mkstream.c` | Standalone test utility tools for recovery and stream validation |
### OS Abstraction Files (`os/`)
The platform abstraction layer is separated into `os/`. Note that `os/` acts as a library layer, so having unused functions (e.g., platform helper functions not currently invoked by the main CLI application) is expected.
SnapRAID is designed to recover from an interruption, including `SIGKILL`, at any point. It achieves this by reading recovery data from multiple snapshots, checking file metadata when reading, and validating data with hashes. Account for this design before treating a non-atomic transition or mixed snapshot lifecycle as an integrity defect.
### Build System
-`configure.ac`: Autoconf script (detects systemd vs BSD init)
- Both Linux and Windows builds are out-of-tree in dedicated subdirectories (`linux/` and `windows/`) in the project directory, keeping the root directory clean:
- Linux build:
`mkdir -p linux && (cd linux && ../configure && make -j$(nproc))`
Subsequent Linux rebuilds: `(cd linux && make -j$(nproc))`
- Windows x64 cross-compilation:
`mkdir -p windows && (cd windows && ../configure.windows-x64 && make -j$(nproc))`
Subsequent Windows rebuilds: `(cd windows && make -j$(nproc))`
- The Windows build needs to be tested only when modifying Windows-specific code (e.g., `os/mingw.*`, `cmdline/mingwapp.c`, or Windows-specific `#ifdef` paths)
- **Simplicity First**: Always prefer the simplest and cleanest implementation that fully satisfies the demonstrated requirements. Do not introduce extra state, abstractions, conditions, or defensive handling unless a concrete requirement or verified failure mode needs them. When replacing existing logic, preserve its narrow established semantics instead of broadening it through inferred state from unrelated subsystems.
- **Smallest Necessary Change** Harmless existing behavior or artifacts do not justify refactoring. Always make the smallest change necessary to satisfy the requirement.
- **Comments**: Use `/** ... */` for multiline top comments preceding declarations and `/* ... */` for multiline comments within code. Use `/* first letter lowercase */` for single-line inline notes.
- **Critical Comments**: Always add a comment at non-obvious critical points, especially around data-integrity invariants, crash recovery, fallback behavior, concurrency, and fatal versus best-effort error handling. Explain why the logic is required, not merely what the code does.
- **Stack Over Heap**: Prefer stack-allocated fixed-size buffers over dynamic memory allocation (`malloc`/`free`) whenever the upper bound is small, fixed, and known at compile time.
- **Tag Escaping**: When emitting structured tags with `log_tag()`, always wrap file paths, directory paths, link targets, disk names, filter patterns, and arbitrary string fields with `esc_tag()` to prevent colons (e.g., Windows drive letters `C:`), backslashes, or newlines from breaking colon-delimited tag parsing.
- **Allocation**: Always use custom `malloc_nofail()`, `calloc_nofail()`, `nalloc_nofail()`, or `strdup_nofail()` wrappers (which handle OOM by aborting)
- **Path Manipulation**: Never use standard unsafe string functions (`strcpy`, `strcat`, `strcmp`) on paths. Always use the platform-correct, size-bounded wrappers in `support.h` (e.g., `pathcpy()`, `pathcat()`, `pathcmp()`, `pathslash()`).
- **TommyDS Iteration**: For `tommy_list`, iterate using:
- Run `./linux/snapraid test` for the regression test
- The `test` and `selftest` suites (in `cmdline/selftest.c` and `./linux/snapraid test`) must be strictly memory-only without creating files or performing filesystem I/O
- If running the speed benchmark (`./linux/snapraid -T`), always use `--speed-test-period 100` (e.g. `./linux/snapraid -T --speed-test-period 100`) to run it faster