Ensure DialPipe times eventually by default

Signed-off-by: John Starks <jostarks@microsoft.com>
This commit is contained in:
John Starks
2016-01-31 14:00:21 -08:00
parent 3191792462
commit 99eef7be8d
3 changed files with 31 additions and 13 deletions
+3 -3
View File
@@ -15,8 +15,8 @@ import (
//sys setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes
const (
fileSkipCompletionOnSuccess = 1
fileSkipSetEventOnHandle = 2
cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1
cFILE_SKIP_SET_EVENT_ON_HANDLE = 2
)
var (
@@ -72,7 +72,7 @@ func makeWin32File(h syscall.Handle) (*win32File, error) {
if err != nil {
return nil, err
}
err = setFileCompletionNotificationModes(h, fileSkipCompletionOnSuccess|fileSkipSetEventOnHandle)
err = setFileCompletionNotificationModes(h, cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS|cFILE_SKIP_SET_EVENT_ON_HANDLE)
if err != nil {
return nil, err
}
+15 -9
View File
@@ -21,12 +21,15 @@ const (
cERROR_PIPE_CONNECTED = syscall.Errno(535)
cERROR_SEM_TIMEOUT = syscall.Errno(121)
pipeFlagAccessDuplex = 0x3
pipeFlagFirstInstance = 0x80000
cPIPE_ACCESS_DUPLEX = 0x3
cFILE_FLAG_FIRST_PIPE_INSTANCE = 0x80000
pipeModeRejectRemoteClients = 0x8
cPIPE_REJECT_REMOTE_CLIENTS = 0x8
pipeUnlimitedInstances = 255
cPIPE_UNLIMITED_INSTANCES = 255
cNMPWAIT_USE_DEFAULT_WAIT = 0
cNMPWAIT_NOWAIT = 1
)
var (
@@ -71,6 +74,9 @@ func makeWin32Pipe(h syscall.Handle, path string) (*win32Pipe, error) {
return &win32Pipe{f, path}, nil
}
// DialPipe connects to a named pipe by path, timing out if the connection
// takes longer than the specified duration. If timeout is nil, then the timeout
// is the default timeout established by the pipe server.
func DialPipe(path string, timeout *time.Duration) (net.Conn, error) {
var absTimeout time.Time
if timeout != nil {
@@ -86,9 +92,9 @@ func DialPipe(path string, timeout *time.Duration) (net.Conn, error) {
now := time.Now()
var ms uint32
if absTimeout.IsZero() {
ms = syscall.INFINITE
ms = cNMPWAIT_USE_DEFAULT_WAIT
} else if now.After(absTimeout) {
ms = 1
ms = cNMPWAIT_NOWAIT
} else {
ms = uint32(absTimeout.Sub(now).Nanoseconds() / 1000 / 1000)
}
@@ -126,9 +132,9 @@ type win32PipeListener struct {
}
func makeServerPipeHandle(path, securityDescriptor string, first bool) (syscall.Handle, error) {
var flags uint32 = pipeFlagAccessDuplex | syscall.FILE_FLAG_OVERLAPPED
var flags uint32 = cPIPE_ACCESS_DUPLEX | syscall.FILE_FLAG_OVERLAPPED
if first {
flags |= pipeFlagFirstInstance
flags |= cFILE_FLAG_FIRST_PIPE_INSTANCE
}
var sd uintptr
if securityDescriptor != "" {
@@ -140,7 +146,7 @@ func makeServerPipeHandle(path, securityDescriptor string, first bool) (syscall.
var sa syscall.SecurityAttributes
sa.Length = uint32(unsafe.Sizeof(sa))
sa.SecurityDescriptor = sd
h, err := createNamedPipe(path, flags, pipeModeRejectRemoteClients, pipeUnlimitedInstances, 4096, 4096, 0, &sa)
h, err := createNamedPipe(path, flags, cPIPE_REJECT_REMOTE_CLIENTS, cPIPE_UNLIMITED_INSTANCES, 4096, 4096, 0, &sa)
if sd != 0 {
localFree(sd)
}
+13 -1
View File
@@ -39,7 +39,7 @@ func TestDialAccessDeniedWithRestrictedSD(t *testing.T) {
defer l.Close()
_, err = DialPipe(testPipeName, nil)
if err.(*os.PathError).Err != syscall.ERROR_ACCESS_DENIED {
t.Fatalf("expected EACCES, got %v", err)
t.Fatalf("expected ERROR_ACCESS_DENIED, got %v", err)
}
}
@@ -185,3 +185,15 @@ func TestAcceptAfterCloseFails(t *testing.T) {
t.Fatalf("expected ErrPipeListenerClosed, got %v", err)
}
}
func TestDialTimesOutByDefault(t *testing.T) {
l, err := ListenPipe(testPipeName, "")
if err != nil {
t.Fatal(err)
}
defer l.Close()
_, err = DialPipe(testPipeName, nil)
if err != ErrTimeout {
t.Fatalf("expected ErrTimeout, got %v", err)
}
}