Merge pull request #2626 from hashicorp/f-remove-win-cgo
Update go-winio to remove cgo on Windows
This commit is contained in:
commit
13aa9ed776
|
@ -64,11 +64,15 @@ for target in $targets; do
|
||||||
;;
|
;;
|
||||||
"windows_386")
|
"windows_386")
|
||||||
echo "==> Building windows 386..."
|
echo "==> Building windows 386..."
|
||||||
CGO_ENABLED=1 CXX=i686-w64-mingw32-g++ CC=i686-w64-mingw32-gcc GOARCH="386" GOOS="windows" go build -ldflags "-X $LDFLAG" -o "pkg/windows_386/nomad.exe"
|
CGO_ENABLED=0 GOARCH="386" GOOS="windows" go build -ldflags "-X $LDFLAG" -o "pkg/windows_386/nomad.exe"
|
||||||
|
# Use the following if CGO is required
|
||||||
|
#CGO_ENABLED=1 CXX=i686-w64-mingw32-g++ CC=i686-w64-mingw32-gcc GOARCH="386" GOOS="windows" go build -ldflags "-X $LDFLAG" -o "pkg/windows_386/nomad.exe"
|
||||||
;;
|
;;
|
||||||
"windows_amd64")
|
"windows_amd64")
|
||||||
echo "==> Building windows amd64..."
|
echo "==> Building windows amd64..."
|
||||||
CGO_ENABLED=1 CXX=x86_64-w64-mingw32-g++ CC=x86_64-w64-mingw32-gcc GOARCH="amd64" GOOS="windows" go build -ldflags "-X $LDFLAG" -o "pkg/windows_amd64/nomad.exe"
|
CGO_ENABLED=0 GOARCH="amd64" GOOS="windows" go build -ldflags "-X $LDFLAG" -o "pkg/windows_amd64/nomad.exe"
|
||||||
|
# Use the following if CGO is required
|
||||||
|
#CGO_ENABLED=1 CXX=x86_64-w64-mingw32-g++ CC=x86_64-w64-mingw32-gcc GOARCH="amd64" GOOS="windows" go build -ldflags "-X $LDFLAG" -o "pkg/windows_amd64/nomad.exe"
|
||||||
;;
|
;;
|
||||||
"darwin_amd64")
|
"darwin_amd64")
|
||||||
echo "==> Building darwin amd64..."
|
echo "==> Building darwin amd64..."
|
||||||
|
|
151
vendor/github.com/Microsoft/go-winio/file.go
generated
vendored
151
vendor/github.com/Microsoft/go-winio/file.go
generated
vendored
|
@ -7,6 +7,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -17,6 +18,12 @@ import (
|
||||||
//sys setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes
|
//sys setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes
|
||||||
//sys timeBeginPeriod(period uint32) (n int32) = winmm.timeBeginPeriod
|
//sys timeBeginPeriod(period uint32) (n int32) = winmm.timeBeginPeriod
|
||||||
|
|
||||||
|
type atomicBool int32
|
||||||
|
|
||||||
|
func (b *atomicBool) isSet() bool { return atomic.LoadInt32((*int32)(b)) != 0 }
|
||||||
|
func (b *atomicBool) setFalse() { atomic.StoreInt32((*int32)(b), 0) }
|
||||||
|
func (b *atomicBool) setTrue() { atomic.StoreInt32((*int32)(b), 1) }
|
||||||
|
|
||||||
const (
|
const (
|
||||||
cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1
|
cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1
|
||||||
cFILE_SKIP_SET_EVENT_ON_HANDLE = 2
|
cFILE_SKIP_SET_EVENT_ON_HANDLE = 2
|
||||||
|
@ -33,6 +40,8 @@ func (e *timeoutError) Error() string { return "i/o timeout" }
|
||||||
func (e *timeoutError) Timeout() bool { return true }
|
func (e *timeoutError) Timeout() bool { return true }
|
||||||
func (e *timeoutError) Temporary() bool { return true }
|
func (e *timeoutError) Temporary() bool { return true }
|
||||||
|
|
||||||
|
type timeoutChan chan struct{}
|
||||||
|
|
||||||
var ioInitOnce sync.Once
|
var ioInitOnce sync.Once
|
||||||
var ioCompletionPort syscall.Handle
|
var ioCompletionPort syscall.Handle
|
||||||
|
|
||||||
|
@ -63,8 +72,16 @@ type win32File struct {
|
||||||
handle syscall.Handle
|
handle syscall.Handle
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
closing bool
|
closing bool
|
||||||
readDeadline time.Time
|
readDeadline deadlineHandler
|
||||||
writeDeadline time.Time
|
writeDeadline deadlineHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
type deadlineHandler struct {
|
||||||
|
setLock sync.Mutex
|
||||||
|
channel timeoutChan
|
||||||
|
channelLock sync.RWMutex
|
||||||
|
timer *time.Timer
|
||||||
|
timedout atomicBool
|
||||||
}
|
}
|
||||||
|
|
||||||
// makeWin32File makes a new win32File from an existing file handle
|
// makeWin32File makes a new win32File from an existing file handle
|
||||||
|
@ -79,6 +96,8 @@ func makeWin32File(h syscall.Handle) (*win32File, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
f.readDeadline.channel = make(timeoutChan)
|
||||||
|
f.writeDeadline.channel = make(timeoutChan)
|
||||||
return f, nil
|
return f, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,53 +153,47 @@ func ioCompletionProcessor(h syscall.Handle) {
|
||||||
|
|
||||||
// asyncIo processes the return value from ReadFile or WriteFile, blocking until
|
// asyncIo processes the return value from ReadFile or WriteFile, blocking until
|
||||||
// the operation has actually completed.
|
// the operation has actually completed.
|
||||||
func (f *win32File) asyncIo(c *ioOperation, deadline time.Time, bytes uint32, err error) (int, error) {
|
func (f *win32File) asyncIo(c *ioOperation, d *deadlineHandler, bytes uint32, err error) (int, error) {
|
||||||
if err != syscall.ERROR_IO_PENDING {
|
if err != syscall.ERROR_IO_PENDING {
|
||||||
f.wg.Done()
|
f.wg.Done()
|
||||||
return int(bytes), err
|
return int(bytes), err
|
||||||
} else {
|
}
|
||||||
var r ioResult
|
|
||||||
wait := true
|
|
||||||
timedout := false
|
|
||||||
if f.closing {
|
|
||||||
cancelIoEx(f.handle, &c.o)
|
|
||||||
} else if !deadline.IsZero() {
|
|
||||||
now := time.Now()
|
|
||||||
if !deadline.After(now) {
|
|
||||||
timedout = true
|
|
||||||
} else {
|
|
||||||
timeout := time.After(deadline.Sub(now))
|
|
||||||
select {
|
|
||||||
case r = <-c.ch:
|
|
||||||
wait = false
|
|
||||||
case <-timeout:
|
|
||||||
timedout = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if timedout {
|
|
||||||
cancelIoEx(f.handle, &c.o)
|
|
||||||
}
|
|
||||||
if wait {
|
|
||||||
r = <-c.ch
|
|
||||||
}
|
|
||||||
|
|
||||||
// runtime.KeepAlive is needed, as c is passed via native
|
if f.closing {
|
||||||
// code to ioCompletionProcessor, c must remain alive
|
cancelIoEx(f.handle, &c.o)
|
||||||
// until the channel read is complete.
|
}
|
||||||
runtime.KeepAlive(c)
|
|
||||||
|
|
||||||
|
var timeout timeoutChan
|
||||||
|
if d != nil {
|
||||||
|
d.channelLock.Lock()
|
||||||
|
timeout = d.channel
|
||||||
|
d.channelLock.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
var r ioResult
|
||||||
|
select {
|
||||||
|
case r = <-c.ch:
|
||||||
err = r.err
|
err = r.err
|
||||||
if err == syscall.ERROR_OPERATION_ABORTED {
|
if err == syscall.ERROR_OPERATION_ABORTED {
|
||||||
if f.closing {
|
if f.closing {
|
||||||
err = ErrFileClosed
|
err = ErrFileClosed
|
||||||
} else if timedout {
|
|
||||||
err = ErrTimeout
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f.wg.Done()
|
case <-timeout:
|
||||||
return int(r.bytes), err
|
cancelIoEx(f.handle, &c.o)
|
||||||
|
r = <-c.ch
|
||||||
|
err = r.err
|
||||||
|
if err == syscall.ERROR_OPERATION_ABORTED {
|
||||||
|
err = ErrTimeout
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// runtime.KeepAlive is needed, as c is passed via native
|
||||||
|
// code to ioCompletionProcessor, c must remain alive
|
||||||
|
// until the channel read is complete.
|
||||||
|
runtime.KeepAlive(c)
|
||||||
|
f.wg.Done()
|
||||||
|
return int(r.bytes), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read reads from a file handle.
|
// Read reads from a file handle.
|
||||||
|
@ -189,9 +202,14 @@ func (f *win32File) Read(b []byte) (int, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if f.readDeadline.timedout.isSet() {
|
||||||
|
return 0, ErrTimeout
|
||||||
|
}
|
||||||
|
|
||||||
var bytes uint32
|
var bytes uint32
|
||||||
err = syscall.ReadFile(f.handle, b, &bytes, &c.o)
|
err = syscall.ReadFile(f.handle, b, &bytes, &c.o)
|
||||||
n, err := f.asyncIo(c, f.readDeadline, bytes, err)
|
n, err := f.asyncIo(c, &f.readDeadline, bytes, err)
|
||||||
runtime.KeepAlive(b)
|
runtime.KeepAlive(b)
|
||||||
|
|
||||||
// Handle EOF conditions.
|
// Handle EOF conditions.
|
||||||
|
@ -210,23 +228,66 @@ func (f *win32File) Write(b []byte) (int, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
if f.writeDeadline.timedout.isSet() {
|
||||||
|
return 0, ErrTimeout
|
||||||
|
}
|
||||||
|
|
||||||
var bytes uint32
|
var bytes uint32
|
||||||
err = syscall.WriteFile(f.handle, b, &bytes, &c.o)
|
err = syscall.WriteFile(f.handle, b, &bytes, &c.o)
|
||||||
n, err := f.asyncIo(c, f.writeDeadline, bytes, err)
|
n, err := f.asyncIo(c, &f.writeDeadline, bytes, err)
|
||||||
runtime.KeepAlive(b)
|
runtime.KeepAlive(b)
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *win32File) SetReadDeadline(t time.Time) error {
|
func (f *win32File) SetReadDeadline(deadline time.Time) error {
|
||||||
f.readDeadline = t
|
return f.readDeadline.set(deadline)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *win32File) SetWriteDeadline(t time.Time) error {
|
func (f *win32File) SetWriteDeadline(deadline time.Time) error {
|
||||||
f.writeDeadline = t
|
return f.writeDeadline.set(deadline)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *win32File) Flush() error {
|
func (f *win32File) Flush() error {
|
||||||
return syscall.FlushFileBuffers(f.handle)
|
return syscall.FlushFileBuffers(f.handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *deadlineHandler) set(deadline time.Time) error {
|
||||||
|
d.setLock.Lock()
|
||||||
|
defer d.setLock.Unlock()
|
||||||
|
|
||||||
|
if d.timer != nil {
|
||||||
|
if !d.timer.Stop() {
|
||||||
|
<-d.channel
|
||||||
|
}
|
||||||
|
d.timer = nil
|
||||||
|
}
|
||||||
|
d.timedout.setFalse()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-d.channel:
|
||||||
|
d.channelLock.Lock()
|
||||||
|
d.channel = make(chan struct{})
|
||||||
|
d.channelLock.Unlock()
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
if deadline.IsZero() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
timeoutIO := func() {
|
||||||
|
d.timedout.setTrue()
|
||||||
|
close(d.channel)
|
||||||
|
}
|
||||||
|
|
||||||
|
now := time.Now()
|
||||||
|
duration := deadline.Sub(now)
|
||||||
|
if deadline.After(now) {
|
||||||
|
// Deadline is in the future, set a timer to wait
|
||||||
|
d.timer = time.AfterFunc(duration, timeoutIO)
|
||||||
|
} else {
|
||||||
|
// Deadline is in the past. Cancel all pending IO now.
|
||||||
|
timeoutIO()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
15
vendor/github.com/Microsoft/go-winio/pipe.go
generated
vendored
15
vendor/github.com/Microsoft/go-winio/pipe.go
generated
vendored
|
@ -2,9 +2,6 @@
|
||||||
|
|
||||||
package winio
|
package winio
|
||||||
|
|
||||||
// #include <stdlib.h>
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
|
@ -21,10 +18,12 @@ import (
|
||||||
//sys waitNamedPipe(name string, timeout uint32) (err error) = WaitNamedPipeW
|
//sys waitNamedPipe(name string, timeout uint32) (err error) = WaitNamedPipeW
|
||||||
//sys getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) = GetNamedPipeInfo
|
//sys getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) = GetNamedPipeInfo
|
||||||
//sys getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW
|
//sys getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW
|
||||||
|
//sys localAlloc(uFlags uint32, length uint32) (ptr uintptr) = LocalAlloc
|
||||||
|
//sys copyMemory(dst uintptr, src uintptr, length uint32) = RtlCopyMemory
|
||||||
|
|
||||||
type securityAttributes struct {
|
type securityAttributes struct {
|
||||||
Length uint32
|
Length uint32
|
||||||
SecurityDescriptor unsafe.Pointer
|
SecurityDescriptor uintptr
|
||||||
InheritHandle uint32
|
InheritHandle uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,8 +236,10 @@ func makeServerPipeHandle(path string, securityDescriptor []byte, c *PipeConfig,
|
||||||
sa := &securityAttributes{}
|
sa := &securityAttributes{}
|
||||||
sa.Length = uint32(unsafe.Sizeof(*sa))
|
sa.Length = uint32(unsafe.Sizeof(*sa))
|
||||||
if securityDescriptor != nil {
|
if securityDescriptor != nil {
|
||||||
sa.SecurityDescriptor = C.CBytes(securityDescriptor)
|
len := uint32(len(securityDescriptor))
|
||||||
defer C.free(sa.SecurityDescriptor)
|
sa.SecurityDescriptor = localAlloc(0, len)
|
||||||
|
defer localFree(sa.SecurityDescriptor)
|
||||||
|
copyMemory(sa.SecurityDescriptor, uintptr(unsafe.Pointer(&securityDescriptor[0])), len)
|
||||||
}
|
}
|
||||||
h, err := createNamedPipe(path, flags, mode, cPIPE_UNLIMITED_INSTANCES, uint32(c.OutputBufferSize), uint32(c.InputBufferSize), 0, sa)
|
h, err := createNamedPipe(path, flags, mode, cPIPE_UNLIMITED_INSTANCES, uint32(c.OutputBufferSize), uint32(c.InputBufferSize), 0, sa)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -367,7 +368,7 @@ func connectPipe(p *win32File) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = connectNamedPipe(p.handle, &c.o)
|
err = connectNamedPipe(p.handle, &c.o)
|
||||||
_, err = p.asyncIo(c, time.Time{}, 0, err)
|
_, err = p.asyncIo(c, nil, 0, err)
|
||||||
if err != nil && err != cERROR_PIPE_CONNECTED {
|
if err != nil && err != cERROR_PIPE_CONNECTED {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
13
vendor/github.com/Microsoft/go-winio/zsyscall_windows.go
generated
vendored
13
vendor/github.com/Microsoft/go-winio/zsyscall_windows.go
generated
vendored
|
@ -52,6 +52,8 @@ var (
|
||||||
procWaitNamedPipeW = modkernel32.NewProc("WaitNamedPipeW")
|
procWaitNamedPipeW = modkernel32.NewProc("WaitNamedPipeW")
|
||||||
procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo")
|
procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo")
|
||||||
procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW")
|
procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW")
|
||||||
|
procLocalAlloc = modkernel32.NewProc("LocalAlloc")
|
||||||
|
procRtlCopyMemory = modkernel32.NewProc("RtlCopyMemory")
|
||||||
procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW")
|
procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW")
|
||||||
procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW")
|
procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW")
|
||||||
procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW")
|
procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW")
|
||||||
|
@ -228,6 +230,17 @@ func getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *u
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func localAlloc(uFlags uint32, length uint32) (ptr uintptr) {
|
||||||
|
r0, _, _ := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(uFlags), uintptr(length), 0)
|
||||||
|
ptr = uintptr(r0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func copyMemory(dst uintptr, src uintptr, length uint32) {
|
||||||
|
syscall.Syscall(procRtlCopyMemory.Addr(), 3, uintptr(dst), uintptr(src), uintptr(length))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
|
func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
|
||||||
var _p0 *uint16
|
var _p0 *uint16
|
||||||
_p0, err = syscall.UTF16PtrFromString(accountName)
|
_p0, err = syscall.UTF16PtrFromString(accountName)
|
||||||
|
|
6
vendor/vendor.json
vendored
6
vendor/vendor.json
vendored
|
@ -25,10 +25,10 @@
|
||||||
"revisionTime": "2016-08-22T16:14:30Z"
|
"revisionTime": "2016-08-22T16:14:30Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "A6wxSCZcKyTwZP9b7ErXPZE3Ijg=",
|
"checksumSHA1": "Rjy2uYZkQ8Kjht6ZFU0qzm2I/kI=",
|
||||||
"path": "github.com/Microsoft/go-winio",
|
"path": "github.com/Microsoft/go-winio",
|
||||||
"revision": "13736c32520969a64987228c21c138a4cfdb3720",
|
"revision": "d311c76e775b5092c023569caacdbb4e569c3243",
|
||||||
"revisionTime": "2017-05-03T19:50:31Z"
|
"revisionTime": "2017-05-08T21:01:43Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "XeG94RjA9o/0wo9Fuw6NSRGYnjk=",
|
"checksumSHA1": "XeG94RjA9o/0wo9Fuw6NSRGYnjk=",
|
||||||
|
|
Loading…
Reference in a new issue