mirror of
https://github.com/rwinkhart/go-winio.git
synced 2026-09-06 00:57:19 -04:00
Ensure DialPipe times eventually by default
Signed-off-by: John Starks <jostarks@microsoft.com>
This commit is contained in:
@@ -15,8 +15,8 @@ import (
|
|||||||
//sys setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes
|
//sys setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes
|
||||||
|
|
||||||
const (
|
const (
|
||||||
fileSkipCompletionOnSuccess = 1
|
cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1
|
||||||
fileSkipSetEventOnHandle = 2
|
cFILE_SKIP_SET_EVENT_ON_HANDLE = 2
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -72,7 +72,7 @@ func makeWin32File(h syscall.Handle) (*win32File, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,12 +21,15 @@ const (
|
|||||||
cERROR_PIPE_CONNECTED = syscall.Errno(535)
|
cERROR_PIPE_CONNECTED = syscall.Errno(535)
|
||||||
cERROR_SEM_TIMEOUT = syscall.Errno(121)
|
cERROR_SEM_TIMEOUT = syscall.Errno(121)
|
||||||
|
|
||||||
pipeFlagAccessDuplex = 0x3
|
cPIPE_ACCESS_DUPLEX = 0x3
|
||||||
pipeFlagFirstInstance = 0x80000
|
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 (
|
var (
|
||||||
@@ -71,6 +74,9 @@ func makeWin32Pipe(h syscall.Handle, path string) (*win32Pipe, error) {
|
|||||||
return &win32Pipe{f, path}, nil
|
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) {
|
func DialPipe(path string, timeout *time.Duration) (net.Conn, error) {
|
||||||
var absTimeout time.Time
|
var absTimeout time.Time
|
||||||
if timeout != nil {
|
if timeout != nil {
|
||||||
@@ -86,9 +92,9 @@ func DialPipe(path string, timeout *time.Duration) (net.Conn, error) {
|
|||||||
now := time.Now()
|
now := time.Now()
|
||||||
var ms uint32
|
var ms uint32
|
||||||
if absTimeout.IsZero() {
|
if absTimeout.IsZero() {
|
||||||
ms = syscall.INFINITE
|
ms = cNMPWAIT_USE_DEFAULT_WAIT
|
||||||
} else if now.After(absTimeout) {
|
} else if now.After(absTimeout) {
|
||||||
ms = 1
|
ms = cNMPWAIT_NOWAIT
|
||||||
} else {
|
} else {
|
||||||
ms = uint32(absTimeout.Sub(now).Nanoseconds() / 1000 / 1000)
|
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) {
|
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 {
|
if first {
|
||||||
flags |= pipeFlagFirstInstance
|
flags |= cFILE_FLAG_FIRST_PIPE_INSTANCE
|
||||||
}
|
}
|
||||||
var sd uintptr
|
var sd uintptr
|
||||||
if securityDescriptor != "" {
|
if securityDescriptor != "" {
|
||||||
@@ -140,7 +146,7 @@ func makeServerPipeHandle(path, securityDescriptor string, first bool) (syscall.
|
|||||||
var sa syscall.SecurityAttributes
|
var sa syscall.SecurityAttributes
|
||||||
sa.Length = uint32(unsafe.Sizeof(sa))
|
sa.Length = uint32(unsafe.Sizeof(sa))
|
||||||
sa.SecurityDescriptor = sd
|
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 {
|
if sd != 0 {
|
||||||
localFree(sd)
|
localFree(sd)
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-1
@@ -39,7 +39,7 @@ func TestDialAccessDeniedWithRestrictedSD(t *testing.T) {
|
|||||||
defer l.Close()
|
defer l.Close()
|
||||||
_, err = DialPipe(testPipeName, nil)
|
_, err = DialPipe(testPipeName, nil)
|
||||||
if err.(*os.PathError).Err != syscall.ERROR_ACCESS_DENIED {
|
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)
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user