Commit bb9261bf authored by Alex Brainman's avatar Alex Brainman Committed by Russ Cox

net: initial attempt to implement windows version

R=rsc, Mateusz Czaplinski
CC=golang-dev
https://golang.org/cl/1600041
parent 82989616
...@@ -10,8 +10,6 @@ GOFILES=\ ...@@ -10,8 +10,6 @@ GOFILES=\
dnsclient.go\ dnsclient.go\
dnsconfig.go\ dnsconfig.go\
dnsmsg.go\ dnsmsg.go\
newpollserver.go\
fd.go\
fd_$(GOOS).go\ fd_$(GOOS).go\
hosts.go\ hosts.go\
ip.go\ ip.go\
...@@ -26,4 +24,22 @@ GOFILES=\ ...@@ -26,4 +24,22 @@ GOFILES=\
udpsock.go\ udpsock.go\
unixsock.go\ unixsock.go\
GOFILES_freebsd=\
newpollserver.go\
fd.go\
GOFILES_darwin=\
newpollserver.go\
fd.go\
GOFILES_linux=\
newpollserver.go\
fd.go\
GOFILES_nacl=\
newpollserver.go\
fd.go\
GOFILES+=$(GOFILES_$(GOOS))
include ../../Make.pkg include ../../Make.pkg
// Copyright 2010 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 net
import (
"once"
"os"
"sync"
"syscall"
"unsafe"
)
// BUG(brainman): The Windows implementation does not implement SetTimeout.
// IO completion result parameters.
type ioResult struct {
key uint32
qty uint32
errno int
}
// Network file descriptor.
type netFD struct {
// locking/lifetime of sysfd
sysmu sync.Mutex
sysref int
closing bool
// immutable until Close
sysfd int
family int
proto int
sysfile *os.File
cr chan *ioResult
cw chan *ioResult
net string
laddr Addr
raddr Addr
// owned by client
rdeadline_delta int64
rdeadline int64
rio sync.Mutex
wdeadline_delta int64
wdeadline int64
wio sync.Mutex
}
type InvalidConnError struct{}
func (e *InvalidConnError) String() string { return "invalid net.Conn" }
func (e *InvalidConnError) Temporary() bool { return false }
func (e *InvalidConnError) Timeout() bool { return false }
// pollServer will run around waiting for io completion request
// to arrive. Every request received will contain channel to signal
// io owner about the completion.
type pollServer struct {
iocp int32
}
func newPollServer() (s *pollServer, err os.Error) {
s = new(pollServer)
var e int
if s.iocp, e = syscall.CreateIoCompletionPort(-1, 0, 0, 1); e != 0 {
return nil, os.NewSyscallError("CreateIoCompletionPort", e)
}
go s.Run()
return s, nil
}
type ioPacket struct {
// Used by IOCP interface,
// it must be first field of the struct,
// as our code rely on it.
o syscall.Overlapped
// Link to the io owner.
c chan *ioResult
}
func (s *pollServer) getCompletedIO() (ov *syscall.Overlapped, result *ioResult, err os.Error) {
var r ioResult
var o *syscall.Overlapped
_, e := syscall.GetQueuedCompletionStatus(s.iocp, &r.qty, &r.key, &o, syscall.INFINITE)
switch {
case e == 0:
// Dequeued successfully completed io packet.
return o, &r, nil
case e == syscall.WAIT_TIMEOUT && o == nil:
// Wait has timed out (should not happen now, but might be used in the future).
return nil, &r, os.NewSyscallError("GetQueuedCompletionStatus", e)
case o == nil:
// Failed to dequeue anything -> report the error.
return nil, &r, os.NewSyscallError("GetQueuedCompletionStatus", e)
default:
// Dequeued failed io packet.
r.errno = e
return o, &r, nil
}
return
}
func (s *pollServer) Run() {
for {
o, r, err := s.getCompletedIO()
if err != nil {
panic("Run pollServer: " + err.String() + "\n")
}
p := (*ioPacket)(unsafe.Pointer(o))
p.c <- r
}
}
// Network FD methods.
// All the network FDs use a single pollServer.
var pollserver *pollServer
func startServer() {
p, err := newPollServer()
if err != nil {
panic("Start pollServer: " + err.String() + "\n")
}
pollserver = p
}
var initErr os.Error
func newFD(fd, family, proto int, net string, laddr, raddr Addr) (f *netFD, err os.Error) {
if initErr != nil {
return nil, initErr
}
once.Do(startServer)
// Associate our socket with pollserver.iocp.
if _, e := syscall.CreateIoCompletionPort(int32(fd), pollserver.iocp, 0, 0); e != 0 {
return nil, &OpError{"CreateIoCompletionPort", net, laddr, os.Errno(e)}
}
f = &netFD{
sysfd: fd,
family: family,
proto: proto,
cr: make(chan *ioResult),
cw: make(chan *ioResult),
net: net,
laddr: laddr,
raddr: raddr,
}
var ls, rs string
if laddr != nil {
ls = laddr.String()
}
if raddr != nil {
rs = raddr.String()
}
f.sysfile = os.NewFile(fd, net+":"+ls+"->"+rs)
return f, nil
}
// Add a reference to this fd.
func (fd *netFD) incref() {
fd.sysmu.Lock()
fd.sysref++
fd.sysmu.Unlock()
}
// Remove a reference to this FD and close if we've been asked to do so (and
// there are no references left.
func (fd *netFD) decref() {
fd.sysmu.Lock()
fd.sysref--
if fd.closing && fd.sysref == 0 && fd.sysfd >= 0 {
// In case the user has set linger, switch to blocking mode so
// the close blocks. As long as this doesn't happen often, we
// can handle the extra OS processes. Otherwise we'll need to
// use the pollserver for Close too. Sigh.
syscall.SetNonblock(fd.sysfd, false)
fd.sysfile.Close()
fd.sysfile = nil
fd.sysfd = -1
}
fd.sysmu.Unlock()
}
func (fd *netFD) Close() os.Error {
if fd == nil || fd.sysfile == nil {
return os.EINVAL
}
fd.incref()
syscall.Shutdown(fd.sysfd, syscall.SHUT_RDWR)
fd.closing = true
fd.decref()
return nil
}
func newWSABuf(p []byte) *syscall.WSABuf {
return &syscall.WSABuf{uint32(len(p)), (*byte)(unsafe.Pointer(&p[0]))}
}
func (fd *netFD) Read(p []byte) (n int, err os.Error) {
if fd == nil {
return 0, os.EINVAL
}
fd.rio.Lock()
defer fd.rio.Unlock()
fd.incref()
defer fd.decref()
if fd.sysfile == nil {
return 0, os.EINVAL
}
// Submit receive request.
var pckt ioPacket
pckt.c = fd.cr
var done uint32
flags := uint32(0)
e := syscall.WSARecv(uint32(fd.sysfd), newWSABuf(p), 1, &done, &flags, &pckt.o, nil)
switch e {
case 0:
// IO completed immediately, but we need to get our completion message anyway.
case syscall.ERROR_IO_PENDING:
// IO started, and we have to wait for it's completion.
default:
return 0, &OpError{"WSARecv", fd.net, fd.laddr, os.Errno(e)}
}
// Wait for our request to complete.
r := <-pckt.c
if r.errno != 0 {
err = &OpError{"WSARecv", fd.net, fd.laddr, os.Errno(r.errno)}
}
n = int(r.qty)
return
}
func (fd *netFD) ReadFrom(p []byte) (n int, sa syscall.Sockaddr, err os.Error) {
var r syscall.Sockaddr
return 0, r, nil
}
func (fd *netFD) Write(p []byte) (n int, err os.Error) {
if fd == nil {
return 0, os.EINVAL
}
fd.wio.Lock()
defer fd.wio.Unlock()
fd.incref()
defer fd.decref()
if fd.sysfile == nil {
return 0, os.EINVAL
}
// Submit send request.
var pckt ioPacket
pckt.c = fd.cw
var done uint32
e := syscall.WSASend(uint32(fd.sysfd), newWSABuf(p), 1, &done, uint32(0), &pckt.o, nil)
switch e {
case 0:
// IO completed immediately, but we need to get our completion message anyway.
case syscall.ERROR_IO_PENDING:
// IO started, and we have to wait for it's completion.
default:
return 0, &OpError{"WSASend", fd.net, fd.laddr, os.Errno(e)}
}
// Wait for our request to complete.
r := <-pckt.c
if r.errno != 0 {
err = &OpError{"WSASend", fd.net, fd.laddr, os.Errno(r.errno)}
}
n = int(r.qty)
return
}
func (fd *netFD) WriteTo(p []byte, sa syscall.Sockaddr) (n int, err os.Error) {
return 0, nil
}
func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (nfd *netFD, err os.Error) {
if fd == nil || fd.sysfile == nil {
return nil, os.EINVAL
}
fd.incref()
defer fd.decref()
// Get new socket.
// See ../syscall/exec.go for description of ForkLock.
syscall.ForkLock.RLock()
s, e := syscall.Socket(fd.family, fd.proto, 0)
if e != 0 {
syscall.ForkLock.RUnlock()
return nil, os.Errno(e)
}
syscall.CloseOnExec(s)
syscall.ForkLock.RUnlock()
// Associate our new socket with IOCP.
once.Do(startServer)
if _, e = syscall.CreateIoCompletionPort(int32(s), pollserver.iocp, 0, 0); e != 0 {
return nil, &OpError{"CreateIoCompletionPort", fd.net, fd.laddr, os.Errno(e)}
}
// Submit accept request.
// Will use new unique channel here, because, unlike Read or Write,
// Accept is expected to be executed by many goroutines simultaniously.
var pckt ioPacket
pckt.c = make(chan *ioResult)
attrs, e := syscall.AcceptIOCP(fd.sysfd, s, &pckt.o)
switch e {
case 0:
// IO completed immediately, but we need to get our completion message anyway.
case syscall.ERROR_IO_PENDING:
// IO started, and we have to wait for it's completion.
default:
syscall.Close(s)
return nil, &OpError{"AcceptEx", fd.net, fd.laddr, os.Errno(e)}
}
// Wait for peer connection.
r := <-pckt.c
if r.errno != 0 {
syscall.Close(s)
return nil, &OpError{"AcceptEx", fd.net, fd.laddr, os.Errno(r.errno)}
}
// Inherit properties of the listening socket.
e = syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_UPDATE_ACCEPT_CONTEXT, fd.sysfd)
if e != 0 {
syscall.Close(s)
return nil, &OpError{"Setsockopt", fd.net, fd.laddr, os.Errno(r.errno)}
}
// Get local and peer addr out of AcceptEx buffer.
lsa, rsa := syscall.GetAcceptIOCPSockaddrs(attrs)
// Create our netFD and return it for further use.
laddr := toAddr(lsa)
raddr := toAddr(rsa)
f := &netFD{
sysfd: s,
family: fd.family,
proto: fd.proto,
cr: make(chan *ioResult),
cw: make(chan *ioResult),
net: fd.net,
laddr: laddr,
raddr: raddr,
}
var ls, rs string
if laddr != nil {
ls = laddr.String()
}
if raddr != nil {
rs = raddr.String()
}
f.sysfile = os.NewFile(s, fd.net+":"+ls+"->"+rs)
return f, nil
}
func init() {
var d syscall.WSAData
e := syscall.WSAStartup(uint32(0x101), &d)
if e != 0 {
initErr = os.NewSyscallError("WSAStartup", e)
}
}
...@@ -62,6 +62,8 @@ sub parseparam($) { ...@@ -62,6 +62,8 @@ sub parseparam($) {
$text = ""; $text = "";
$vars = ""; $vars = "";
$mods = "";
$modnames = "";
while(<>) { while(<>) {
chomp; chomp;
s/\s+/ /g; s/\s+/ /g;
...@@ -72,17 +74,27 @@ while(<>) { ...@@ -72,17 +74,27 @@ while(<>) {
# Line must be of the form # Line must be of the form
# func Open(path string, mode int, perm int) (fd int, errno int) # func Open(path string, mode int, perm int) (fd int, errno int)
# Split into name, in params, out params. # Split into name, in params, out params.
if(!/^\/\/sys (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:\[failretval=(.*)\])?\s*(?:=\s*(\w*))?$/) { if(!/^\/\/sys (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:\[failretval=(.*)\])?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$/) {
print STDERR "$ARGV:$.: malformed //sys declaration\n"; print STDERR "$ARGV:$.: malformed //sys declaration\n";
$errors = 1; $errors = 1;
next; next;
} }
my ($func, $in, $out, $failretval, $sysname) = ($1, $2, $3, $4, $5); my ($func, $in, $out, $failretval, $modname, $sysname) = ($1, $2, $3, $4, $5, $6);
# Split argument lists on comma. # Split argument lists on comma.
my @in = parseparamlist($in); my @in = parseparamlist($in);
my @out = parseparamlist($out); my @out = parseparamlist($out);
# Dll file name.
if($modname eq "") {
$modname = "kernel32";
}
$modvname = "mod$modname";
if($modnames !~ /$modname/) {
$modnames .= ".$modname";
$mods .= "\t$modvname = loadDll(\"$modname.dll\")\n";
}
# System call name. # System call name.
if($sysname eq "") { if($sysname eq "") {
$sysname = "$func"; $sysname = "$func";
...@@ -104,7 +116,7 @@ while(<>) { ...@@ -104,7 +116,7 @@ while(<>) {
} }
# Winapi proc address variable. # Winapi proc address variable.
$vars .= sprintf "\t%s = getSysProcAddr(modKERNEL32, \"%s\")\n", $sysvarname, $sysname; $vars .= sprintf "\t%s = getSysProcAddr(%s, \"%s\")\n", $sysvarname, $modvname, $sysname;
# Go function header. # Go function header.
$text .= sprintf "func %s(%s) (%s) {\n", $func, join(', ', @in), join(', ', @out); $text .= sprintf "func %s(%s) (%s) {\n", $func, join(', ', @in), join(', ', @out);
...@@ -198,6 +210,9 @@ while(<>) { ...@@ -198,6 +210,9 @@ while(<>) {
if($i == 0) { if($i == 0) {
if($type eq "bool") { if($type eq "bool") {
$failexpr = "!$name"; $failexpr = "!$name";
} elsif($name eq "errno") {
$ret[$i] = "r1";
$failexpr = "int(r1) == $failretval";
} else { } else {
$failexpr = "$name == $failretval"; $failexpr = "$name == $failretval";
} }
...@@ -212,7 +227,7 @@ while(<>) { ...@@ -212,7 +227,7 @@ while(<>) {
} else { } else {
$body .= "\t$name = $type($reg);\n"; $body .= "\t$name = $type($reg);\n";
} }
push @pout, sprintf "\"%s=\", %s(%s), ", $name, $type, $reg; push @pout, sprintf "\"%s=\", %s, ", $name, $name;
} }
if ($ret[0] eq "_" && $ret[1] eq "_" && $ret[2] eq "_") { if ($ret[0] eq "_" && $ret[1] eq "_" && $ret[2] eq "_") {
$text .= "\t$call;\n"; $text .= "\t$call;\n";
...@@ -241,7 +256,7 @@ package syscall ...@@ -241,7 +256,7 @@ package syscall
import "unsafe" import "unsafe"
var ( var (
modKERNEL32 = loadDll("kernel32.dll") $mods
$vars $vars
) )
......
...@@ -128,6 +128,8 @@ func getSysProcAddr(m uint32, pname string) uintptr { ...@@ -128,6 +128,8 @@ func getSysProcAddr(m uint32, pname string) uintptr {
//sys SetEndOfFile(handle int32) (ok bool, errno int) //sys SetEndOfFile(handle int32) (ok bool, errno int)
//sys GetSystemTimeAsFileTime(time *Filetime) //sys GetSystemTimeAsFileTime(time *Filetime)
//sys sleep(msec uint32) = Sleep //sys sleep(msec uint32) = Sleep
//sys CreateIoCompletionPort(filehandle int32, cphandle int32, key uint32, threadcnt uint32) (handle int32, errno int)
//sys GetQueuedCompletionStatus(cphandle int32, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (ok bool, errno int)
// syscall interface implementation for other packages // syscall interface implementation for other packages
...@@ -382,6 +384,191 @@ func Utimes(path string, tv []Timeval) (errno int) { ...@@ -382,6 +384,191 @@ func Utimes(path string, tv []Timeval) (errno int) {
return EWINDOWS return EWINDOWS
} }
// net api calls
//sys WSAStartup(verreq uint32, data *WSAData) (sockerrno int) = wsock32.WSAStartup
//sys WSACleanup() (errno int) [failretval=-1] = wsock32.WSACleanup
//sys socket(af int32, typ int32, protocol int32) (handle int32, errno int) [failretval=-1] = wsock32.socket
//sys setsockopt(s int32, level int32, optname int32, optval *byte, optlen int32) (errno int) [failretval=-1] = wsock32.setsockopt
//sys bind(s int32, name uintptr, namelen int32) (errno int) [failretval=-1] = wsock32.bind
//sys connect(s int32, name uintptr, namelen int32) (errno int) [failretval=-1] = wsock32.connect
//sys getsockname(s int32, rsa *RawSockaddrAny, addrlen *int32) (errno int) [failretval=-1] = wsock32.getsockname
//sys getpeername(s int32, rsa *RawSockaddrAny, addrlen *int32) (errno int) [failretval=-1] = wsock32.getpeername
//sys listen(s int32, backlog int32) (errno int) [failretval=-1] = wsock32.listen
//sys shutdown(s int32, how int32) (errno int) [failretval=-1] = wsock32.shutdown
//sys AcceptEx(ls uint32, as uint32, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (ok bool, errno int) = wsock32.AcceptEx
//sys GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) = wsock32.GetAcceptExSockaddrs
//sys WSARecv(s uint32, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (errno int) [failretval=-1] = ws2_32.WSARecv
//sys WSASend(s uint32, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (errno int) [failretval=-1] = ws2_32.WSASend
type RawSockaddrInet4 struct {
Family uint16
Port uint16
Addr [4]byte /* in_addr */
Zero [8]uint8
}
type RawSockaddr struct {
Family uint16
Data [14]int8
}
type RawSockaddrAny struct {
Addr RawSockaddr
Pad [96]int8
}
type Sockaddr interface {
sockaddr() (ptr uintptr, len int32, errno int) // lowercase; only we can define Sockaddrs
}
type SockaddrInet4 struct {
Port int
Addr [4]byte
raw RawSockaddrInet4
}
func (sa *SockaddrInet4) sockaddr() (uintptr, int32, int) {
if sa.Port < 0 || sa.Port > 0xFFFF {
return 0, 0, EINVAL
}
sa.raw.Family = AF_INET
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
p[0] = byte(sa.Port >> 8)
p[1] = byte(sa.Port)
for i := 0; i < len(sa.Addr); i++ {
sa.raw.Addr[i] = sa.Addr[i]
}
return uintptr(unsafe.Pointer(&sa.raw)), int32(unsafe.Sizeof(sa.raw)), 0
}
type SockaddrInet6 struct {
Port int
Addr [16]byte
}
func (sa *SockaddrInet6) sockaddr() (uintptr, int32, int) {
// TODO(brainman): implement SockaddrInet6.sockaddr()
return 0, 0, EWINDOWS
}
type SockaddrUnix struct {
Name string
}
func (sa *SockaddrUnix) sockaddr() (uintptr, int32, int) {
// TODO(brainman): implement SockaddrUnix.sockaddr()
return 0, 0, EWINDOWS
}
func (rsa *RawSockaddrAny) Sockaddr() (Sockaddr, int) {
switch rsa.Addr.Family {
case AF_UNIX:
return nil, EWINDOWS
case AF_INET:
pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
sa := new(SockaddrInet4)
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1])
for i := 0; i < len(sa.Addr); i++ {
sa.Addr[i] = pp.Addr[i]
}
return sa, 0
case AF_INET6:
return nil, EWINDOWS
}
return nil, EAFNOSUPPORT
}
func Socket(domain, typ, proto int) (fd, errno int) {
h, e := socket(int32(domain), int32(typ), int32(proto))
return int(h), int(e)
}
func SetsockoptInt(fd, level, opt int, value int) (errno int) {
v := int32(value)
return int(setsockopt(int32(fd), int32(level), int32(opt), (*byte)(unsafe.Pointer(&v)), int32(unsafe.Sizeof(v))))
}
func Bind(fd int, sa Sockaddr) (errno int) {
ptr, n, err := sa.sockaddr()
if err != 0 {
return err
}
return bind(int32(fd), ptr, n)
}
func Connect(fd int, sa Sockaddr) (errno int) {
ptr, n, err := sa.sockaddr()
if err != 0 {
return err
}
return connect(int32(fd), ptr, n)
}
func Getsockname(fd int) (sa Sockaddr, errno int) {
var rsa RawSockaddrAny
l := int32(unsafe.Sizeof(rsa))
if errno = getsockname(int32(fd), &rsa, &l); errno != 0 {
return
}
return rsa.Sockaddr()
}
func Getpeername(fd int) (sa Sockaddr, errno int) {
var rsa RawSockaddrAny
l := int32(unsafe.Sizeof(rsa))
if errno = getpeername(int32(fd), &rsa, &l); errno != 0 {
return
}
return rsa.Sockaddr()
}
func Listen(s int, n int) (errno int) {
return int(listen(int32(s), int32(n)))
}
func Shutdown(fd, how int) (errno int) {
return int(shutdown(int32(fd), int32(how)))
}
func AcceptIOCP(iocpfd, fd int, o *Overlapped) (attrs *byte, errno int) {
// Will ask for local and remote address only.
rsa := make([]RawSockaddrAny, 2)
attrs = (*byte)(unsafe.Pointer(&rsa[0]))
alen := uint32(unsafe.Sizeof(rsa[0]))
var done uint32
_, errno = AcceptEx(uint32(iocpfd), uint32(fd), attrs, 0, alen, alen, &done, o)
return
}
func GetAcceptIOCPSockaddrs(attrs *byte) (lsa, rsa Sockaddr) {
var lrsa, rrsa *RawSockaddrAny
var llen, rlen int32
alen := uint32(unsafe.Sizeof(*lrsa))
GetAcceptExSockaddrs(attrs, 0, alen, alen, &lrsa, &llen, &rrsa, &rlen)
lsa, _ = lrsa.Sockaddr()
rsa, _ = rrsa.Sockaddr()
return
}
// TODO(brainman): fix all needed for net
func Accept(fd int) (nfd int, sa Sockaddr, errno int) { return 0, nil, EWINDOWS }
func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, errno int) { return 0, nil, EWINDOWS }
func Sendto(fd int, p []byte, flags int, to Sockaddr) (errno int) { return EWINDOWS }
func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (errno int) { return EWINDOWS }
type Linger struct {
Onoff int32
Linger int32
}
func SetsockoptLinger(fd, level, opt int, l *Linger) (errno int) { return EWINDOWS }
func BindToDevice(fd int, device string) (errno int) { return EWINDOWS }
// TODO(brainman): fix all needed for os // TODO(brainman): fix all needed for os
const ( const (
......
...@@ -13,6 +13,7 @@ const ( ...@@ -13,6 +13,7 @@ const (
ERROR_MOD_NOT_FOUND = 126 ERROR_MOD_NOT_FOUND = 126
ERROR_PROC_NOT_FOUND = 127 ERROR_PROC_NOT_FOUND = 127
ERROR_DIRECTORY = 267 ERROR_DIRECTORY = 267
ERROR_IO_PENDING = 997
// TODO(brainman): should use value for EWINDOWS that does not clashes with anything else // TODO(brainman): should use value for EWINDOWS that does not clashes with anything else
EWINDOWS = 99999 /* otherwise unused */ EWINDOWS = 99999 /* otherwise unused */
) )
......
This diff is collapsed.
...@@ -10,19 +10,15 @@ package syscall ...@@ -10,19 +10,15 @@ package syscall
// Constants // Constants
const ( const (
sizeofPtr = 0x4 sizeofPtr = 0x4
sizeofShort = 0x2 sizeofShort = 0x2
sizeofInt = 0x4 sizeofInt = 0x4
sizeofLong = 0x4 sizeofLong = 0x4
sizeofLongLong = 0x8 sizeofLongLong = 0x8
PathMax = 0x1000 PathMax = 0x1000
SizeofSockaddrInet4 = 0x10 SizeofLinger = 0x8
SizeofSockaddrInet6 = 0x1c SizeofMsghdr = 0x1c
SizeofSockaddrAny = 0x70 SizeofCmsghdr = 0xc
SizeofSockaddrUnix = 0x6e
SizeofLinger = 0x8
SizeofMsghdr = 0x1c
SizeofCmsghdr = 0xc
) )
const ( const (
...@@ -82,6 +78,10 @@ const ( ...@@ -82,6 +78,10 @@ const (
MAX_PATH = 260 MAX_PATH = 260
MAX_COMPUTERNAME_LENGTH = 15 MAX_COMPUTERNAME_LENGTH = 15
INFINITE = 0xffffffff
WAIT_TIMEOUT = 258
) )
// Types // Types
...@@ -155,6 +155,58 @@ type Stat_t struct { ...@@ -155,6 +155,58 @@ type Stat_t struct {
Mode uint32 Mode uint32
} }
// Socket related.
const (
AF_UNIX = 1
AF_INET = 2
AF_INET6 = 23
SOCK_STREAM = 1
SOCK_DGRAM = 2
SOCK_RAW = 3
IPPROTO_IP = 0
IPPROTO_TCP = 6
IPPROTO_UDP = 17
SOL_SOCKET = 0xffff
SO_REUSEADDR = 4
SO_KEEPALIVE = 8
SO_DONTROUTE = 16
SO_BROADCAST = 32
SO_LINGER = 128
SO_RCVBUF = 0x1002
SO_SNDBUF = 0x1001
SO_UPDATE_ACCEPT_CONTEXT = 0x700b
SOMAXCONN = 5
TCP_NODELAY = 1
SHUT_RD = 0
SHUT_WR = 1
SHUT_RDWR = 2
WSADESCRIPTION_LEN = 256
WSASYS_STATUS_LEN = 128
)
type WSAData struct {
Version uint16
HighVersion uint16
Description [WSADESCRIPTION_LEN + 1]byte
SystemStatus [WSASYS_STATUS_LEN + 1]byte
MaxSockets uint16
MaxUdpDg uint16
VendorInfo *byte
}
type WSABuf struct {
Len uint32
Buf *byte
}
// TODO(brainman): fix all needed for os // TODO(brainman): fix all needed for os
const ( const (
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment