// mmap memory maps a DB's data file. // Based on: https://github.com/edsrzf/mmap-go func mmap(db *DB, sz int) error { if !db.readOnly { // Truncate the database to the size of the mmap. if err := db.file.Truncate(int64(sz)); err != nil { return fmt.Errorf("truncate: %s", err) } } // Open a file mapping handle. sizelo := uint32(sz >> 32) sizehi := uint32(sz) & 0xffffffff h, errno := syscall.CreateFileMapping(syscall.Handle(db.file.Fd()), nil, syscall.PAGE_READONLY, sizelo, sizehi, nil) if h == 0 { return os.NewSyscallError("CreateFileMapping", errno) } // Create the memory map. addr, errno := syscall.MapViewOfFile(h, syscall.FILE_MAP_READ, 0, 0, uintptr(sz)) if addr == 0 { return os.NewSyscallError("MapViewOfFile", errno) } // Close mapping handle. if err := syscall.CloseHandle(syscall.Handle(h)); err != nil { return os.NewSyscallError("CloseHandle", err) } // Convert to a byte array. db.data = ((*[maxMapSize]byte)(unsafe.Pointer(addr))) db.datasz = sz return nil }
func setDefaultSockopts(s, f, t int) error { switch f { case syscall.AF_INET6: // Allow both IP versions even if the OS default is otherwise. // Note that some operating systems never admit this option. syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 0) } if f == syscall.AF_UNIX || (f == syscall.AF_INET || f == syscall.AF_INET6) && t == syscall.SOCK_STREAM { // Allow reuse of recently-used addresses. err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1) if err != nil { return os.NewSyscallError("setsockopt", err) } } // Allow broadcast. err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1) if err != nil { return os.NewSyscallError("setsockopt", err) } return nil }
// 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, os.Error) { var ( tab []byte e int msgs []syscall.RoutingMessage ifmat []Addr ) tab, e = syscall.RouteRIB(syscall.NET_RT_IFLIST2, ifindex) if e != 0 { return nil, os.NewSyscallError("route rib", e) } msgs, e = syscall.ParseRoutingMessage(tab) if e != 0 { return nil, os.NewSyscallError("route message", e) } for _, m := range msgs { switch v := m.(type) { case *syscall.InterfaceMulticastAddrMessage: if ifindex == 0 || ifindex == int(v.Header.Index) { ifma, err := newMulticastAddr(v) if err != nil { return nil, err } ifmat = append(ifmat, ifma...) } } } return ifmat, nil }
// If the ifindex is zero, interfaceTable returns mappings of all // network interfaces. Otheriwse it returns a mapping of a specific // interface. func interfaceTable(ifindex int) ([]Interface, error) { tab, err := syscall.NetlinkRIB(syscall.RTM_GETLINK, syscall.AF_UNSPEC) if err != nil { return nil, os.NewSyscallError("netlink rib", err) } msgs, err := syscall.ParseNetlinkMessage(tab) if err != nil { return nil, os.NewSyscallError("netlink message", err) } var ift []Interface for _, m := range msgs { switch m.Header.Type { case syscall.NLMSG_DONE: goto done case syscall.RTM_NEWLINK: ifim := (*syscall.IfInfomsg)(unsafe.Pointer(&m.Data[0])) if ifindex == 0 || ifindex == int(ifim.Index) { attrs, err := syscall.ParseNetlinkRouteAttr(&m) if err != nil { return nil, os.NewSyscallError("netlink routeattr", err) } ifi := newLink(ifim, attrs) ift = append(ift, ifi) } } } done: return ift, nil }
func (c *CloneParams) CloneFrozen() (int, error) { pid := callClone(c) // TODO: clone errors? c.CommWriter.Close() c.stdhandles.Close() c.comm = make(chan CommStatus) go commReader(c.CommReader, c.comm) var status syscall.WaitStatus for { wpid, err := syscall.Wait4(pid, &status, 0, nil) // TODO: rusage if err != nil { return -1, os.NewSyscallError("Wait4", err) } if wpid == pid { break } } if status.Stopped() && status.StopSignal() == syscall.SIGTRAP { return pid, nil } if status.Exited() { co, ok := <-c.comm if ok { return -1, childError(co) } return -1, fmt.Errorf("DAFUQ") } err := syscall.Kill(pid, syscall.SIGKILL) if err != nil { return -1, os.NewSyscallError("Kill", err) } return -1, fmt.Errorf("traps, signals, dafuq is this") }
func newLookupPort(network, service string) (port int, err error) { acquireThread() defer releaseThread() var stype int32 switch network { case "tcp4", "tcp6": stype = syscall.SOCK_STREAM case "udp4", "udp6": stype = syscall.SOCK_DGRAM } hints := syscall.AddrinfoW{ Family: syscall.AF_UNSPEC, Socktype: stype, Protocol: syscall.IPPROTO_IP, } var result *syscall.AddrinfoW e := syscall.GetAddrInfoW(nil, syscall.StringToUTF16Ptr(service), &hints, &result) if e != nil { return 0, os.NewSyscallError("GetAddrInfoW", e) } defer syscall.FreeAddrInfoW(result) if result == nil { return 0, os.NewSyscallError("LookupPort", syscall.EINVAL) } addr := unsafe.Pointer(result.Addr) switch result.Family { case syscall.AF_INET: a := (*syscall.RawSockaddrInet4)(addr) return int(syscall.Ntohs(a.Port)), nil case syscall.AF_INET6: a := (*syscall.RawSockaddrInet6)(addr) return int(syscall.Ntohs(a.Port)), nil } return 0, os.NewSyscallError("LookupPort", syscall.EINVAL) }
// munmap Windows implementation // Based on: https://github.com/edsrzf/mmap-go // Based on: https://github.com/boltdb/bolt/bolt_windows.go func munmap(b []byte) (err error) { handleLock.Lock() defer handleLock.Unlock() addr := (uintptr)(unsafe.Pointer(&b[0])) if err := syscall.UnmapViewOfFile(addr); err != nil { return os.NewSyscallError("UnmapViewOfFile", err) } handle, ok := handleMap[addr] if !ok { // should be impossible; we would've seen the error above return errors.New("unknown base address") } delete(handleMap, addr) e := syscall.CloseHandle(syscall.Handle(handle)) if e != nil { return os.NewSyscallError("CloseHandle", e) } file, ok := fileMap[addr] if !ok { // should be impossible; we would've seen the error above return errors.New("unknown base address") } delete(fileMap, addr) e = file.Close() if e != nil { return errors.New("close file" + e.Error()) } return nil }
// Must run within the I/O thread. func (w *Watcher) startRead(watch *watch) error { if e := syscall.CancelIo(watch.ino.handle); e != nil { w.Error <- os.NewSyscallError("CancelIo", e) w.deleteWatch(watch) } mask := toWindowsFlags(watch.mask) for _, m := range watch.names { mask |= toWindowsFlags(m) } if mask == 0 { if e := syscall.CloseHandle(watch.ino.handle); e != nil { w.Error <- os.NewSyscallError("CloseHandle", e) } delete(w.watches[watch.ino.volume], watch.ino.index) return nil } e := syscall.ReadDirectoryChanges(watch.ino.handle, &watch.buf[0], uint32(unsafe.Sizeof(watch.buf)), false, mask, nil, &watch.ov, 0) if e != nil { err := os.NewSyscallError("ReadDirectoryChanges", e) if e == syscall.ERROR_ACCESS_DENIED && watch.mask&provisional == 0 { // Watched directory was probably removed if w.sendEvent(watch.path, watch.mask&FS_DELETE_SELF) { if watch.mask&FS_ONESHOT != 0 { watch.mask = 0 } } err = nil } w.deleteWatch(watch) w.startRead(watch) return err } return nil }
func getIno(path string) (ino *inode, err error) { pathp, e := syscall.UTF16PtrFromString(path) if e != nil { return nil, e } h, e := syscall.CreateFile(pathp, syscall.FILE_LIST_DIRECTORY, syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS|syscall.FILE_FLAG_OVERLAPPED, 0) if e != nil { return nil, os.NewSyscallError("CreateFile", e) } var fi syscall.ByHandleFileInformation if e = syscall.GetFileInformationByHandle(h, &fi); e != nil { syscall.CloseHandle(h) return nil, os.NewSyscallError("GetFileInformationByHandle", e) } ino = &inode{ handle: h, volume: fi.VolumeSerialNumber, index: uint64(fi.FileIndexHigh)<<32 | uint64(fi.FileIndexLow), } return ino, nil }
func setDefaultSockopts(s, f, t int) error { switch f { case syscall.AF_INET6: // Allow both IP versions even if the OS default is otherwise. // Note that some operating systems never admit this option. syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 0) } if f == syscall.AF_UNIX || (f == syscall.AF_INET || f == syscall.AF_INET6) && t == syscall.SOCK_STREAM { // Allow reuse of recently-used addresses. err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1) if err != nil { return os.NewSyscallError("setsockopt", err) } // Allow reuse of recently-used ports. // This option is supported only in descendants of 4.4BSD, // to make an effective multicast application and an application // that requires quick draw possible. err = syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEPORT, 1) if err != nil { return os.NewSyscallError("setsockopt", err) } } // Allow broadcast. err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1) if err != nil { return os.NewSyscallError("setsockopt", err) } return nil }
// Wrapper around the accept system call that marks the returned file // descriptor as nonblocking and close-on-exec. func accept(s int) (int, syscall.Sockaddr, error) { ns, sa, err := accept4Func(s, syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC) // On Linux the accept4 system call was introduced in 2.6.28 // kernel and on FreeBSD it was introduced in 10 kernel. If we // get an ENOSYS error on both Linux and FreeBSD, or EINVAL // error on Linux, fall back to using accept. switch err { case nil: return ns, sa, nil default: // errors other than the ones listed return -1, sa, os.NewSyscallError("accept4", err) case syscall.ENOSYS: // syscall missing case syscall.EINVAL: // some Linux use this instead of ENOSYS case syscall.EACCES: // some Linux use this instead of ENOSYS case syscall.EFAULT: // some Linux use this instead of ENOSYS } // See ../syscall/exec_unix.go for description of ForkLock. // It is probably okay to hold the lock across syscall.Accept // because we have put fd.sysfd into non-blocking mode. // However, a call to the File method will put it back into // blocking mode. We can't take that risk, so no use of ForkLock here. ns, sa, err = acceptFunc(s) if err == nil { syscall.CloseOnExec(ns) } if err != nil { return -1, nil, os.NewSyscallError("accept", err) } if err = syscall.SetNonblock(ns, true); err != nil { closeFunc(ns) return -1, nil, os.NewSyscallError("setnonblock", err) } return ns, sa, nil }
// Wrapper around the socket system call that marks the returned file // descriptor as nonblocking and close-on-exec. func sysSocket(family, sotype, proto int) (int, error) { // 创建socket套接字 s, err := socketFunc(family, sotype|syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC, proto) // On Linux the SOCK_NONBLOCK and SOCK_CLOEXEC flags were // introduced in 2.6.27 kernel and on FreeBSD both flags were // introduced in 10 kernel. If we get an EINVAL error on Linux // or EPROTONOSUPPORT error on FreeBSD, fall back to using // socket without them. switch err { case nil: return s, nil default: return -1, os.NewSyscallError("socket", err) case syscall.EPROTONOSUPPORT, syscall.EINVAL: } // See ../syscall/exec_unix.go for description of ForkLock. syscall.ForkLock.RLock() s, err = socketFunc(family, sotype, proto) if err == nil { syscall.CloseOnExec(s) } syscall.ForkLock.RUnlock() if err != nil { return -1, os.NewSyscallError("socket", err) } if err = syscall.SetNonblock(s, true); err != nil { closeFunc(s) return -1, os.NewSyscallError("setnonblock", err) } return s, nil }
// If the ifindex is zero, interfaceAddrTable returns addresses // for all network interfaces. Otherwise it returns addresses // for a specific interface. func interfaceAddrTable(ifindex int) ([]Addr, os.Error) { var ( tab []byte e int err os.Error ifat []Addr msgs []syscall.NetlinkMessage ) tab, e = syscall.NetlinkRIB(syscall.RTM_GETADDR, syscall.AF_UNSPEC) if e != 0 { return nil, os.NewSyscallError("netlink rib", e) } msgs, e = syscall.ParseNetlinkMessage(tab) if e != 0 { return nil, os.NewSyscallError("netlink message", e) } ifat, err = addrTable(msgs, ifindex) if err != nil { return nil, err } return ifat, nil }
func mmap(fd uintptr, off int64, l, inprot int) (sli []byte, err error) { flProtect := uint32(syscall.PAGE_READONLY) dwDesiredAccess := uint32(syscall.FILE_MAP_READ) switch { case inprot&WRITE != 0: flProtect = syscall.PAGE_READWRITE dwDesiredAccess = syscall.FILE_MAP_WRITE case inprot&RDWR != 0: flProtect = syscall.PAGE_READWRITE dwDesiredAccess = syscall.FILE_MAP_WRITE } h, errno := syscall.CreateFileMapping(syscall.Handle(fd), nil, flProtect, 0, uint32(l), nil) if h == 0 { return nil, os.NewSyscallError("CreateFileMapping", errno) } addr, errno := syscall.MapViewOfFile(h, dwDesiredAccess, uint32(off>>32), uint32(off&0xFFFFFFFF), uintptr(l)) if addr == 0 { return nil, os.NewSyscallError("MapViewOfFile", errno) } handleLock.Lock() handleMap[addr] = h handleLock.Unlock() var header = struct { d uintptr l, c int }{addr, l, l} sli = *(*[]byte)(unsafe.Pointer(&header)) return sli, nil }
// If the ifindex is zero, interfaceAddrTable returns addresses // for all network interfaces. Otherwise it returns addresses // for a specific interface. func interfaceAddrTable(ifindex int) ([]Addr, error) { tab, err := syscall.RouteRIB(syscall.NET_RT_IFLIST, ifindex) if err != nil { return nil, os.NewSyscallError("route rib", err) } msgs, err := syscall.ParseRoutingMessage(tab) if err != nil { return nil, os.NewSyscallError("route message", err) } var ifat []Addr for _, m := range msgs { switch v := m.(type) { case *syscall.InterfaceAddrMessage: if ifindex == 0 || ifindex == int(v.Header.Index) { ifa, err := newAddr(v) if err != nil { return nil, err } if ifa != nil { ifat = append(ifat, ifa) } } } } return ifat, nil }
func mmap(hfile uintptr, off int64, len int) (uintptr, error) { flProtect := uint32(syscall.PAGE_READONLY) dwDesiredAccess := uint32(syscall.FILE_MAP_READ) flProtect = syscall.PAGE_READWRITE dwDesiredAccess = syscall.FILE_MAP_WRITE // The maximum size is the area of the file, starting from 0, // that we wish to allow to be mappable. It is the sum of // the length the user requested, plus the offset where that length // is starting from. This does not map the data into memory. maxSizeHigh := uint32((off + int64(len)) >> 32) maxSizeLow := uint32((off + int64(len)) & 0xFFFFFFFF) // TODO: Do we need to set some security attributes? It might help portability. h, errno := syscall.CreateFileMapping(syscall.Handle(hfile), nil, flProtect, maxSizeHigh, maxSizeLow, nil) if h == 0 { return 0, os.NewSyscallError("CreateFileMapping", errno) } // Actually map a view of the data into memory. The view's size // is the length the user requested. fileOffsetHigh := uint32(off >> 32) fileOffsetLow := uint32(off & 0xFFFFFFFF) addr, errno := syscall.MapViewOfFile(h, dwDesiredAccess, fileOffsetHigh, fileOffsetLow, uintptr(len)) if addr == 0 { return 0, os.NewSyscallError("MapViewOfFile", errno) } return addr, nil }
// readEvents reads from the inotify file descriptor, converts the // received events into Event objects and sends them via the Event channel func (w *Watcher) readEvents() { var ( buf [syscall.SizeofInotifyEvent * 4096]byte // Buffer for a maximum of 4096 raw events n int // Number of bytes read with read() errno int // Syscall errno ) for { n, errno = syscall.Read(w.fd, buf[0:]) // See if there is a message on the "done" channel _, done := <-w.done // If EOF or a "done" message is received if n == 0 || done { errno := syscall.Close(w.fd) if errno == -1 { w.Error <- os.NewSyscallError("close", errno) } close(w.Event) close(w.Error) return } if n < 0 { w.Error <- os.NewSyscallError("read", errno) continue } if n < syscall.SizeofInotifyEvent { w.Error <- os.NewError("inotify: short read in readEvents()") continue } var offset uint32 = 0 // We don't know how many events we just read into the buffer // While the offset points to at least one whole event... for offset <= uint32(n-syscall.SizeofInotifyEvent) { // Point "raw" to the event in the buffer raw := (*syscall.InotifyEvent)(unsafe.Pointer(&buf[offset])) event := new(Event) event.Mask = uint32(raw.Mask) event.Cookie = uint32(raw.Cookie) nameLen := uint32(raw.Len) // If the event happened to the watched directory or the watched file, the kernel // doesn't append the filename to the event, but we would like to always fill the // the "Name" field with a valid filename. We retrieve the path of the watch from // the "paths" map. event.Name = w.paths[int(raw.Wd)] if nameLen > 0 { // Point "bytes" at the first byte of the filename bytes := (*[syscall.PathMax]byte)(unsafe.Pointer(&buf[offset+syscall.SizeofInotifyEvent])) // The filename is padded with NUL bytes. TrimRight() gets rid of those. event.Name += "/" + strings.TrimRight(string(bytes[0:nameLen]), "\000") } // Send the event on the events channel w.Event <- event // Move to the next event in the buffer offset += syscall.SizeofInotifyEvent + nameLen } } }
// If the ifindex is zero, interfaceTable returns mappings of all // network interfaces. Otherwise it returns a mapping of a specific // interface. func interfaceTable(ifindex int) ([]Interface, error) { // 如果ifindex为0,返回所有网络接口 tab, err := syscall.NetlinkRIB(syscall.RTM_GETLINK, syscall.AF_UNSPEC) // 获得netlink rib if err != nil { return nil, os.NewSyscallError("netlinkrib", err) } msgs, err := syscall.ParseNetlinkMessage(tab) // 解析netlink信息 if err != nil { return nil, os.NewSyscallError("parsenetlinkmessage", err) } var ift []Interface loop: for _, m := range msgs { // 遍历获取的netlink信息 switch m.Header.Type { case syscall.NLMSG_DONE: break loop case syscall.RTM_NEWLINK: ifim := (*syscall.IfInfomsg)(unsafe.Pointer(&m.Data[0])) if ifindex == 0 || ifindex == int(ifim.Index) { attrs, err := syscall.ParseNetlinkRouteAttr(&m) if err != nil { return nil, os.NewSyscallError("parsenetlinkrouteattr", err) } ift = append(ift, *newLink(ifim, attrs)) // 加入到Interface Slice中 if ifindex == int(ifim.Index) { break loop } } } } return ift, nil }
func mmap(f *os.File, offset int64, length int) (out []byte, err error) { // Open a file mapping handle. sizelo := uint32(length >> 32) sizehi := uint32(length) & 0xffffffff sharedHandle, errno := openSharedFile(f) if errno != nil { return nil, os.NewSyscallError("CreateFile", errno) } h, errno := syscall.CreateFileMapping(syscall.Handle(sharedHandle.Fd()), nil, syscall.PAGE_READONLY, sizelo, sizehi, nil) if h == 0 { return nil, os.NewSyscallError("CreateFileMapping", errno) } // Create the memory map. addr, errno := syscall.MapViewOfFile(h, syscall.FILE_MAP_READ, 0, 0, uintptr(length)) if addr == 0 { return nil, os.NewSyscallError("MapViewOfFile", errno) } handleLock.Lock() handleMap[addr] = h fileMap[addr] = sharedHandle handleLock.Unlock() // Convert to a byte array. hdr := (*reflect.SliceHeader)(unsafe.Pointer(&out)) hdr.Data = uintptr(unsafe.Pointer(addr)) hdr.Len = length hdr.Cap = length return }
func newSplicePair() (p *Pair, err error) { p = &Pair{} p.r, p.w, err = os.Pipe() if err != nil { return nil, err } errNo := syscall.Errno(0) for _, f := range []*os.File{p.r, p.w} { _, errNo = fcntl(f.Fd(), syscall.F_SETFL, syscall.O_NONBLOCK) if errNo != 0 { p.Close() return nil, os.NewSyscallError("fcntl setfl", errNo) } } p.size, errNo = fcntl(p.r.Fd(), F_GETPIPE_SZ, 0) if errNo == syscall.EINVAL { p.size = DefaultPipeSize return p, nil } if errNo != 0 { p.Close() return nil, os.NewSyscallError("fcntl getsize", errNo) } return p, nil }
func newLookupIP(name string) (addrs []IP, err error) { acquireThread() defer releaseThread() hints := syscall.AddrinfoW{ Family: syscall.AF_UNSPEC, Socktype: syscall.SOCK_STREAM, Protocol: syscall.IPPROTO_IP, } var result *syscall.AddrinfoW e := syscall.GetAddrInfoW(syscall.StringToUTF16Ptr(name), nil, &hints, &result) if e != nil { return nil, os.NewSyscallError("GetAddrInfoW", e) } defer syscall.FreeAddrInfoW(result) addrs = make([]IP, 0, 5) for ; result != nil; result = result.Next { addr := unsafe.Pointer(result.Addr) switch result.Family { case syscall.AF_INET: a := (*syscall.RawSockaddrInet4)(addr).Addr addrs = append(addrs, IPv4(a[0], a[1], a[2], a[3])) case syscall.AF_INET6: a := (*syscall.RawSockaddrInet6)(addr).Addr addrs = append(addrs, IP{a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]}) default: return nil, os.NewSyscallError("LookupIP", syscall.EWINDOWS) } } return addrs, nil }
// If the ifindex is zero, interfaceTable returns mappings of all // network interfaces. Otheriwse it returns a mapping of a specific // interface. func interfaceTable(ifindex int) ([]Interface, error) { var ift []Interface tab, err := syscall.RouteRIB(syscall.NET_RT_IFLIST, ifindex) if err != nil { return nil, os.NewSyscallError("route rib", err) } msgs, err := syscall.ParseRoutingMessage(tab) if err != nil { return nil, os.NewSyscallError("route message", err) } for _, m := range msgs { switch v := m.(type) { case *syscall.InterfaceMessage: if ifindex == 0 || ifindex == int(v.Header.Index) { ifi, err := newLink(v) if err != nil { return nil, err } ift = append(ift, ifi...) } } } return ift, nil }
// getNeighbors sends a request to netlink to retrieve all neighbors using // the specified address family. func getNeighbors(family Family) ([]*Neighbor, error) { // Request neighbors belonging to a specific family from netlink tab, err := syscall.NetlinkRIB(syscall.RTM_GETNEIGH, int(family)) if err != nil { return nil, os.NewSyscallError("netlink rib", err) } // Parse netlink information into individual messages msgs, err := syscall.ParseNetlinkMessage(tab) if err != nil { return nil, os.NewSyscallError("netlink message", err) } // Check messages for information var nn []*Neighbor for _, m := range msgs { // Ignore any messages which don't indicate a new neighbor if m.Header.Type != syscall.RTM_NEWNEIGH { continue } // Attempt to parse an individual neighbor from a message n, err := newNeighbor(&m) if err != nil { return nil, err } nn = append(nn, n) } return nn, nil }
func (p *pollster) AddFD(fd int, mode int, repeat bool) os.Error { var kmode int if mode == 'r' { kmode = syscall.EVFILT_READ } else { kmode = syscall.EVFILT_WRITE } var events [1]syscall.Kevent_t ev := &events[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, &events, nil, nil) if e != 0 { return os.NewSyscallError("kevent", e) } if n != 1 || (ev.Flags&syscall.EV_ERROR) == 0 || int(ev.Ident) != fd || int(ev.Filter) != kmode { return os.NewSyscallError("kqueue phase error", e) } if ev.Data != 0 { return os.Errno(int(ev.Data)) } return nil }
// First return value is whether the pollServer should be woken up. // This version always returns false. 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, err := syscall.Kevent(p.kq, p.kbuf[:], nil, nil) if err != nil { return false, os.NewSyscallError("kevent", err) } if n != 1 || (ev.Flags&syscall.EV_ERROR) == 0 || int(ev.Ident) != fd || int(ev.Filter) != kmode { return false, os.NewSyscallError("kqueue phase error", err) } if ev.Data != 0 { return false, syscall.Errno(int(ev.Data)) } return false, nil }
// adapterAddresses returns a list of IP adapter and address // structures. The structure contains an IP adapter and flattened // multiple IP addresses including unicast, anycast and multicast // addresses. func adapterAddresses() ([]*windows.IpAdapterAddresses, error) { var b []byte l := uint32(15000) // recommended initial size for { b = make([]byte, l) err := windows.GetAdaptersAddresses(syscall.AF_UNSPEC, windows.GAA_FLAG_INCLUDE_PREFIX, 0, (*windows.IpAdapterAddresses)(unsafe.Pointer(&b[0])), &l) if err == nil { if l == 0 { return nil, nil } break } if err.(syscall.Errno) != syscall.ERROR_BUFFER_OVERFLOW { return nil, os.NewSyscallError("getadaptersaddresses", err) } if l <= uint32(len(b)) { return nil, os.NewSyscallError("getadaptersaddresses", err) } } var aas []*windows.IpAdapterAddresses for aa := (*windows.IpAdapterAddresses)(unsafe.Pointer(&b[0])); aa != nil; aa = aa.Next { aas = append(aas, aa) } return aas, nil }
func initSecurityAttributes() (*syscall.SecurityAttributes, error) { // create security descriptor sd := make([]byte, 4096) if res, _, err := procInitializeSecurityDescriptor.Call( uintptr(unsafe.Pointer(&sd[0])), SECURITY_DESCRIPTOR_REVISION); int(res) == 0 { return nil, os.NewSyscallError("InitializeSecurityDescriptor", err) } // configure security descriptor present := 1 defaulted := 0 if res, _, err := procSetSecurityDescriptorDacl.Call( uintptr(unsafe.Pointer(&sd[0])), uintptr(present), uintptr(unsafe.Pointer(nil)), // acl uintptr(defaulted)); int(res) == 0 { return nil, os.NewSyscallError("SetSecurityDescriptorDacl", err) } var sa syscall.SecurityAttributes sa.Length = uint32(unsafe.Sizeof(sa)) sa.SecurityDescriptor = uintptr(unsafe.Pointer(&sd[0])) return &sa, nil }
func (process *jobProcess) Wait() (int, error) { s, e := syscall.WaitForSingleObject(syscall.Handle(process.processHandle), syscall.INFINITE) switch s { case syscall.WAIT_OBJECT_0: break case syscall.WAIT_FAILED: return -1, os.NewSyscallError("WaitForSingleObject", e) default: return -1, errors.New("os: unexpected result from WaitForSingleObject") } var ec uint32 e = syscall.GetExitCodeProcess(syscall.Handle(process.processHandle), &ec) if e != nil { return -1, os.NewSyscallError("GetExitCodeProcess", e) } var u syscall.Rusage e = syscall.GetProcessTimes(syscall.Handle(process.processHandle), &u.CreationTime, &u.ExitTime, &u.KernelTime, &u.UserTime) if e != nil { return -1, os.NewSyscallError("GetProcessTimes", e) } // NOTE(brainman): It seems that sometimes process is not dead // when WaitForSingleObject returns. But we do not know any // other way to wait for it. Sleeping for a while seems to do // the trick sometimes. So we will sleep and smell the roses. defer time.Sleep(5 * time.Millisecond) defer syscall.CloseHandle(syscall.Handle(process.processHandle)) return int(ec), nil }
// interfaceMulticastAddrTable returns addresses for a specific // interface. func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) { tab, err := syscall.RouteRIB(syscall.NET_RT_IFLIST2, ifi.Index) if err != nil { return nil, os.NewSyscallError("route rib", err) } msgs, err := syscall.ParseRoutingMessage(tab) if err != nil { return nil, os.NewSyscallError("route message", err) } var ifmat []Addr for _, m := range msgs { switch m := m.(type) { case *syscall.InterfaceMulticastAddrMessage: if ifi.Index == int(m.Header.Index) { ifma, err := newMulticastAddr(ifi, m) if err != nil { return nil, err } if ifma != nil { ifmat = append(ifmat, ifma) } } } } return ifmat, nil }
// enable raw mode and gather metrics, like number of columns func (l *LineReader) raw() { // STD_OUTPUT_HANDLE h, errno := syscall.GetStdHandle(-11) t.h = uintptr(h) if int32(t.h) == -1 { err := os.Errno(errno) panic(err) } ok, _, e := syscall.Syscall(procGetConsoleMode, 2, t.h, uintptr(unsafe.Pointer(&t.origTerm)), 0) if ok == 0 { err := os.NewSyscallError("GetConsoleMode", int(e)) panic(err) } raw := t.origTerm raw &^= _ENABLE_LINE_INPUT | _ENABLE_ECHO_INPUT | _ENABLE_PROCESSED_INPUT | _ENABLE_WINDOW_INPUT ok, _, e = syscall.Syscall(procSetConsoleMode, 2, t.h, uintptr(raw), 0) if ok == 0 { err := os.NewSyscallError("SetConsoleMode", int(e)) panic(err) } win := t.getConsoleInfo() t.cols = int(win.dwSize.x) t.rows = int(win.dwSize.y) t.buf = new(buffer) }