All checks were successful
check / check (pull_request) Successful in 2m27s
Replace the mtime fallback for ctime in the scanner with platform-specific implementations that extract the real ctime from syscall.Stat_t: - macOS/Darwin: uses Birthtimespec (file birth/creation time) - Linux: uses Ctim (inode change time) - Falls back to mtime when syscall stats are unavailable (e.g. afero.MemMapFs) Also: - Document platform-specific ctime semantics in README - Document ctime restore limitations (cannot be set on either platform) - Add ctime field documentation to File model - Update README files table schema to match actual schema (adds ctime, source_path, link_target columns) - Add comprehensive tests for fileCTime on real files and mock FileInfo closes #13
29 lines
894 B
Go
29 lines
894 B
Go
package snapshot
|
|
|
|
import (
|
|
"os"
|
|
"syscall"
|
|
"time"
|
|
)
|
|
|
|
// fileCTime returns the inode change time on Linux.
|
|
//
|
|
// On Linux, "ctime" refers to the inode change time — the last time the
|
|
// file's metadata (permissions, ownership, link count, etc.) was modified.
|
|
// This is NOT the file creation time; Linux did not expose birth time until
|
|
// the statx(2) syscall was added in kernel 4.11, and Go's syscall package
|
|
// does not yet surface it.
|
|
//
|
|
// This differs from macOS/Darwin where "ctime" means birth time (file
|
|
// creation time). See ctime_darwin.go for details.
|
|
//
|
|
// If the underlying stat information is unavailable (e.g. when using a
|
|
// virtual filesystem like afero.MemMapFs), this falls back to mtime.
|
|
func fileCTime(info os.FileInfo) time.Time {
|
|
stat, ok := info.Sys().(*syscall.Stat_t)
|
|
if !ok {
|
|
return info.ModTime()
|
|
}
|
|
return time.Unix(stat.Ctim.Sec, stat.Ctim.Nsec).UTC()
|
|
}
|