Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions src/os/chtimes_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//go:build !baremetal && !nintendoswitch && !wasip1 && !wasm_unknown && !wasip2

package os

import (
"syscall"
"time"
)

// See https://github.com/torvalds/linux/blob/master/include/linux/stat.h
const _UTIME_OMIT = (1 << 30) - 2

// Chtimes changes the access and modification times of the named file.
func Chtimes(name string, atime time.Time, mtime time.Time) error {
var utimes [2]syscall.Timespec
set := func(i int, t time.Time) {
if t.IsZero() {
utimes[i] = syscall.Timespec{Sec: _UTIME_OMIT, Nsec: _UTIME_OMIT}
} else {
utimes[i] = syscall.NsecToTimespec(t.UnixNano())
}
}
set(0, atime)
set(1, mtime)
if e := syscall.UtimesNano(fixLongPath(name), utimes[0:]); e != nil {
return &PathError{Op: "chtimes", Path: name, Err: e}
}
return nil
}
42 changes: 42 additions & 0 deletions src/os/chtimes_linux_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//go:build !baremetal && !nintendoswitch && !wasip1 && !wasm_unknown && !wasip2

package os_test

import (
"os"
"path/filepath"
"testing"
"time"
)

func TestChtimes(t *testing.T) {
path := filepath.Join(t.TempDir(), "file.txt")
if err := os.WriteFile(path, []byte("hello"), 0o600); err != nil {
t.Fatal(err)
}

wantMtime := time.Date(2025, 3, 15, 12, 30, 45, 0, time.UTC)
if err := os.Chtimes(path, wantMtime, wantMtime); err != nil {
t.Fatalf("Chtimes failed: %v", err)
}

fi, err := os.Stat(path)
if err != nil {
t.Fatal(err)
}
if !fi.ModTime().Equal(wantMtime) {
t.Errorf("ModTime() = %v, want %v", fi.ModTime(), wantMtime)
}

// Zero time.Time should leave the modification time unchanged.
if err := os.Chtimes(path, time.Time{}, time.Time{}); err != nil {
t.Fatalf("Chtimes with zero times failed: %v", err)
}
fi, err = os.Stat(path)
if err != nil {
t.Fatal(err)
}
if !fi.ModTime().Equal(wantMtime) {
t.Errorf("ModTime() after zero Chtimes = %v, want %v", fi.ModTime(), wantMtime)
}
}
10 changes: 10 additions & 0 deletions src/os/chtimes_other.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//go:build !linux || baremetal || nintendoswitch || wasip1 || wasm_unknown || wasip2

package os

import "time"

// Chtimes is a stub on non-Linux targets.
func Chtimes(name string, atime time.Time, mtime time.Time) error {
return ErrNotImplemented
}
5 changes: 0 additions & 5 deletions src/os/file_posix.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@ import (

//TODO: re-implement the ErrNoDeadline error in the correct code path

// Chtimes is a stub, not yet implemented
func Chtimes(name string, atime time.Time, mtime time.Time) error {
return ErrNotImplemented
}

// setDeadline sets the read and write deadline.
func (f *File) setDeadline(t time.Time) error {
if t.IsZero() {
Expand Down
Loading