]> Cypherpunks repositories - gostls13.git/commitdiff
os: OS-dependent bits to support NetBSD.
authorChristopher Nielsen <m4dh4tt3r@gmail.com>
Thu, 15 Dec 2011 17:19:19 +0000 (12:19 -0500)
committerRuss Cox <rsc@golang.org>
Thu, 15 Dec 2011 17:19:19 +0000 (12:19 -0500)
R=golang-dev, jsing
CC=golang-dev
https://golang.org/cl/5482068

include/libc.h
src/libmach/netbsd.c [new file with mode: 0644]
src/pkg/net/fd_netbsd.go [new file with mode: 0644]
src/pkg/net/interface_netbsd.go [new file with mode: 0644]
src/pkg/net/tcpsock_posix.go
src/pkg/os/stat_netbsd.go [new file with mode: 0644]

index 0b50eb3c5fd6e37abf527f303ce4c9a2d17d17e9..b464cb4c63edb8c697c4e88b30c7b11686987a3d 100644 (file)
@@ -187,7 +187,7 @@ extern      void    sysfatal(char*, ...);
 #define DMWRITE                0x2             /* mode bit for write permission */
 #define DMEXEC         0x1             /* mode bit for execute permission */
 
-#ifdef RFMEM   /* FreeBSD, OpenBSD */
+#ifdef RFMEM   /* FreeBSD, OpenBSD, NetBSD */
 #undef RFFDG
 #undef RFNOTEG
 #undef RFPROC
diff --git a/src/libmach/netbsd.c b/src/libmach/netbsd.c
new file mode 100644 (file)
index 0000000..03e08d9
--- /dev/null
@@ -0,0 +1,46 @@
+// This is stubbed out for the moment. Will revisit when the time comes.
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <mach.h>
+
+int
+ctlproc(int pid, char *msg)
+{
+       sysfatal("ctlproc unimplemented in NetBSD");
+       return -1;
+}
+
+char*
+proctextfile(int pid)
+{
+       sysfatal("proctextfile unimplemented in NetBSD");
+       return nil;
+}
+
+char*
+procstatus(int pid)
+{
+       sysfatal("procstatus unimplemented in NetBSD");
+       return nil;
+}
+
+Map*
+attachproc(int pid, Fhdr *fp)
+{
+       sysfatal("attachproc unimplemented in NetBSD");
+       return nil;
+}
+
+void
+detachproc(Map *m)
+{
+       sysfatal("detachproc unimplemented in NetBSD");
+}
+
+int
+procthreadpids(int pid, int *p, int np)
+{
+       sysfatal("procthreadpids unimplemented in NetBSD");
+       return -1;
+}
diff --git a/src/pkg/net/fd_netbsd.go b/src/pkg/net/fd_netbsd.go
new file mode 100644 (file)
index 0000000..e52ac35
--- /dev/null
@@ -0,0 +1,115 @@
+// 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.
+
+// Waiting for FDs via kqueue/kevent.
+
+package net
+
+import (
+       "os"
+       "syscall"
+)
+
+type pollster struct {
+       kq       int
+       eventbuf [10]syscall.Kevent_t
+       events   []syscall.Kevent_t
+
+       // An event buffer for AddFD/DelFD.
+       // Must hold pollServer lock.
+       kbuf [1]syscall.Kevent_t
+}
+
+func newpollster() (p *pollster, err error) {
+       p = new(pollster)
+       if p.kq, err = syscall.Kqueue(); err != nil {
+               return nil, os.NewSyscallError("kqueue", err)
+       }
+       p.events = p.eventbuf[0:0]
+       return p, nil
+}
+
+func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, error) {
+       // pollServer is locked.
+
+       var kmode int
+       if mode == 'r' {
+               kmode = syscall.EVFILT_READ
+       } else {
+               kmode = syscall.EVFILT_WRITE
+       }
+       ev := &p.kbuf[0]
+       // EV_ADD - add event to kqueue list
+       // EV_ONESHOT - delete the event the first time it triggers
+       flags := syscall.EV_ADD
+       if !repeat {
+               flags |= syscall.EV_ONESHOT
+       }
+       syscall.SetKevent(ev, fd, kmode, flags)
+
+       n, e := syscall.Kevent(p.kq, p.kbuf[:], nil, nil)
+       if e != nil {
+               return false, os.NewSyscallError("kevent", e)
+       }
+       if n != 1 || (ev.Flags&syscall.EV_ERROR) == 0 || int(ev.Ident) != fd || int(ev.Filter) != kmode {
+               return false, os.NewSyscallError("kqueue phase error", e)
+       }
+       if ev.Data != 0 {
+               return false, syscall.Errno(int(ev.Data))
+       }
+       return false, nil
+}
+
+func (p *pollster) DelFD(fd int, mode int) {
+       // pollServer is locked.
+
+       var kmode int
+       if mode == 'r' {
+               kmode = syscall.EVFILT_READ
+       } else {
+               kmode = syscall.EVFILT_WRITE
+       }
+       ev := &p.kbuf[0]
+       // EV_DELETE - delete event from kqueue list
+       syscall.SetKevent(ev, fd, kmode, syscall.EV_DELETE)
+       syscall.Kevent(p.kq, p.kbuf[:], nil, nil)
+}
+
+func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err error) {
+       var t *syscall.Timespec
+       for len(p.events) == 0 {
+               if nsec > 0 {
+                       if t == nil {
+                               t = new(syscall.Timespec)
+                       }
+                       *t = syscall.NsecToTimespec(nsec)
+               }
+
+               s.Unlock()
+               nn, e := syscall.Kevent(p.kq, nil, p.eventbuf[:], t)
+               s.Lock()
+
+               if e != nil {
+                       if e == syscall.EINTR {
+                               continue
+                       }
+                       return -1, 0, os.NewSyscallError("kevent", e)
+               }
+               if nn == 0 {
+                       return -1, 0, nil
+               }
+               p.events = p.eventbuf[0:nn]
+       }
+       ev := &p.events[0]
+       p.events = p.events[1:]
+       fd = int(ev.Ident)
+       if ev.Filter == syscall.EVFILT_READ {
+               mode = 'r'
+       } else {
+               mode = 'w'
+       }
+       return fd, mode, nil
+}
+
+func (p *pollster) Close() error { return os.NewSyscallError("close", syscall.Close(p.kq)) }
diff --git a/src/pkg/net/interface_netbsd.go b/src/pkg/net/interface_netbsd.go
new file mode 100644 (file)
index 0000000..4150e9a
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2011 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.
+
+// Network interface identification for NetBSD
+
+package net
+
+// If the ifindex is zero, interfaceMulticastAddrTable returns
+// addresses for all network interfaces.  Otherwise it returns
+// addresses for a specific interface.
+func interfaceMulticastAddrTable(ifindex int) ([]Addr, error) {
+       return nil, nil
+}
index 44890ba66bb53391236128b78914ba8765efcdd2..a7c09c73ed5bd89ac7f49160a4f9a3834dfd545e 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin freebsd linux openbsd windows
+// +build darwin freebsd linux netbsd openbsd windows
 
 // TCP sockets
 
diff --git a/src/pkg/os/stat_netbsd.go b/src/pkg/os/stat_netbsd.go
new file mode 100644 (file)
index 0000000..66189a6
--- /dev/null
@@ -0,0 +1,56 @@
+// 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 os
+
+import (
+       "syscall"
+       "time"
+)
+
+func sameFile(fs1, fs2 *FileStat) bool {
+       sys1 := fs1.Sys.(*syscall.Stat_t)
+       sys2 := fs2.Sys.(*syscall.Stat_t)
+       return sys1.Dev == sys2.Dev && sys1.Ino == sys2.Ino
+}
+
+func fileInfoFromStat(st *syscall.Stat_t, name string) FileInfo {
+       fs := &FileStat{
+               name:    basename(name),
+               size:    int64(st.Size),
+               modTime: timespecToTime(st.Mtim),
+               Sys:     st,
+       }
+       fs.mode = FileMode(st.Mode & 0777)
+       switch st.Mode & syscall.S_IFMT {
+       case syscall.S_IFBLK, syscall.S_IFCHR:
+               fs.mode |= ModeDevice
+       case syscall.S_IFDIR:
+               fs.mode |= ModeDir
+       case syscall.S_IFIFO:
+               fs.mode |= ModeNamedPipe
+       case syscall.S_IFLNK:
+               fs.mode |= ModeSymlink
+       case syscall.S_IFREG:
+               // nothing to do
+       case syscall.S_IFSOCK:
+               fs.mode |= ModeSocket
+       }
+       if st.Mode&syscall.S_ISGID != 0 {
+               fs.mode |= ModeSetgid
+       }
+       if st.Mode&syscall.S_ISUID != 0 {
+               fs.mode |= ModeSetuid
+       }
+       return fs
+}
+
+func timespecToTime(ts syscall.Timespec) time.Time {
+       return time.Unix(int64(ts.Sec), int64(ts.Nsec))
+}
+
+// For testing.
+func atime(fi FileInfo) time.Time {
+       return timespecToTime(fi.(*FileStat).Sys.(*syscall.Stat_t).Atim)
+}