Files
wehub-resource-sync 36b3af2e3d
PR Check / Code Quality: Format (push) Failing after 1s
PR Check / Code Quality: Lint (darwin) (push) Failing after 0s
PR Check / Code Quality: Lint (freebsd) (push) Failing after 1s
PR Check / Code Quality: Lint (windows) (push) Failing after 1s
PR Check / Code Quality: Lint (linux) (push) Failing after 1s
PR Check / Security: Vulnerability Scan (push) Failing after 0s
Update Documentation / update-docs (push) Failing after 2s
PR Check / Code Quality: Vendor (push) Failing after 1s
PR Check / Code Quality: Coverage (push) Failing after 0s
PR Check / Tests: Unit (macos-latest) (push) Has been cancelled
PR Check / Tests: Unit (ubuntu-24.04) (push) Has been cancelled
PR Check / Tests: Unit (ubuntu-24.04-arm) (push) Has been cancelled
PR Check / Tests: Unit (windows-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:22:06 +08:00

63 lines
1.1 KiB
Go

package target
import (
"fmt"
"os"
"path/filepath"
"strconv"
)
// ResolveFile finds processes holding a lock on the given file path
func ResolveFile(path string) ([]int, error) {
absPath, err := filepath.Abs(path)
if err != nil {
return nil, err
}
realPath, err := filepath.EvalSymlinks(absPath)
if err != nil {
realPath = absPath
}
var pids []int
procDirs, err := os.ReadDir("/proc")
if err != nil {
return nil, fmt.Errorf("failed to read /proc: %w", err)
}
for _, d := range procDirs {
if !d.IsDir() {
continue
}
pid, err := strconv.Atoi(d.Name())
if err != nil {
continue
}
fdDir := filepath.Join("/proc", d.Name(), "fd")
fds, err := os.ReadDir(fdDir)
if err != nil {
continue
}
for _, fd := range fds {
linkPath, err := os.Readlink(filepath.Join(fdDir, fd.Name()))
if err != nil {
continue
}
if linkPath == realPath || linkPath == absPath {
pids = append(pids, pid)
break
}
}
}
if len(pids) == 0 {
return nil, fmt.Errorf("no process found holding file: %s", absPath)
}
return pids, nil
}