| // Copyright 2011 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| package net | |
| import ( | |
| "internal/syscall/windows" | |
| "os" | |
| "syscall" | |
| ) | |
| const _SO_TYPE = windows.SO_TYPE | |
| func dupSocket(h syscall.Handle) (syscall.Handle, error) { | |
| var info syscall.WSAProtocolInfo | |
| err := windows.WSADuplicateSocket(h, uint32(syscall.Getpid()), &info) | |
| if err != nil { | |
| return 0, err | |
| } | |
| return windows.WSASocket(-1, -1, -1, &info, 0, windows.WSA_FLAG_OVERLAPPED|windows.WSA_FLAG_NO_HANDLE_INHERIT) | |
| } | |
| func dupFileSocket(f *os.File) (syscall.Handle, error) { | |
| // Call Fd to disassociate the IOCP from the handle, | |
| // it is not safe to share a duplicated handle | |
| // that is associated with IOCP. | |
| // Don't use the returned fd, as it might be closed | |
| // if f happens to be the last reference to the file. | |
| f.Fd() | |
| sc, err := f.SyscallConn() | |
| if err != nil { | |
| return 0, err | |
| } | |
| var h syscall.Handle | |
| var syserr error | |
| err = sc.Control(func(fd uintptr) { | |
| h, syserr = dupSocket(syscall.Handle(fd)) | |
| }) | |
| if err == nil { | |
| err = syserr | |
| } | |
| if err != nil { | |
| return 0, err | |
| } | |
| return h, nil | |
| } |