2018-02-05 16:05:59 -05:00
|
|
|
package system // import "github.com/docker/docker/pkg/system"
|
2015-10-01 13:45:32 -04:00
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
2022-01-26 08:44:54 -05:00
|
|
|
"syscall"
|
2015-10-01 13:45:32 -04:00
|
|
|
"time"
|
2022-01-26 08:44:54 -05:00
|
|
|
"unsafe"
|
2015-10-01 13:45:32 -04:00
|
|
|
)
|
|
|
|
|
2022-01-26 08:44:54 -05:00
|
|
|
// Used by Chtimes
|
|
|
|
var maxTime time.Time
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
if unsafe.Sizeof(syscall.Timespec{}.Nsec) == 8 {
|
|
|
|
// This is a 64 bit timespec
|
|
|
|
// os.Chtimes limits time to the following
|
pkg/system: add note about maxTime
This code caused me some head-scratches, and initially I wondered
if this was a bug, but it looks to be intentional to set nsec, not
sec, as time.Unix() internally divides nsec, and sets sec accordingly;
https://github.com/golang/go/blob/go1.19.2/src/time/time.go#L1364-L1380
// Unix returns the local Time corresponding to the given Unix time,
// sec seconds and nsec nanoseconds since January 1, 1970 UTC.
// It is valid to pass nsec outside the range [0, 999999999].
// Not all sec values have a corresponding time value. One such
// value is 1<<63-1 (the largest int64 value).
func Unix(sec int64, nsec int64) Time {
if nsec < 0 || nsec >= 1e9 {
n := nsec / 1e9
sec += n
nsec -= n * 1e9
if nsec < 0 {
nsec += 1e9
sec--
}
}
return unixTime(sec, int32(nsec))
}
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-01-26 09:36:49 -05:00
|
|
|
//
|
|
|
|
// Note that this intentionally sets nsec (not sec), which sets both sec
|
|
|
|
// and nsec internally in time.Unix();
|
|
|
|
// https://github.com/golang/go/blob/go1.19.2/src/time/time.go#L1364-L1380
|
2022-01-26 08:44:54 -05:00
|
|
|
maxTime = time.Unix(0, 1<<63-1)
|
|
|
|
} else {
|
|
|
|
// This is a 32 bit timespec
|
|
|
|
maxTime = time.Unix(1<<31-1, 0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-01 13:45:32 -04:00
|
|
|
// Chtimes changes the access time and modified time of a file at the given path
|
|
|
|
func Chtimes(name string, atime time.Time, mtime time.Time) error {
|
|
|
|
unixMinTime := time.Unix(0, 0)
|
2015-11-03 17:49:50 -05:00
|
|
|
unixMaxTime := maxTime
|
2015-10-01 13:45:32 -04:00
|
|
|
|
|
|
|
// If the modified time is prior to the Unix Epoch, or after the
|
|
|
|
// end of Unix Time, os.Chtimes has undefined behavior
|
|
|
|
// default to Unix Epoch in this case, just in case
|
|
|
|
|
|
|
|
if atime.Before(unixMinTime) || atime.After(unixMaxTime) {
|
|
|
|
atime = unixMinTime
|
|
|
|
}
|
|
|
|
|
|
|
|
if mtime.Before(unixMinTime) || mtime.After(unixMaxTime) {
|
|
|
|
mtime = unixMinTime
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := os.Chtimes(name, atime, mtime); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2016-02-08 18:40:12 -05:00
|
|
|
// Take platform specific action for setting create time.
|
2018-01-14 18:42:25 -05:00
|
|
|
return setCTime(name, mtime)
|
2015-10-01 13:45:32 -04:00
|
|
|
}
|