readlink.go 984 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. //go:build linux || darwin
  2. // +build linux darwin
  3. package pathx
  4. import (
  5. "os"
  6. "path/filepath"
  7. )
  8. // ReadLink returns the destination of the named symbolic link recursively.
  9. func ReadLink(name string) (string, error) {
  10. name, err := filepath.Abs(name)
  11. if err != nil {
  12. return "", err
  13. }
  14. if _, err := os.Lstat(name); err != nil {
  15. return name, nil
  16. }
  17. // uncheck condition: ignore file path /var, maybe be temporary file path
  18. if name == "/" || name == "/var" {
  19. return name, nil
  20. }
  21. isLink, err := isLink(name)
  22. if err != nil {
  23. return "", err
  24. }
  25. if !isLink {
  26. dir, base := filepath.Split(name)
  27. dir = filepath.Clean(dir)
  28. dir, err := ReadLink(dir)
  29. if err != nil {
  30. return "", err
  31. }
  32. return filepath.Join(dir, base), nil
  33. }
  34. link, err := os.Readlink(name)
  35. if err != nil {
  36. return "", err
  37. }
  38. dir, base := filepath.Split(link)
  39. dir = filepath.Dir(dir)
  40. dir, err = ReadLink(dir)
  41. if err != nil {
  42. return "", err
  43. }
  44. return filepath.Join(dir, base), nil
  45. }