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
diff --git a/src/pkg/os/env_windows.go b/src/pkg/os/env_windows.go
index a45d79b..e6ddc40 100644
--- a/src/pkg/os/env_windows.go
+++ b/src/pkg/os/env_windows.go
@@ -119,7 +119,7 @@
if e != 0 {
return
}
- defer syscall.LocalFree(uint32(uintptr(unsafe.Pointer(argv))))
+ defer syscall.LocalFree(syscall.Handle(uintptr(unsafe.Pointer(argv))))
Args = make([]string, argc)
for i, v := range (*argv)[:argc] {
Args[i] = string(syscall.UTF16ToString((*v)[:]))
diff --git a/src/pkg/os/exec_posix.go b/src/pkg/os/exec_posix.go
index 7dfcdd4..e209770 100644
--- a/src/pkg/os/exec_posix.go
+++ b/src/pkg/os/exec_posix.go
@@ -35,16 +35,9 @@
if sysattr.Env == nil {
sysattr.Env = Environ()
}
- // Create array of integer (system) fds.
- intfd := make([]int, len(attr.Files))
- for i, f := range attr.Files {
- if f == nil {
- intfd[i] = -1
- } else {
- intfd[i] = f.Fd()
- }
+ for _, f := range attr.Files {
+ sysattr.Files = append(sysattr.Files, f.Fd())
}
- sysattr.Files = intfd
pid, h, e := syscall.StartProcess(name, argv, sysattr)
if iserror(e) {
diff --git a/src/pkg/os/exec_windows.go b/src/pkg/os/exec_windows.go
index 991099d..5b432d3 100644
--- a/src/pkg/os/exec_windows.go
+++ b/src/pkg/os/exec_windows.go
@@ -10,7 +10,7 @@
)
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 {
case syscall.WAIT_OBJECT_0:
break
@@ -20,7 +20,7 @@
return nil, NewError("os: unexpected result from WaitForSingleObject")
}
var ec uint32
- e = syscall.GetExitCodeProcess(int32(p.handle), &ec)
+ e = syscall.GetExitCodeProcess(syscall.Handle(p.handle), &ec)
if e != 0 {
return nil, NewSyscallError("GetExitCodeProcess", e)
}
@@ -31,7 +31,7 @@
func (p *Process) Signal(sig Signal) Error {
switch sig.(UnixSignal) {
case SIGKILL:
- e := syscall.TerminateProcess(int32(p.handle), 1)
+ e := syscall.TerminateProcess(syscall.Handle(p.handle), 1)
return NewSyscallError("TerminateProcess", e)
}
return Errno(syscall.EWINDOWS)
@@ -41,7 +41,7 @@
if p.handle == -1 {
return EINVAL
}
- e := syscall.CloseHandle(int32(p.handle))
+ e := syscall.CloseHandle(syscall.Handle(p.handle))
if e != 0 {
return NewSyscallError("CloseHandle", e)
}
diff --git a/src/pkg/os/file.go b/src/pkg/os/file.go
index 1b8faec..4335d45 100644
--- a/src/pkg/os/file.go
+++ b/src/pkg/os/file.go
@@ -9,36 +9,12 @@
package os
import (
- "runtime"
- "sync"
"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.
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,
// standard output, and standard error file descriptors.
var (
diff --git a/src/pkg/os/file_posix.go b/src/pkg/os/file_posix.go
index 05db6bc..0791a0d 100644
--- a/src/pkg/os/file_posix.go
+++ b/src/pkg/os/file_posix.go
@@ -21,26 +21,6 @@
}
}
-
-// 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.
// 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.
diff --git a/src/pkg/os/file_unix.go b/src/pkg/os/file_unix.go
index def9b3b..bda6a1e 100644
--- a/src/pkg/os/file_unix.go
+++ b/src/pkg/os/file_unix.go
@@ -6,9 +6,37 @@
import (
"runtime"
+ "sync"
"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
type dirInfo struct {
buf []byte // buffer for directory I/O
@@ -161,3 +189,22 @@
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
+}
diff --git a/src/pkg/os/file_windows.go b/src/pkg/os/file_windows.go
index 80886f6..70dd6e2 100644
--- a/src/pkg/os/file_windows.go
+++ b/src/pkg/os/file_windows.go
@@ -6,9 +6,37 @@
import (
"runtime"
+ "sync"
"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
type dirInfo struct {
stat syscall.Stat_t
@@ -40,7 +68,7 @@
if e != 0 {
return nil, &PathError{"open", name, Errno(e)}
}
- f := NewFile(int(r), name)
+ f := NewFile(r, name)
d.usefirststat = true
f.dirinfo = d
return f, nil
@@ -85,15 +113,15 @@
}
var e int
if file.isdir() {
- e = syscall.FindClose(int32(file.fd))
+ e = syscall.FindClose(syscall.Handle(file.fd))
} else {
- e = syscall.CloseHandle(int32(file.fd))
+ e = syscall.CloseHandle(syscall.Handle(file.fd))
}
var err Error
if e != 0 {
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
runtime.SetFinalizer(file, nil)
@@ -102,7 +130,7 @@
func (file *File) statFile(name string) (fi *FileInfo, err Error) {
var stat syscall.ByHandleFileInformation
- e := syscall.GetFileInformationByHandle(int32(file.fd), &stat)
+ e := syscall.GetFileInformationByHandle(syscall.Handle(file.fd), &stat)
if e != 0 {
return nil, &PathError{"stat", file.name, Errno(e)}
}
@@ -156,7 +184,7 @@
if di.usefirststat {
di.usefirststat = false
} 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 == syscall.ERROR_NO_MORE_FILES {
break
@@ -207,7 +235,7 @@
Offset: uint32(off),
}
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 {
return 0, e
}
@@ -237,7 +265,7 @@
Offset: uint32(off),
}
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 {
return 0, e
}
@@ -268,3 +296,22 @@
}
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
+}