]> Cypherpunks repositories - gostls13.git/commitdiff
time: fix Plan 9 build for new API
authorAnthony Martin <ality@pbrane.org>
Mon, 12 Dec 2011 21:12:22 +0000 (16:12 -0500)
committerRuss Cox <rsc@golang.org>
Mon, 12 Dec 2011 21:12:22 +0000 (16:12 -0500)
I had to move readFile into sys_$GOOS.go
since syscall.Open takes only two arguments
on Plan 9.

R=lucio.dere, rsc, alex.brainman
CC=golang-dev
https://golang.org/cl/5447061

src/pkg/runtime/plan9/thread.c
src/pkg/time/Makefile
src/pkg/time/sleep.go
src/pkg/time/sys.go [deleted file]
src/pkg/time/sys_plan9.go
src/pkg/time/sys_unix.go
src/pkg/time/zoneinfo_plan9.go

index 87ea8a23634ecfc9f8b5eca062cefd204cb25e43..07edb717e45fc0354a467ef03b8e86dce039e8c0 100644 (file)
@@ -97,6 +97,18 @@ runtime·nanotime(void)
        return (int64)hi<<32 | (int64)lo;
 }
 
+void
+time·now(int64 sec, int32 nsec)
+{
+       int64 ns;
+
+       ns = runtime·nanotime();
+       sec = ns / 1000000000LL;
+       nsec = ns - sec * 1000000000LL;
+       FLUSH(&sec);
+       FLUSH(&nsec);
+}
+
 extern Tos *_tos;
 void
 runtime·exit(int32)
index 28c6afc537997f852565067b732847f521dfde42..9f61329d381bf81a198a62d0e13db6599ded4bbd 100644 (file)
@@ -8,7 +8,6 @@ TARG=time
 GOFILES=\
        format.go\
        sleep.go\
-       sys.go\
        tick.go\
        time.go\
        zoneinfo.go\
index 844d964d5a02236959a66ca43a9425a40ac308f8..b4680db2387e9dd008326949e15ad5aa4511d3eb 100644 (file)
@@ -4,6 +4,9 @@
 
 package time
 
+// Sleep pauses the current goroutine for the duration d.
+func Sleep(d Duration)
+
 func nano() int64 {
        sec, nsec := now()
        return sec*1e9 + int64(nsec)
diff --git a/src/pkg/time/sys.go b/src/pkg/time/sys.go
deleted file mode 100644 (file)
index fe6bc27..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package time
-
-import "syscall"
-
-// Sleep pauses the current goroutine for the duration d.
-func Sleep(d Duration)
-
-// readFile reads and returns the content of the named file.
-// It is a trivial implementation of ioutil.ReadFile, reimplemented
-// here to avoid depending on io/ioutil or os.
-func readFile(name string) ([]byte, error) {
-       f, err := syscall.Open(name, syscall.O_RDONLY, 0)
-       if err != nil {
-               return nil, err
-       }
-       defer syscall.Close(f)
-       var (
-               buf [4096]byte
-               ret []byte
-               n   int
-       )
-       for {
-               n, err = syscall.Read(f, buf[:])
-               if n > 0 {
-                       ret = append(ret, buf[:n]...)
-               }
-               if n == 0 || err != nil {
-                       break
-               }
-       }
-       return ret, err
-}
index e58fb519ea32e5c22065a2a551213d00e2e6cdd4..c7cfa792a29f3c717b8dc159e31980ddc27b846d 100644 (file)
@@ -2,9 +2,39 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// +build plan9
+
 package time
 
+import "syscall"
+
 // for testing: whatever interrupts a sleep
 func interrupt() {
        // cannot predict pid, don't want to kill group
 }
+
+// readFile reads and returns the content of the named file.
+// It is a trivial implementation of ioutil.ReadFile, reimplemented
+// here to avoid depending on io/ioutil or os.
+func readFile(name string) ([]byte, error) {
+       f, err := syscall.Open(name, syscall.O_RDONLY)
+       if err != nil {
+               return nil, err
+       }
+       defer syscall.Close(f)
+       var (
+               buf [4096]byte
+               ret []byte
+               n   int
+       )
+       for {
+               n, err = syscall.Read(f, buf[:])
+               if n > 0 {
+                       ret = append(ret, buf[:n]...)
+               }
+               if n == 0 || err != nil {
+                       break
+               }
+       }
+       return ret, err
+}
index 715d186be17fc72ac5130e30193164fdcced4ae7..55ae5f7da289b5854f639847de2c0612324c1842 100644 (file)
@@ -12,3 +12,29 @@ import "syscall"
 func interrupt() {
        syscall.Kill(syscall.Getpid(), syscall.SIGCHLD)
 }
+
+// readFile reads and returns the content of the named file.
+// It is a trivial implementation of ioutil.ReadFile, reimplemented
+// here to avoid depending on io/ioutil or os.
+func readFile(name string) ([]byte, error) {
+       f, err := syscall.Open(name, syscall.O_RDONLY, 0)
+       if err != nil {
+               return nil, err
+       }
+       defer syscall.Close(f)
+       var (
+               buf [4096]byte
+               ret []byte
+               n   int
+       )
+       for {
+               n, err = syscall.Read(f, buf[:])
+               if n > 0 {
+                       ret = append(ret, buf[:n]...)
+               }
+               if n == 0 || err != nil {
+                       break
+               }
+       }
+       return ret, err
+}
index 38aefc7a977c729b1d2eb6265cbf02b26dcea09e..9c052d42cd32376b2aa4dfdb58adbbb2e360558e 100644 (file)
 
 package time
 
-//import (
-//     "strconv"
-//     "strings"
-//)
+import (
+       "errors"
+       "syscall"
+)
 
-func parseZones(s string) (zt []zonetime) {
-       f := strings.Fields(s)
+var badData = errors.New("malformed time zone information")
+
+func isSpace(r rune) bool {
+       return r == ' ' || r == '\t' || r == '\n'
+}
+
+// Copied from strings to avoid a dependency.
+func fields(s string) []string {
+       // First count the fields.
+       n := 0
+       inField := false
+       for _, rune := range s {
+               wasInField := inField
+               inField = !isSpace(rune)
+               if inField && !wasInField {
+                       n++
+               }
+       }
+
+       // Now create them.
+       a := make([]string, n)
+       na := 0
+       fieldStart := -1 // Set to -1 when looking for start of field.
+       for i, rune := range s {
+               if isSpace(rune) {
+                       if fieldStart >= 0 {
+                               a[na] = s[fieldStart:i]
+                               na++
+                               fieldStart = -1
+                       }
+               } else if fieldStart == -1 {
+                       fieldStart = i
+               }
+       }
+       if fieldStart >= 0 { // Last field might end at EOF.
+               a[na] = s[fieldStart:]
+       }
+       return a
+}
+
+func loadZoneData(s string) (l *Location, err error) {
+       f := fields(s)
        if len(f) < 4 {
-               return
+               if len(f) == 2 && f[0] == "GMT" {
+                       return UTC, nil
+               }
+               return nil, badData
        }
 
+       var zones [2]zone
+
        // standard timezone offset
-       o, err := strconv.Atoi(f[1])
+       o, err := atoi(f[1])
        if err != nil {
-               return
+               return nil, badData
        }
-       std := &zone{name: f[0], utcoff: o, isdst: false}
+       zones[0] = zone{name: f[0], offset: o, isDST: false}
 
        // alternate timezone offset
-       o, err = strconv.Atoi(f[3])
+       o, err = atoi(f[3])
        if err != nil {
-               return
+               return nil, badData
        }
-       dst := &zone{name: f[2], utcoff: o, isdst: true}
+       zones[1] = zone{name: f[2], offset: o, isDST: true}
 
        // transition time pairs
+       var tx []zoneTrans
        f = f[4:]
        for i := 0; i < len(f); i++ {
-               z := std
+               zi := 0
                if i%2 == 0 {
-                       z = dst
+                       zi = 1
                }
-               t, err := strconv.Atoi(f[i])
+               t, err := atoi(f[i])
                if err != nil {
-                       return nil
+                       return nil, badData
                }
-               t -= std.utcoff
-               zt = append(zt, zonetime{time: int32(t), zone: z})
+               t -= zones[0].offset
+               tx = append(tx, zoneTrans{when: int64(t), index: uint8(zi)})
        }
-       return
+
+       // Committed to succeed.
+       l = &Location{zone: zones[:], tx: tx}
+
+       // Fill in the cache with information about right now,
+       // since that will be the most common lookup.
+       sec, _ := now()
+       for i := range tx {
+               if tx[i].when <= sec && (i+1 == len(tx) || sec < tx[i+1].when) {
+                       l.cacheStart = tx[i].when
+                       l.cacheEnd = 1<<63 - 1
+                       if i+1 < len(tx) {
+                               l.cacheEnd = tx[i+1].when
+                       }
+                       l.cacheZone = &l.zone[tx[i].index]
+               }
+       }
+
+       return l, nil
 }
 
-func initLocal() {
-       t, err := os.Getenverror("timezone")
+func loadZoneFile(name string) (*Location, error) {
+       b, err := readFile(name)
        if err != nil {
-               // do nothing: use UTC
-               return
+               return nil, err
        }
-       zones = parseZones(t)
+       return loadZoneData(string(b))
 }
 
 func initTestingZone() {
-       buf, err := readFile("/adm/timezone/US_Pacific")
-       if err != nil {
+       if z, err := loadZoneFile("/adm/timezone/US_Pacific"); err == nil {
+               localLoc = *z
                return
        }
-       zones = parseZones(string(buf))
+
+       // Fall back to UTC.
+       localLoc.name = "UTC"
+}
+
+func initLocal() {
+       t, ok := syscall.Getenv("timezone")
+       if ok {
+               if z, err := loadZoneData(t); err == nil {
+                       localLoc = *z
+                       return
+               }
+       } else {
+               if z, err := loadZoneFile("/adm/timezone/local"); err == nil {
+                       localLoc = *z
+                       localLoc.name = "Local"
+                       return
+               }
+       }
+
+       // Fall back to UTC.
+       localLoc.name = "UTC"
+}
+
+func loadLocation(name string) (*Location, error) {
+       if z, err := loadZoneFile("/adm/timezone/" + name); err == nil {
+               return z, nil
+       }
+       return nil, errors.New("unknown time zone " + name)
 }