From 1afa2a1b2dc0802fa4e92c81e40324a4b436d94c Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Wed, 19 May 2010 17:48:53 -0700 Subject: [PATCH] os: add Chtimes function R=rsc, r CC=golang-dev https://golang.org/cl/1103041 --- src/pkg/os/file.go | 16 ++++++++++++++++ src/pkg/os/os_test.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/src/pkg/os/file.go b/src/pkg/os/file.go index ccecf67edae..3196406d608 100644 --- a/src/pkg/os/file.go +++ b/src/pkg/os/file.go @@ -407,3 +407,19 @@ func (f *File) Truncate(size int64) Error { } return nil } + +// Chtimes changes the access and modification times of the named +// file, similar to the Unix utime() or utimes() functions. +// +// The argument times are in nanoseconds, although the underlying +// filesystem may truncate or round the values to a more +// coarse time unit. +func Chtimes(name string, atime_ns int64, mtime_ns int64) Error { + var utimes [2]syscall.Timeval + utimes[0] = syscall.NsecToTimeval(atime_ns) + utimes[1] = syscall.NsecToTimeval(mtime_ns) + if e := syscall.Utimes(name, &utimes); e != 0 { + return &PathError{"chtimes", name, Errno(e)} + } + return nil +} diff --git a/src/pkg/os/os_test.go b/src/pkg/os/os_test.go index 5fb599265ea..b2332f0c8f8 100644 --- a/src/pkg/os/os_test.go +++ b/src/pkg/os/os_test.go @@ -483,6 +483,48 @@ func TestTruncate(t *testing.T) { Remove(Path) } +func TestChtimes(t *testing.T) { + MkdirAll("_obj", 0777) + const Path = "_obj/_TestChtimes_" + fd, err := Open(Path, O_WRONLY|O_CREAT, 0666) + if err != nil { + t.Fatalf("create %s: %s", Path, err) + } + fd.Write([]byte("hello, world\n")) + fd.Close() + + preStat, err := Stat(Path) + if err != nil { + t.Fatalf("Stat %s: %s", Path, err) + } + + // Move access and modification time back a second + const OneSecond = 1e9 // in nanoseconds + err = Chtimes(Path, preStat.Atime_ns-OneSecond, preStat.Mtime_ns-OneSecond) + if err != nil { + t.Fatalf("Chtimes %s: %s", Path, err) + } + + postStat, err := Stat(Path) + if err != nil { + t.Fatalf("second Stat %s: %s", Path, err) + } + + if postStat.Atime_ns >= preStat.Atime_ns { + t.Errorf("Atime_ns didn't go backwards; was=%d, after=%d", + preStat.Atime_ns, + postStat.Atime_ns) + } + + if postStat.Mtime_ns >= preStat.Mtime_ns { + t.Errorf("Mtime_ns didn't go backwards; was=%d, after=%d", + preStat.Mtime_ns, + postStat.Mtime_ns) + } + + Remove(Path) +} + func TestChdirAndGetwd(t *testing.T) { fd, err := Open(".", O_RDONLY, 0) if err != nil {