Commit 63b8b948 authored by Wei Guangjing's avatar Wei Guangjing Committed by Russ Cox

windows: define and use syscall.Handle

Fixes #1487.

R=rsc, alex.brainman, go.peter.90, mikioh.mikioh, mattn.jp
CC=golang-dev
https://golang.org/cl/4600042
parent 21efa147
// 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 file
import (
"os"
"syscall"
)
type File struct {
fd syscall.Handle // file descriptor number
name string // file name at Open time
}
func newFile(fd syscall.Handle, name string) *File {
if fd < 0 {
return nil
}
return &File{fd, name}
}
var (
Stdin = newFile(syscall.Stdin, "/dev/stdin")
Stdout = newFile(syscall.Stdout, "/dev/stdout")
Stderr = newFile(syscall.Stderr, "/dev/stderr")
)
func OpenFile(name string, mode int, perm uint32) (file *File, err os.Error) {
r, e := syscall.Open(name, mode, perm)
if e != 0 {
err = os.Errno(e)
}
return newFile(r, name), err
}
const (
O_RDONLY = syscall.O_RDONLY
O_RDWR = syscall.O_RDWR
O_CREATE = syscall.O_CREAT
O_TRUNC = syscall.O_TRUNC
)
func Open(name string) (file *File, err os.Error) {
return OpenFile(name, O_RDONLY, 0)
}
func Create(name string) (file *File, err os.Error) {
return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)
}
func (file *File) Close() os.Error {
if file == nil {
return os.EINVAL
}
e := syscall.Close(file.fd)
file.fd = syscall.InvalidHandle // so it can't be closed again
if e != 0 {
return os.Errno(e)
}
return nil
}
func (file *File) Read(b []byte) (ret int, err os.Error) {
if file == nil {
return -1, os.EINVAL
}
r, e := syscall.Read(file.fd, b)
if e != 0 {
err = os.Errno(e)
}
return int(r), err
}
func (file *File) Write(b []byte) (ret int, err os.Error) {
if file == nil {
return -1, os.EINVAL
}
r, e := syscall.Write(file.fd, b)
if e != 0 {
err = os.Errno(e)
}
return int(r), err
}
func (file *File) String() string {
return file.name
}
...@@ -14,8 +14,13 @@ fi ...@@ -14,8 +14,13 @@ fi
rm -f *.$O rm -f *.$O
if [ "$GOOS" = "windows" ];then
$GC -o file.8 file_windows.go
else
$GC file.go
fi
for i in \ for i in \
file.go \
helloworld.go \ helloworld.go \
helloworld3.go \ helloworld3.go \
echo.go \ echo.go \
......
...@@ -19,7 +19,7 @@ func init() { Reader = &rngReader{} } ...@@ -19,7 +19,7 @@ func init() { Reader = &rngReader{} }
// A rngReader satisfies reads by reading from the Windows CryptGenRandom API. // A rngReader satisfies reads by reading from the Windows CryptGenRandom API.
type rngReader struct { type rngReader struct {
prov uint32 prov syscall.Handle
mu sync.Mutex mu sync.Mutex
} }
......
...@@ -29,8 +29,8 @@ func init() { ...@@ -29,8 +29,8 @@ func init() {
} }
} }
func closesocket(s int) (errno int) { func closesocket(s syscall.Handle) (errno int) {
return syscall.Closesocket(int32(s)) return syscall.Closesocket(s)
} }
// Interface for all io operations. // Interface for all io operations.
...@@ -88,7 +88,7 @@ func (o *bufOp) Init(fd *netFD, buf []byte) { ...@@ -88,7 +88,7 @@ func (o *bufOp) Init(fd *netFD, buf []byte) {
// iocp and send them to the correspondent waiting client // iocp and send them to the correspondent waiting client
// goroutine via channel supplied in the request. // goroutine via channel supplied in the request.
type resultSrv struct { type resultSrv struct {
iocp int32 iocp syscall.Handle
} }
func (s *resultSrv) Run() { func (s *resultSrv) Run() {
...@@ -132,7 +132,7 @@ func (s *ioSrv) ProcessRemoteIO() { ...@@ -132,7 +132,7 @@ func (s *ioSrv) ProcessRemoteIO() {
case o := <-s.submchan: case o := <-s.submchan:
o.Op().errnoc <- o.Submit() o.Op().errnoc <- o.Submit()
case o := <-s.canchan: case o := <-s.canchan:
o.Op().errnoc <- syscall.CancelIo(uint32(o.Op().fd.sysfd)) o.Op().errnoc <- syscall.CancelIo(syscall.Handle(o.Op().fd.sysfd))
} }
} }
} }
...@@ -189,7 +189,7 @@ var onceStartServer sync.Once ...@@ -189,7 +189,7 @@ var onceStartServer sync.Once
func startServer() { func startServer() {
resultsrv = new(resultSrv) resultsrv = new(resultSrv)
var errno int var errno int
resultsrv.iocp, errno = syscall.CreateIoCompletionPort(-1, 0, 0, 1) resultsrv.iocp, errno = syscall.CreateIoCompletionPort(syscall.InvalidHandle, 0, 0, 1)
if errno != 0 { if errno != 0 {
panic("CreateIoCompletionPort failed " + syscall.Errstr(errno)) panic("CreateIoCompletionPort failed " + syscall.Errstr(errno))
} }
...@@ -209,7 +209,7 @@ type netFD struct { ...@@ -209,7 +209,7 @@ type netFD struct {
closing bool closing bool
// immutable until Close // immutable until Close
sysfd int sysfd syscall.Handle
family int family int
proto int proto int
net string net string
...@@ -225,7 +225,7 @@ type netFD struct { ...@@ -225,7 +225,7 @@ type netFD struct {
wio sync.Mutex wio sync.Mutex
} }
func allocFD(fd, family, proto int, net string) (f *netFD) { func allocFD(fd syscall.Handle, family, proto int, net string) (f *netFD) {
f = &netFD{ f = &netFD{
sysfd: fd, sysfd: fd,
family: family, family: family,
...@@ -236,13 +236,13 @@ func allocFD(fd, family, proto int, net string) (f *netFD) { ...@@ -236,13 +236,13 @@ func allocFD(fd, family, proto int, net string) (f *netFD) {
return f return f
} }
func newFD(fd, family, proto int, net string) (f *netFD, err os.Error) { func newFD(fd syscall.Handle, family, proto int, net string) (f *netFD, err os.Error) {
if initErr != nil { if initErr != nil {
return nil, initErr return nil, initErr
} }
onceStartServer.Do(startServer) onceStartServer.Do(startServer)
// Associate our socket with resultsrv.iocp. // Associate our socket with resultsrv.iocp.
if _, e := syscall.CreateIoCompletionPort(int32(fd), resultsrv.iocp, 0, 0); e != 0 { if _, e := syscall.CreateIoCompletionPort(syscall.Handle(fd), resultsrv.iocp, 0, 0); e != 0 {
return nil, os.Errno(e) return nil, os.Errno(e)
} }
return allocFD(fd, family, proto, net), nil return allocFD(fd, family, proto, net), nil
...@@ -280,7 +280,7 @@ func (fd *netFD) decref() { ...@@ -280,7 +280,7 @@ func (fd *netFD) decref() {
// use the resultsrv for Close too. Sigh. // use the resultsrv for Close too. Sigh.
syscall.SetNonblock(fd.sysfd, false) syscall.SetNonblock(fd.sysfd, false)
closesocket(fd.sysfd) closesocket(fd.sysfd)
fd.sysfd = -1 fd.sysfd = syscall.InvalidHandle
// no need for a finalizer anymore // no need for a finalizer anymore
runtime.SetFinalizer(fd, nil) runtime.SetFinalizer(fd, nil)
} }
...@@ -288,7 +288,7 @@ func (fd *netFD) decref() { ...@@ -288,7 +288,7 @@ func (fd *netFD) decref() {
} }
func (fd *netFD) Close() os.Error { func (fd *netFD) Close() os.Error {
if fd == nil || fd.sysfd == -1 { if fd == nil || fd.sysfd == syscall.InvalidHandle {
return os.EINVAL return os.EINVAL
} }
...@@ -307,7 +307,7 @@ type readOp struct { ...@@ -307,7 +307,7 @@ type readOp struct {
func (o *readOp) Submit() (errno int) { func (o *readOp) Submit() (errno int) {
var d, f uint32 var d, f uint32
return syscall.WSARecv(uint32(o.fd.sysfd), &o.buf, 1, &d, &f, &o.o, nil) return syscall.WSARecv(syscall.Handle(o.fd.sysfd), &o.buf, 1, &d, &f, &o.o, nil)
} }
func (o *readOp) Name() string { func (o *readOp) Name() string {
...@@ -322,7 +322,7 @@ func (fd *netFD) Read(buf []byte) (n int, err os.Error) { ...@@ -322,7 +322,7 @@ func (fd *netFD) Read(buf []byte) (n int, err os.Error) {
defer fd.rio.Unlock() defer fd.rio.Unlock()
fd.incref() fd.incref()
defer fd.decref() defer fd.decref()
if fd.sysfd == -1 { if fd.sysfd == syscall.InvalidHandle {
return 0, os.EINVAL return 0, os.EINVAL
} }
var o readOp var o readOp
...@@ -344,7 +344,7 @@ type readFromOp struct { ...@@ -344,7 +344,7 @@ type readFromOp struct {
func (o *readFromOp) Submit() (errno int) { func (o *readFromOp) Submit() (errno int) {
var d, f uint32 var d, f uint32
l := int32(unsafe.Sizeof(o.rsa)) l := int32(unsafe.Sizeof(o.rsa))
return syscall.WSARecvFrom(uint32(o.fd.sysfd), &o.buf, 1, &d, &f, &o.rsa, &l, &o.o, nil) return syscall.WSARecvFrom(o.fd.sysfd, &o.buf, 1, &d, &f, &o.rsa, &l, &o.o, nil)
} }
func (o *readFromOp) Name() string { func (o *readFromOp) Name() string {
...@@ -362,7 +362,7 @@ func (fd *netFD) ReadFrom(buf []byte) (n int, sa syscall.Sockaddr, err os.Error) ...@@ -362,7 +362,7 @@ func (fd *netFD) ReadFrom(buf []byte) (n int, sa syscall.Sockaddr, err os.Error)
defer fd.rio.Unlock() defer fd.rio.Unlock()
fd.incref() fd.incref()
defer fd.decref() defer fd.decref()
if fd.sysfd == -1 { if fd.sysfd == syscall.InvalidHandle {
return 0, nil, os.EINVAL return 0, nil, os.EINVAL
} }
var o readFromOp var o readFromOp
...@@ -380,7 +380,7 @@ type writeOp struct { ...@@ -380,7 +380,7 @@ type writeOp struct {
func (o *writeOp) Submit() (errno int) { func (o *writeOp) Submit() (errno int) {
var d uint32 var d uint32
return syscall.WSASend(uint32(o.fd.sysfd), &o.buf, 1, &d, 0, &o.o, nil) return syscall.WSASend(o.fd.sysfd, &o.buf, 1, &d, 0, &o.o, nil)
} }
func (o *writeOp) Name() string { func (o *writeOp) Name() string {
...@@ -395,7 +395,7 @@ func (fd *netFD) Write(buf []byte) (n int, err os.Error) { ...@@ -395,7 +395,7 @@ func (fd *netFD) Write(buf []byte) (n int, err os.Error) {
defer fd.wio.Unlock() defer fd.wio.Unlock()
fd.incref() fd.incref()
defer fd.decref() defer fd.decref()
if fd.sysfd == -1 { if fd.sysfd == syscall.InvalidHandle {
return 0, os.EINVAL return 0, os.EINVAL
} }
var o writeOp var o writeOp
...@@ -412,7 +412,7 @@ type writeToOp struct { ...@@ -412,7 +412,7 @@ type writeToOp struct {
func (o *writeToOp) Submit() (errno int) { func (o *writeToOp) Submit() (errno int) {
var d uint32 var d uint32
return syscall.WSASendto(uint32(o.fd.sysfd), &o.buf, 1, &d, 0, o.sa, &o.o, nil) return syscall.WSASendto(o.fd.sysfd, &o.buf, 1, &d, 0, o.sa, &o.o, nil)
} }
func (o *writeToOp) Name() string { func (o *writeToOp) Name() string {
...@@ -430,7 +430,7 @@ func (fd *netFD) WriteTo(buf []byte, sa syscall.Sockaddr) (n int, err os.Error) ...@@ -430,7 +430,7 @@ func (fd *netFD) WriteTo(buf []byte, sa syscall.Sockaddr) (n int, err os.Error)
defer fd.wio.Unlock() defer fd.wio.Unlock()
fd.incref() fd.incref()
defer fd.decref() defer fd.decref()
if fd.sysfd == -1 { if fd.sysfd == syscall.InvalidHandle {
return 0, os.EINVAL return 0, os.EINVAL
} }
var o writeToOp var o writeToOp
...@@ -443,14 +443,14 @@ func (fd *netFD) WriteTo(buf []byte, sa syscall.Sockaddr) (n int, err os.Error) ...@@ -443,14 +443,14 @@ func (fd *netFD) WriteTo(buf []byte, sa syscall.Sockaddr) (n int, err os.Error)
type acceptOp struct { type acceptOp struct {
anOp anOp
newsock int newsock syscall.Handle
attrs [2]syscall.RawSockaddrAny // space for local and remote address only attrs [2]syscall.RawSockaddrAny // space for local and remote address only
} }
func (o *acceptOp) Submit() (errno int) { func (o *acceptOp) Submit() (errno int) {
var d uint32 var d uint32
l := uint32(unsafe.Sizeof(o.attrs[0])) l := uint32(unsafe.Sizeof(o.attrs[0]))
return syscall.AcceptEx(uint32(o.fd.sysfd), uint32(o.newsock), return syscall.AcceptEx(o.fd.sysfd, o.newsock,
(*byte)(unsafe.Pointer(&o.attrs[0])), 0, l, l, &d, &o.o) (*byte)(unsafe.Pointer(&o.attrs[0])), 0, l, l, &d, &o.o)
} }
...@@ -459,7 +459,7 @@ func (o *acceptOp) Name() string { ...@@ -459,7 +459,7 @@ func (o *acceptOp) Name() string {
} }
func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (nfd *netFD, err os.Error) { func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (nfd *netFD, err os.Error) {
if fd == nil || fd.sysfd == -1 { if fd == nil || fd.sysfd == syscall.InvalidHandle {
return nil, os.EINVAL return nil, os.EINVAL
} }
fd.incref() fd.incref()
...@@ -478,7 +478,7 @@ func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (nfd *netFD, err os. ...@@ -478,7 +478,7 @@ func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (nfd *netFD, err os.
// Associate our new socket with IOCP. // Associate our new socket with IOCP.
onceStartServer.Do(startServer) onceStartServer.Do(startServer)
if _, e = syscall.CreateIoCompletionPort(int32(s), resultsrv.iocp, 0, 0); e != 0 { if _, e = syscall.CreateIoCompletionPort(s, resultsrv.iocp, 0, 0); e != 0 {
return nil, &OpError{"CreateIoCompletionPort", fd.net, fd.laddr, os.Errno(e)} return nil, &OpError{"CreateIoCompletionPort", fd.net, fd.laddr, os.Errno(e)}
} }
...@@ -493,7 +493,7 @@ func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (nfd *netFD, err os. ...@@ -493,7 +493,7 @@ func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (nfd *netFD, err os.
} }
// Inherit properties of the listening socket. // Inherit properties of the listening socket.
e = syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_UPDATE_ACCEPT_CONTEXT, fd.sysfd) e = syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_UPDATE_ACCEPT_CONTEXT, int(fd.sysfd))
if e != 0 { if e != 0 {
closesocket(s) closesocket(s)
return nil, err return nil, err
......
...@@ -42,12 +42,12 @@ func getInterfaceList() ([]syscall.InterfaceInfo, os.Error) { ...@@ -42,12 +42,12 @@ func getInterfaceList() ([]syscall.InterfaceInfo, os.Error) {
if e != 0 { if e != 0 {
return nil, os.NewSyscallError("Socket", e) return nil, os.NewSyscallError("Socket", e)
} }
defer syscall.Closesocket(int32(s)) defer syscall.Closesocket(s)
ii := [20]syscall.InterfaceInfo{} ii := [20]syscall.InterfaceInfo{}
ret := uint32(0) ret := uint32(0)
size := uint32(unsafe.Sizeof(ii)) size := uint32(unsafe.Sizeof(ii))
e = syscall.WSAIoctl(int32(s), syscall.SIO_GET_INTERFACE_LIST, nil, 0, (*byte)(unsafe.Pointer(&ii[0])), size, &ret, nil, 0) e = syscall.WSAIoctl(s, syscall.SIO_GET_INTERFACE_LIST, nil, 0, (*byte)(unsafe.Pointer(&ii[0])), size, &ret, nil, 0)
if e != 0 { if e != 0 {
return nil, os.NewSyscallError("WSAIoctl", e) return nil, os.NewSyscallError("WSAIoctl", e)
} }
......
...@@ -26,28 +26,26 @@ import ( ...@@ -26,28 +26,26 @@ import (
// boolean value is true, kernel supports IPv6 IPv4-mapping. // boolean value is true, kernel supports IPv6 IPv4-mapping.
func probeIPv6Stack() (supportsIPv6, supportsIPv4map bool) { func probeIPv6Stack() (supportsIPv6, supportsIPv4map bool) {
var probes = []struct { var probes = []struct {
s int
la TCPAddr la TCPAddr
ok bool ok bool
}{ }{
// IPv6 communication capability // IPv6 communication capability
{-1, TCPAddr{IP: ParseIP("::1")}, false}, {TCPAddr{IP: ParseIP("::1")}, false},
// IPv6 IPv4-mapped address communication capability // IPv6 IPv4-mapped address communication capability
{-1, TCPAddr{IP: IPv4(127, 0, 0, 1)}, false}, {TCPAddr{IP: IPv4(127, 0, 0, 1)}, false},
} }
var errno int
for i := range probes { for i := range probes {
probes[i].s, errno = syscall.Socket(syscall.AF_INET6, syscall.SOCK_STREAM, syscall.IPPROTO_TCP) s, errno := syscall.Socket(syscall.AF_INET6, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
if errno != 0 { if errno != 0 {
continue continue
} }
defer closesocket(probes[i].s) defer closesocket(s)
sa, err := probes[i].la.toAddr().sockaddr(syscall.AF_INET6) sa, err := probes[i].la.toAddr().sockaddr(syscall.AF_INET6)
if err != nil { if err != nil {
continue continue
} }
errno = syscall.Bind(probes[i].s, sa) errno = syscall.Bind(s, sa)
if errno != 0 { if errno != 0 {
continue continue
} }
......
...@@ -12,12 +12,12 @@ import ( ...@@ -12,12 +12,12 @@ import (
type sendfileOp struct { type sendfileOp struct {
anOp anOp
src int32 // source src syscall.Handle // source
n uint32 n uint32
} }
func (o *sendfileOp) Submit() (errno int) { func (o *sendfileOp) Submit() (errno int) {
return syscall.TransmitFile(int32(o.fd.sysfd), o.src, o.n, 0, &o.o, nil, syscall.TF_WRITE_BEHIND) return syscall.TransmitFile(o.fd.sysfd, o.src, o.n, 0, &o.o, nil, syscall.TF_WRITE_BEHIND)
} }
func (o *sendfileOp) Name() string { func (o *sendfileOp) Name() string {
...@@ -56,7 +56,7 @@ func sendFile(c *netFD, r io.Reader) (written int64, err os.Error, handled bool) ...@@ -56,7 +56,7 @@ func sendFile(c *netFD, r io.Reader) (written int64, err os.Error, handled bool)
var o sendfileOp var o sendfileOp
o.Init(c) o.Init(c)
o.n = uint32(n) o.n = uint32(n)
o.src = int32(f.Fd()) o.src = f.Fd()
done, err := iosrv.ExecIO(&o, 0) done, err := iosrv.ExecIO(&o, 0)
if err != nil { if err != nil {
return 0, err, false return 0, err, false
......
...@@ -50,8 +50,7 @@ func socket(net string, f, p, t int, la, ra syscall.Sockaddr, toAddr func(syscal ...@@ -50,8 +50,7 @@ func socket(net string, f, p, t int, la, ra syscall.Sockaddr, toAddr func(syscal
if ra != nil { if ra != nil {
if err = fd.connect(ra); err != nil { if err = fd.connect(ra); err != nil {
fd.sysfd = -1 fd.Close()
closesocket(s)
return nil, err return nil, err
} }
} }
...@@ -65,25 +64,25 @@ func socket(net string, f, p, t int, la, ra syscall.Sockaddr, toAddr func(syscal ...@@ -65,25 +64,25 @@ func socket(net string, f, p, t int, la, ra syscall.Sockaddr, toAddr func(syscal
return fd, nil return fd, nil
} }
func setsockoptInt(fd, level, opt int, value int) os.Error { func setsockoptInt(fd *netFD, level, opt int, value int) os.Error {
return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, level, opt, value)) return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, level, opt, value))
} }
func setsockoptNsec(fd, level, opt int, nsec int64) os.Error { func setsockoptNsec(fd *netFD, level, opt int, nsec int64) os.Error {
var tv = syscall.NsecToTimeval(nsec) var tv = syscall.NsecToTimeval(nsec)
return os.NewSyscallError("setsockopt", syscall.SetsockoptTimeval(fd, level, opt, &tv)) return os.NewSyscallError("setsockopt", syscall.SetsockoptTimeval(fd.sysfd, level, opt, &tv))
} }
func setReadBuffer(fd *netFD, bytes int) os.Error { func setReadBuffer(fd *netFD, bytes int) os.Error {
fd.incref() fd.incref()
defer fd.decref() defer fd.decref()
return setsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_RCVBUF, bytes) return setsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_RCVBUF, bytes)
} }
func setWriteBuffer(fd *netFD, bytes int) os.Error { func setWriteBuffer(fd *netFD, bytes int) os.Error {
fd.incref() fd.incref()
defer fd.decref() defer fd.decref()
return setsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_SNDBUF, bytes) return setsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_SNDBUF, bytes)
} }
func setReadTimeout(fd *netFD, nsec int64) os.Error { func setReadTimeout(fd *netFD, nsec int64) os.Error {
...@@ -106,7 +105,7 @@ func setTimeout(fd *netFD, nsec int64) os.Error { ...@@ -106,7 +105,7 @@ func setTimeout(fd *netFD, nsec int64) os.Error {
func setReuseAddr(fd *netFD, reuse bool) os.Error { func setReuseAddr(fd *netFD, reuse bool) os.Error {
fd.incref() fd.incref()
defer fd.decref() defer fd.decref()
return setsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, boolint(reuse)) return setsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, boolint(reuse))
} }
func bindToDevice(fd *netFD, dev string) os.Error { func bindToDevice(fd *netFD, dev string) os.Error {
...@@ -117,19 +116,19 @@ func bindToDevice(fd *netFD, dev string) os.Error { ...@@ -117,19 +116,19 @@ func bindToDevice(fd *netFD, dev string) os.Error {
func setDontRoute(fd *netFD, dontroute bool) os.Error { func setDontRoute(fd *netFD, dontroute bool) os.Error {
fd.incref() fd.incref()
defer fd.decref() defer fd.decref()
return setsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_DONTROUTE, boolint(dontroute)) return setsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_DONTROUTE, boolint(dontroute))
} }
func setKeepAlive(fd *netFD, keepalive bool) os.Error { func setKeepAlive(fd *netFD, keepalive bool) os.Error {
fd.incref() fd.incref()
defer fd.decref() defer fd.decref()
return setsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, boolint(keepalive)) return setsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, boolint(keepalive))
} }
func setNoDelay(fd *netFD, noDelay bool) os.Error { func setNoDelay(fd *netFD, noDelay bool) os.Error {
fd.incref() fd.incref()
defer fd.decref() defer fd.decref()
return setsockoptInt(fd.sysfd, syscall.IPPROTO_TCP, syscall.TCP_NODELAY, boolint(noDelay)) return setsockoptInt(fd, syscall.IPPROTO_TCP, syscall.TCP_NODELAY, boolint(noDelay))
} }
func setLinger(fd *netFD, sec int) os.Error { func setLinger(fd *netFD, sec int) os.Error {
......
...@@ -10,7 +10,7 @@ import ( ...@@ -10,7 +10,7 @@ import (
"syscall" "syscall"
) )
func setKernelSpecificSockopt(s, f int) { func setKernelSpecificSockopt(s syscall.Handle, f int) {
// Allow reuse of recently-used addresses and ports. // Allow reuse of recently-used addresses and ports.
syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1) syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
......
...@@ -119,7 +119,7 @@ func init() { ...@@ -119,7 +119,7 @@ func init() {
if e != 0 { if e != 0 {
return return
} }
defer syscall.LocalFree(uint32(uintptr(unsafe.Pointer(argv)))) defer syscall.LocalFree(syscall.Handle(uintptr(unsafe.Pointer(argv))))
Args = make([]string, argc) Args = make([]string, argc)
for i, v := range (*argv)[:argc] { for i, v := range (*argv)[:argc] {
Args[i] = string(syscall.UTF16ToString((*v)[:])) Args[i] = string(syscall.UTF16ToString((*v)[:]))
......
...@@ -35,16 +35,9 @@ func StartProcess(name string, argv []string, attr *ProcAttr) (p *Process, err E ...@@ -35,16 +35,9 @@ func StartProcess(name string, argv []string, attr *ProcAttr) (p *Process, err E
if sysattr.Env == nil { if sysattr.Env == nil {
sysattr.Env = Environ() sysattr.Env = Environ()
} }
// Create array of integer (system) fds. for _, f := range attr.Files {
intfd := make([]int, len(attr.Files)) sysattr.Files = append(sysattr.Files, f.Fd())
for i, f := range attr.Files {
if f == nil {
intfd[i] = -1
} else {
intfd[i] = f.Fd()
} }
}
sysattr.Files = intfd
pid, h, e := syscall.StartProcess(name, argv, sysattr) pid, h, e := syscall.StartProcess(name, argv, sysattr)
if iserror(e) { if iserror(e) {
......
...@@ -10,7 +10,7 @@ import ( ...@@ -10,7 +10,7 @@ import (
) )
func (p *Process) Wait(options int) (w *Waitmsg, err Error) { func (p *Process) Wait(options int) (w *Waitmsg, err Error) {
s, e := syscall.WaitForSingleObject(int32(p.handle), syscall.INFINITE) s, e := syscall.WaitForSingleObject(syscall.Handle(p.handle), syscall.INFINITE)
switch s { switch s {
case syscall.WAIT_OBJECT_0: case syscall.WAIT_OBJECT_0:
break break
...@@ -20,7 +20,7 @@ func (p *Process) Wait(options int) (w *Waitmsg, err Error) { ...@@ -20,7 +20,7 @@ func (p *Process) Wait(options int) (w *Waitmsg, err Error) {
return nil, NewError("os: unexpected result from WaitForSingleObject") return nil, NewError("os: unexpected result from WaitForSingleObject")
} }
var ec uint32 var ec uint32
e = syscall.GetExitCodeProcess(int32(p.handle), &ec) e = syscall.GetExitCodeProcess(syscall.Handle(p.handle), &ec)
if e != 0 { if e != 0 {
return nil, NewSyscallError("GetExitCodeProcess", e) return nil, NewSyscallError("GetExitCodeProcess", e)
} }
...@@ -31,7 +31,7 @@ func (p *Process) Wait(options int) (w *Waitmsg, err Error) { ...@@ -31,7 +31,7 @@ func (p *Process) Wait(options int) (w *Waitmsg, err Error) {
func (p *Process) Signal(sig Signal) Error { func (p *Process) Signal(sig Signal) Error {
switch sig.(UnixSignal) { switch sig.(UnixSignal) {
case SIGKILL: case SIGKILL:
e := syscall.TerminateProcess(int32(p.handle), 1) e := syscall.TerminateProcess(syscall.Handle(p.handle), 1)
return NewSyscallError("TerminateProcess", e) return NewSyscallError("TerminateProcess", e)
} }
return Errno(syscall.EWINDOWS) return Errno(syscall.EWINDOWS)
...@@ -41,7 +41,7 @@ func (p *Process) Release() Error { ...@@ -41,7 +41,7 @@ func (p *Process) Release() Error {
if p.handle == -1 { if p.handle == -1 {
return EINVAL return EINVAL
} }
e := syscall.CloseHandle(int32(p.handle)) e := syscall.CloseHandle(syscall.Handle(p.handle))
if e != 0 { if e != 0 {
return NewSyscallError("CloseHandle", e) return NewSyscallError("CloseHandle", e)
} }
......
...@@ -9,36 +9,12 @@ ...@@ -9,36 +9,12 @@
package os package os
import ( import (
"runtime"
"sync"
"syscall" "syscall"
) )
// File represents an open file descriptor.
type File struct {
fd int
name string
dirinfo *dirInfo // nil unless directory being read
nepipe int // number of consecutive EPIPE in Write
l sync.Mutex // used to implement windows pread/pwrite
}
// Fd returns the integer Unix file descriptor referencing the open file.
func (file *File) Fd() int { return file.fd }
// Name returns the name of the file as presented to Open. // Name returns the name of the file as presented to Open.
func (file *File) Name() string { return file.name } func (file *File) Name() string { return file.name }
// NewFile returns a new File with the given file descriptor and name.
func NewFile(fd int, name string) *File {
if fd < 0 {
return nil
}
f := &File{fd: fd, name: name}
runtime.SetFinalizer(f, (*File).Close)
return f
}
// Stdin, Stdout, and Stderr are open Files pointing to the standard input, // Stdin, Stdout, and Stderr are open Files pointing to the standard input,
// standard output, and standard error file descriptors. // standard output, and standard error file descriptors.
var ( var (
......
...@@ -21,26 +21,6 @@ func epipecheck(file *File, e int) { ...@@ -21,26 +21,6 @@ func epipecheck(file *File, e int) {
} }
} }
// Pipe returns a connected pair of Files; reads from r return bytes written to w.
// It returns the files and an Error, if any.
func Pipe() (r *File, w *File, err Error) {
var p [2]int
// See ../syscall/exec.go for description of lock.
syscall.ForkLock.RLock()
e := syscall.Pipe(p[0:])
if iserror(e) {
syscall.ForkLock.RUnlock()
return nil, nil, NewSyscallError("pipe", e)
}
syscall.CloseOnExec(p[0])
syscall.CloseOnExec(p[1])
syscall.ForkLock.RUnlock()
return NewFile(p[0], "|0"), NewFile(p[1], "|1"), nil
}
// Stat returns a FileInfo structure describing the named file and an error, if any. // Stat returns a FileInfo structure describing the named file and an error, if any.
// If name names a valid symbolic link, the returned FileInfo describes // If name names a valid symbolic link, the returned FileInfo describes
// the file pointed at by the link and has fi.FollowedSymlink set to true. // the file pointed at by the link and has fi.FollowedSymlink set to true.
......
...@@ -6,9 +6,37 @@ package os ...@@ -6,9 +6,37 @@ package os
import ( import (
"runtime" "runtime"
"sync"
"syscall" "syscall"
) )
// File represents an open file descriptor.
type File struct {
fd int
name string
dirinfo *dirInfo // nil unless directory being read
nepipe int // number of consecutive EPIPE in Write
l sync.Mutex // used to implement windows pread/pwrite
}
// Fd returns the integer Unix file descriptor referencing the open file.
func (file *File) Fd() int {
if file == nil {
return -1
}
return file.fd
}
// NewFile returns a new File with the given file descriptor and name.
func NewFile(fd int, name string) *File {
if fd < 0 {
return nil
}
f := &File{fd: fd, name: name}
runtime.SetFinalizer(f, (*File).Close)
return f
}
// Auxiliary information if the File describes a directory // Auxiliary information if the File describes a directory
type dirInfo struct { type dirInfo struct {
buf []byte // buffer for directory I/O buf []byte // buffer for directory I/O
...@@ -161,3 +189,22 @@ func basename(name string) string { ...@@ -161,3 +189,22 @@ func basename(name string) string {
return name return name
} }
// Pipe returns a connected pair of Files; reads from r return bytes written to w.
// It returns the files and an Error, if any.
func Pipe() (r *File, w *File, err Error) {
var p [2]int
// See ../syscall/exec.go for description of lock.
syscall.ForkLock.RLock()
e := syscall.Pipe(p[0:])
if iserror(e) {
syscall.ForkLock.RUnlock()
return nil, nil, NewSyscallError("pipe", e)
}
syscall.CloseOnExec(p[0])
syscall.CloseOnExec(p[1])
syscall.ForkLock.RUnlock()
return NewFile(p[0], "|0"), NewFile(p[1], "|1"), nil
}
...@@ -6,9 +6,37 @@ package os ...@@ -6,9 +6,37 @@ package os
import ( import (
"runtime" "runtime"
"sync"
"syscall" "syscall"
) )
// File represents an open file descriptor.
type File struct {
fd syscall.Handle
name string
dirinfo *dirInfo // nil unless directory being read
nepipe int // number of consecutive EPIPE in Write
l sync.Mutex // used to implement windows pread/pwrite
}
// Fd returns the Windows handle referencing the open file.
func (file *File) Fd() syscall.Handle {
if file == nil {
return syscall.InvalidHandle
}
return file.fd
}
// NewFile returns a new File with the given file descriptor and name.
func NewFile(fd syscall.Handle, name string) *File {
if fd < 0 {
return nil
}
f := &File{fd: fd, name: name}
runtime.SetFinalizer(f, (*File).Close)
return f
}
// Auxiliary information if the File describes a directory // Auxiliary information if the File describes a directory
type dirInfo struct { type dirInfo struct {
stat syscall.Stat_t stat syscall.Stat_t
...@@ -40,7 +68,7 @@ func openDir(name string) (file *File, err Error) { ...@@ -40,7 +68,7 @@ func openDir(name string) (file *File, err Error) {
if e != 0 { if e != 0 {
return nil, &PathError{"open", name, Errno(e)} return nil, &PathError{"open", name, Errno(e)}
} }
f := NewFile(int(r), name) f := NewFile(r, name)
d.usefirststat = true d.usefirststat = true
f.dirinfo = d f.dirinfo = d
return f, nil return f, nil
...@@ -85,15 +113,15 @@ func (file *File) Close() Error { ...@@ -85,15 +113,15 @@ func (file *File) Close() Error {
} }
var e int var e int
if file.isdir() { if file.isdir() {
e = syscall.FindClose(int32(file.fd)) e = syscall.FindClose(syscall.Handle(file.fd))
} else { } else {
e = syscall.CloseHandle(int32(file.fd)) e = syscall.CloseHandle(syscall.Handle(file.fd))
} }
var err Error var err Error
if e != 0 { if e != 0 {
err = &PathError{"close", file.name, Errno(e)} err = &PathError{"close", file.name, Errno(e)}
} }
file.fd = -1 // so it can't be closed again file.fd = syscall.InvalidHandle // so it can't be closed again
// no need for a finalizer anymore // no need for a finalizer anymore
runtime.SetFinalizer(file, nil) runtime.SetFinalizer(file, nil)
...@@ -102,7 +130,7 @@ func (file *File) Close() Error { ...@@ -102,7 +130,7 @@ func (file *File) Close() Error {
func (file *File) statFile(name string) (fi *FileInfo, err Error) { func (file *File) statFile(name string) (fi *FileInfo, err Error) {
var stat syscall.ByHandleFileInformation var stat syscall.ByHandleFileInformation
e := syscall.GetFileInformationByHandle(int32(file.fd), &stat) e := syscall.GetFileInformationByHandle(syscall.Handle(file.fd), &stat)
if e != 0 { if e != 0 {
return nil, &PathError{"stat", file.name, Errno(e)} return nil, &PathError{"stat", file.name, Errno(e)}
} }
...@@ -156,7 +184,7 @@ func (file *File) Readdir(n int) (fi []FileInfo, err Error) { ...@@ -156,7 +184,7 @@ func (file *File) Readdir(n int) (fi []FileInfo, err Error) {
if di.usefirststat { if di.usefirststat {
di.usefirststat = false di.usefirststat = false
} else { } else {
e := syscall.FindNextFile(int32(file.fd), &di.stat.Windata) e := syscall.FindNextFile(syscall.Handle(file.fd), &di.stat.Windata)
if e != 0 { if e != 0 {
if e == syscall.ERROR_NO_MORE_FILES { if e == syscall.ERROR_NO_MORE_FILES {
break break
...@@ -207,7 +235,7 @@ func (f *File) pread(b []byte, off int64) (n int, err int) { ...@@ -207,7 +235,7 @@ func (f *File) pread(b []byte, off int64) (n int, err int) {
Offset: uint32(off), Offset: uint32(off),
} }
var done uint32 var done uint32
e = syscall.ReadFile(int32(f.fd), b, &done, &o) e = syscall.ReadFile(syscall.Handle(f.fd), b, &done, &o)
if e != 0 { if e != 0 {
return 0, e return 0, e
} }
...@@ -237,7 +265,7 @@ func (f *File) pwrite(b []byte, off int64) (n int, err int) { ...@@ -237,7 +265,7 @@ func (f *File) pwrite(b []byte, off int64) (n int, err int) {
Offset: uint32(off), Offset: uint32(off),
} }
var done uint32 var done uint32
e = syscall.WriteFile(int32(f.fd), b, &done, &o) e = syscall.WriteFile(syscall.Handle(f.fd), b, &done, &o)
if e != 0 { if e != 0 {
return 0, e return 0, e
} }
...@@ -268,3 +296,22 @@ func Truncate(name string, size int64) Error { ...@@ -268,3 +296,22 @@ func Truncate(name string, size int64) Error {
} }
return nil return nil
} }
// Pipe returns a connected pair of Files; reads from r return bytes written to w.
// It returns the files and an Error, if any.
func Pipe() (r *File, w *File, err Error) {
var p [2]syscall.Handle
// See ../syscall/exec.go for description of lock.
syscall.ForkLock.RLock()
e := syscall.Pipe(p[0:])
if iserror(e) {
syscall.ForkLock.RUnlock()
return nil, nil, NewSyscallError("pipe", e)
}
syscall.CloseOnExec(p[0])
syscall.CloseOnExec(p[1])
syscall.ForkLock.RUnlock()
return NewFile(p[0], "|0"), NewFile(p[1], "|1"), nil
}
...@@ -121,11 +121,11 @@ func createEnvBlock(envv []string) *uint16 { ...@@ -121,11 +121,11 @@ func createEnvBlock(envv []string) *uint16 {
return &utf16.Encode([]int(string(b)))[0] return &utf16.Encode([]int(string(b)))[0]
} }
func CloseOnExec(fd int) { func CloseOnExec(fd Handle) {
SetHandleInformation(int32(fd), HANDLE_FLAG_INHERIT, 0) SetHandleInformation(Handle(fd), HANDLE_FLAG_INHERIT, 0)
} }
func SetNonblock(fd int, nonblocking bool) (errno int) { func SetNonblock(fd Handle, nonblocking bool) (errno int) {
return 0 return 0
} }
...@@ -220,7 +220,7 @@ func joinExeDirAndFName(dir, p string) (name string, err int) { ...@@ -220,7 +220,7 @@ func joinExeDirAndFName(dir, p string) (name string, err int) {
type ProcAttr struct { type ProcAttr struct {
Dir string Dir string
Env []string Env []string
Files []int Files []Handle
Sys *SysProcAttr Sys *SysProcAttr
} }
...@@ -290,14 +290,14 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid, handle int, ...@@ -290,14 +290,14 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid, handle int,
defer ForkLock.Unlock() defer ForkLock.Unlock()
p, _ := GetCurrentProcess() p, _ := GetCurrentProcess()
fd := make([]int32, len(attr.Files)) fd := make([]Handle, len(attr.Files))
for i := range attr.Files { for i := range attr.Files {
if attr.Files[i] > 0 { if attr.Files[i] > 0 {
err := DuplicateHandle(p, int32(attr.Files[i]), p, &fd[i], 0, true, DUPLICATE_SAME_ACCESS) err := DuplicateHandle(p, Handle(attr.Files[i]), p, &fd[i], 0, true, DUPLICATE_SAME_ACCESS)
if err != 0 { if err != 0 {
return 0, 0, err return 0, 0, err
} }
defer CloseHandle(int32(fd[i])) defer CloseHandle(Handle(fd[i]))
} }
} }
si := new(StartupInfo) si := new(StartupInfo)
...@@ -317,7 +317,7 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid, handle int, ...@@ -317,7 +317,7 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid, handle int,
if err != 0 { if err != 0 {
return 0, 0, err return 0, 0, err
} }
defer CloseHandle(pi.Thread) defer CloseHandle(Handle(pi.Thread))
return int(pi.ProcessId), int(pi.Process), 0 return int(pi.ProcessId), int(pi.Process), 0
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -216,7 +216,7 @@ type Overlapped struct { ...@@ -216,7 +216,7 @@ type Overlapped struct {
InternalHigh uint32 InternalHigh uint32
Offset uint32 Offset uint32
OffsetHigh uint32 OffsetHigh uint32
HEvent int32 HEvent Handle
} }
type Filetime struct { type Filetime struct {
...@@ -306,14 +306,14 @@ type StartupInfo struct { ...@@ -306,14 +306,14 @@ type StartupInfo struct {
ShowWindow uint16 ShowWindow uint16
_ uint16 _ uint16
_ *byte _ *byte
StdInput int32 StdInput Handle
StdOutput int32 StdOutput Handle
StdErr int32 StdErr Handle
} }
type ProcessInformation struct { type ProcessInformation struct {
Process int32 Process Handle
Thread int32 Thread Handle
ProcessId uint32 ProcessId uint32
ThreadId uint32 ThreadId uint32
} }
......
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