summaryrefslogtreecommitdiff
path: root/internal/file/hardlink.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/file/hardlink.go')
-rw-r--r--internal/file/hardlink.go59
1 files changed, 0 insertions, 59 deletions
diff --git a/internal/file/hardlink.go b/internal/file/hardlink.go
deleted file mode 100644
index 8913674..0000000
--- a/internal/file/hardlink.go
+++ /dev/null
@@ -1,59 +0,0 @@
-package file
-
-import (
- "fmt"
- "log"
- "os"
- "syscall"
-)
-
-// haveHardlink ensures f.path is a hard link to f.hardlinkTarget.
-//
-// Idempotency and clobber policy:
-// - already the same inode as the target: nothing to do.
-// - a different file/link is in the way: it is renamed to "<path>.old"
-// before the link is created (matching the symlink resource's behavior).
-func (f *File) haveHardlink() error {
- log.Printf("processing hardlink: %s -> %s", f.path, f.hardlinkTarget)
-
- if f.hardlinkTarget == "" {
- return fmt.Errorf("hardlink %s has no target", f.path)
- }
-
- targetInfo, err := os.Stat(f.hardlinkTarget)
- if err != nil {
- return fmt.Errorf("failed to stat hardlink target %s: %w", f.hardlinkTarget, err)
- }
-
- if info, err := os.Lstat(f.path); err == nil {
- if sameInode(info, targetInfo) {
- log.Printf("hardlink %s already links to %s", f.path, f.hardlinkTarget)
- return nil
- }
- old := f.path + ".old"
- log.Printf("%s already exists, renaming to %s", f.path, old)
- if err := os.Rename(f.path, old); err != nil {
- return fmt.Errorf("failed to move existing %s aside: %w", f.path, err)
- }
- } else if !os.IsNotExist(err) {
- return fmt.Errorf("failed to stat %s: %w", f.path, err)
- }
-
- if err := os.Link(f.hardlinkTarget, f.path); err != nil {
- return fmt.Errorf("failed to create hardlink %s -> %s: %w", f.path, f.hardlinkTarget, err)
- }
-
- log.Printf("created hardlink %s -> %s", f.path, f.hardlinkTarget)
- return nil
-}
-
-// sameInode reports whether two FileInfos refer to the same underlying inode
-// (same device and inode number), i.e. they are already hard-linked.
-func sameInode(a, b os.FileInfo) bool {
- as, aok := a.Sys().(*syscall.Stat_t)
- bs, bok := b.Sys().(*syscall.Stat_t)
- if !aok || !bok {
- return false
- }
- return as.Dev == bs.Dev && as.Ino == bs.Ino
-}