Redesign FILE ccache I/O handling

These four commits implement a new design for FILE ccache I/O, based partly on past discussions with Nico.  Benefits of the new design include:

* About a 30% reduction in lines of code.
* Callers don't have to mess around with flags when iterating over a cache.
* RT issue #7804 is fixed; one thread iterating over a ccache will not cause another thread's store operation to fail.
* If a cache file is replaced (by kinit or whatever), iterators will always continue iterating over the old cache, and will never try to open and seek into the new one.
* If OFD locks are unavailable on the platform and regular POSIX locks are prematurely removed due to their poor semantics, the use of O_APPEND writes should almost always avoid corruption and race issues.

The fourth commit is a bit dense, as I couldn't find a way to decompose it any further.