chtimes.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. package system // import "github.com/docker/docker/pkg/system"
  2. import (
  3. "os"
  4. "syscall"
  5. "time"
  6. "unsafe"
  7. )
  8. // Used by Chtimes
  9. var unixEpochTime, unixMaxTime time.Time
  10. func init() {
  11. unixEpochTime = time.Unix(0, 0)
  12. if unsafe.Sizeof(syscall.Timespec{}.Nsec) == 8 {
  13. // This is a 64 bit timespec
  14. // os.Chtimes limits time to the following
  15. //
  16. // Note that this intentionally sets nsec (not sec), which sets both sec
  17. // and nsec internally in time.Unix();
  18. // https://github.com/golang/go/blob/go1.19.2/src/time/time.go#L1364-L1380
  19. unixMaxTime = time.Unix(0, 1<<63-1)
  20. } else {
  21. // This is a 32 bit timespec
  22. unixMaxTime = time.Unix(1<<31-1, 0)
  23. }
  24. }
  25. // Chtimes changes the access time and modified time of a file at the given path.
  26. // If the modified time is prior to the Unix Epoch (unixMinTime), or after the
  27. // end of Unix Time (unixEpochTime), os.Chtimes has undefined behavior. In this
  28. // case, Chtimes defaults to Unix Epoch, just in case.
  29. func Chtimes(name string, atime time.Time, mtime time.Time) error {
  30. if atime.Before(unixEpochTime) || atime.After(unixMaxTime) {
  31. atime = unixEpochTime
  32. }
  33. if mtime.Before(unixEpochTime) || mtime.After(unixMaxTime) {
  34. mtime = unixEpochTime
  35. }
  36. if err := os.Chtimes(name, atime, mtime); err != nil {
  37. return err
  38. }
  39. // Take platform specific action for setting create time.
  40. return setCTime(name, mtime)
  41. }