From 99eef7be8db4b2f5078e025d858a450388bdcaf4 Mon Sep 17 00:00:00 2001 From: John Starks Date: Sun, 31 Jan 2016 13:58:14 -0800 Subject: [PATCH] Ensure DialPipe times eventually by default Signed-off-by: John Starks --- file.go | 6 +++--- pipe.go | 24 +++++++++++++++--------- pipe_test.go | 14 +++++++++++++- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/file.go b/file.go index e303a5d..e9921af 100644 --- a/file.go +++ b/file.go @@ -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 } diff --git a/pipe.go b/pipe.go index b438a10..ccc3744 100644 --- a/pipe.go +++ b/pipe.go @@ -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) } diff --git a/pipe_test.go b/pipe_test.go index 433588c..67c86ce 100644 --- a/pipe_test.go +++ b/pipe_test.go @@ -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) + } +}