driver_unix.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // +build linux darwin freebsd solaris
  2. package driver
  3. import (
  4. "errors"
  5. "fmt"
  6. "os"
  7. "path/filepath"
  8. "sort"
  9. "github.com/containerd/continuity/devices"
  10. "github.com/containerd/continuity/sysx"
  11. )
  12. func (d *driver) Mknod(path string, mode os.FileMode, major, minor int) error {
  13. return devices.Mknod(path, mode, major, minor)
  14. }
  15. func (d *driver) Mkfifo(path string, mode os.FileMode) error {
  16. if mode&os.ModeNamedPipe == 0 {
  17. return errors.New("mode passed to Mkfifo does not have the named pipe bit set")
  18. }
  19. // mknod with a mode that has ModeNamedPipe set creates a fifo, not a
  20. // device.
  21. return devices.Mknod(path, mode, 0, 0)
  22. }
  23. // Lchmod changes the mode of an file not following symlinks.
  24. func (d *driver) Lchmod(path string, mode os.FileMode) (err error) {
  25. if !filepath.IsAbs(path) {
  26. path, err = filepath.Abs(path)
  27. if err != nil {
  28. return
  29. }
  30. }
  31. return sysx.Fchmodat(0, path, uint32(mode), sysx.AtSymlinkNofollow)
  32. }
  33. // Getxattr returns all of the extended attributes for the file at path p.
  34. func (d *driver) Getxattr(p string) (map[string][]byte, error) {
  35. xattrs, err := sysx.Listxattr(p)
  36. if err != nil {
  37. return nil, fmt.Errorf("listing %s xattrs: %v", p, err)
  38. }
  39. sort.Strings(xattrs)
  40. m := make(map[string][]byte, len(xattrs))
  41. for _, attr := range xattrs {
  42. value, err := sysx.Getxattr(p, attr)
  43. if err != nil {
  44. return nil, fmt.Errorf("getting %q xattr on %s: %v", attr, p, err)
  45. }
  46. // NOTE(stevvooe): This append/copy tricky relies on unique
  47. // xattrs. Break this out into an alloc/copy if xattrs are no
  48. // longer unique.
  49. m[attr] = append(m[attr], value...)
  50. }
  51. return m, nil
  52. }
  53. // Setxattr sets all of the extended attributes on file at path, following
  54. // any symbolic links, if necessary. All attributes on the target are
  55. // replaced by the values from attr. If the operation fails to set any
  56. // attribute, those already applied will not be rolled back.
  57. func (d *driver) Setxattr(path string, attrMap map[string][]byte) error {
  58. for attr, value := range attrMap {
  59. if err := sysx.Setxattr(path, attr, value, 0); err != nil {
  60. return fmt.Errorf("error setting xattr %q on %s: %v", attr, path, err)
  61. }
  62. }
  63. return nil
  64. }
  65. // LGetxattr returns all of the extended attributes for the file at path p
  66. // not following symbolic links.
  67. func (d *driver) LGetxattr(p string) (map[string][]byte, error) {
  68. xattrs, err := sysx.LListxattr(p)
  69. if err != nil {
  70. return nil, fmt.Errorf("listing %s xattrs: %v", p, err)
  71. }
  72. sort.Strings(xattrs)
  73. m := make(map[string][]byte, len(xattrs))
  74. for _, attr := range xattrs {
  75. value, err := sysx.LGetxattr(p, attr)
  76. if err != nil {
  77. return nil, fmt.Errorf("getting %q xattr on %s: %v", attr, p, err)
  78. }
  79. // NOTE(stevvooe): This append/copy tricky relies on unique
  80. // xattrs. Break this out into an alloc/copy if xattrs are no
  81. // longer unique.
  82. m[attr] = append(m[attr], value...)
  83. }
  84. return m, nil
  85. }
  86. // LSetxattr sets all of the extended attributes on file at path, not
  87. // following any symbolic links. All attributes on the target are
  88. // replaced by the values from attr. If the operation fails to set any
  89. // attribute, those already applied will not be rolled back.
  90. func (d *driver) LSetxattr(path string, attrMap map[string][]byte) error {
  91. for attr, value := range attrMap {
  92. if err := sysx.LSetxattr(path, attr, value, 0); err != nil {
  93. return fmt.Errorf("error setting xattr %q on %s: %v", attr, path, err)
  94. }
  95. }
  96. return nil
  97. }
  98. func (d *driver) DeviceInfo(fi os.FileInfo) (maj uint64, min uint64, err error) {
  99. return devices.DeviceInfo(fi)
  100. }
  101. // Readlink was forked on Windows to fix a Golang bug, use the "os" package here
  102. func (d *driver) Readlink(p string) (string, error) {
  103. return os.Readlink(p)
  104. }