devices_unix.go 1.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. // +build linux darwin freebsd solaris
  2. package devices
  3. import (
  4. "fmt"
  5. "os"
  6. "syscall"
  7. )
  8. func DeviceInfo(fi os.FileInfo) (uint64, uint64, error) {
  9. sys, ok := fi.Sys().(*syscall.Stat_t)
  10. if !ok {
  11. return 0, 0, fmt.Errorf("cannot extract device from os.FileInfo")
  12. }
  13. return getmajor(sys.Rdev), getminor(sys.Rdev), nil
  14. }
  15. // mknod provides a shortcut for syscall.Mknod
  16. func Mknod(p string, mode os.FileMode, maj, min int) error {
  17. var (
  18. m = syscallMode(mode.Perm())
  19. dev int
  20. )
  21. if mode&os.ModeDevice != 0 {
  22. dev = makedev(maj, min)
  23. if mode&os.ModeCharDevice != 0 {
  24. m |= syscall.S_IFCHR
  25. } else {
  26. m |= syscall.S_IFBLK
  27. }
  28. } else if mode&os.ModeNamedPipe != 0 {
  29. m |= syscall.S_IFIFO
  30. }
  31. return syscall.Mknod(p, m, dev)
  32. }
  33. // syscallMode returns the syscall-specific mode bits from Go's portable mode bits.
  34. func syscallMode(i os.FileMode) (o uint32) {
  35. o |= uint32(i.Perm())
  36. if i&os.ModeSetuid != 0 {
  37. o |= syscall.S_ISUID
  38. }
  39. if i&os.ModeSetgid != 0 {
  40. o |= syscall.S_ISGID
  41. }
  42. if i&os.ModeSticky != 0 {
  43. o |= syscall.S_ISVTX
  44. }
  45. return
  46. }