From aca44879d5644da7c5b8ec6a1115e9b6ea6c40d9 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 30 Jan 2019 11:46:27 +0100 Subject: [PATCH] unix: add ioctl wrappers to get and set RTC time on Linux Add IoctlGetRTCTime and IoctlSetRTCTime to get and set the RTC time via the RTC_RD_TIME and RTC_SET_TIME ioctls. Change-Id: I63190026be39746599c2cd7116603d4a1d5bd695 Reviewed-on: https://go-review.googlesource.com/c/160397 Run-TryBot: Tobias Klauser TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- unix/syscall_linux.go | 13 +++++++++++++ unix/syscall_linux_test.go | 15 +++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/unix/syscall_linux.go b/unix/syscall_linux.go index d82ab4b7..a07ee49e 100644 --- a/unix/syscall_linux.go +++ b/unix/syscall_linux.go @@ -14,6 +14,7 @@ package unix import ( "encoding/binary" "net" + "runtime" "syscall" "unsafe" ) @@ -80,6 +81,12 @@ func ioctlSetTermios(fd int, req uint, value *Termios) error { return ioctl(fd, req, uintptr(unsafe.Pointer(value))) } +func IoctlSetRTCTime(fd int, value *RTCTime) error { + err := ioctl(fd, RTC_SET_TIME, uintptr(unsafe.Pointer(value))) + runtime.KeepAlive(value) + return err +} + // IoctlGetInt performs an ioctl operation which gets an integer value // from fd, using the specified request number. func IoctlGetInt(fd int, req uint) (int, error) { @@ -100,6 +107,12 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { return &value, err } +func IoctlGetRTCTime(fd int) (*RTCTime, error) { + var value RTCTime + err := ioctl(fd, RTC_RD_TIME, uintptr(unsafe.Pointer(&value))) + return &value, err +} + //sys Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) func Link(oldpath string, newpath string) (err error) { diff --git a/unix/syscall_linux_test.go b/unix/syscall_linux_test.go index c7c6c058..3d2805bb 100644 --- a/unix/syscall_linux_test.go +++ b/unix/syscall_linux_test.go @@ -32,6 +32,21 @@ func TestIoctlGetInt(t *testing.T) { t.Logf("%d bits of entropy available", v) } +func TestIoctlGetRTCTime(t *testing.T) { + f, err := os.Open("/dev/rtc0") + if err != nil { + t.Skipf("skipping test, %v", err) + } + defer f.Close() + + v, err := unix.IoctlGetRTCTime(int(f.Fd())) + if err != nil { + t.Fatalf("failed to perform ioctl: %v", err) + } + + t.Logf("RTC time: %04d-%02d-%02d %02d:%02d:%02d", v.Year+1900, v.Mon+1, v.Mday, v.Hour, v.Min, v.Sec) +} + func TestPpoll(t *testing.T) { if runtime.GOOS == "android" { t.Skip("mkfifo syscall is not available on android, skipping test")