From: qmuntal Date: Fri, 9 May 2025 14:55:00 +0000 (+0200) Subject: os: remove NewFile socket detection on Windows X-Git-Tag: go1.25rc1~300 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=41bd52b3fa2ac77e0180f29777309f65fda9fad0;p=gostls13.git os: remove NewFile socket detection on Windows NewFile was recently updated (in CL 668195) to detect whether the handle is a socket or not. This special case is not really necessary, given that socket handles can be used as if they were normal file handles on all functions supported by os.File (see https://learn.microsoft.com/en-us/windows/win32/winsock/socket-handles-2). Not only is not necessary, but is can also be problematic, as there is no way to reliably detect whether a handle is a socket or not. For example, the test failure reported in #73630 is caused by a named pipe wrongly detected as a socket. This aligns with the Unix NewFile behavior of returning an os.File that identifies itself as a file handle even if it is a socket. This makes os.File.Close to always return os.ErrClosed in case of multiple calls rather than sometimes returning "use of closed network connection". Updates #10350. Fixes #73630. Change-Id: Ia8329783d5c8ef6dac34ef69ed1ce9d2a9862e11 Reviewed-on: https://go-review.googlesource.com/c/go/+/671455 LUCI-TryBot-Result: Go LUCI Reviewed-by: Michael Knyszek Reviewed-by: Damien Neil --- diff --git a/src/os/file_windows.go b/src/os/file_windows.go index d1d3124eed..c97307371c 100644 --- a/src/os/file_windows.go +++ b/src/os/file_windows.go @@ -82,49 +82,14 @@ func newConsoleFile(h syscall.Handle, name string) *File { return newFile(h, name, "console", false) } -var wsaLoaded atomic.Bool - -// isWSALoaded returns true if the ws2_32.dll module is loaded. -func isWSALoaded() bool { - // ws2_32.dll may be delay loaded, we can only short-circuit - // if we know it is loaded. - if wsaLoaded.Load() { - return true - } - var ws2_32_dll = [...]uint16{'w', 's', '2', '_', '3', '2', '.', 'd', 'l', 'l', 0} - _, err := windows.GetModuleHandle(unsafe.SliceData(ws2_32_dll[:])) - wsaLoaded.Store(err == nil) - return err == nil -} - // newFileFromNewFile is called by [NewFile]. func newFileFromNewFile(fd uintptr, name string) *File { h := syscall.Handle(fd) if h == syscall.InvalidHandle { return nil } - kind := "file" - var sotype int - if t, err := syscall.GetFileType(h); err == nil && t == syscall.FILE_TYPE_PIPE { - kind = "pipe" - // Windows reports sockets as FILE_TYPE_PIPE. - // We need to call getsockopt and check the socket type to distinguish between sockets and pipes. - // If the call fails, we assume it's a pipe. - // Avoid calling getsockopt if the WSA module is not loaded, it is a heavy dependency - // and sockets can only be created using that module. - if isWSALoaded() { - if sotype, err = syscall.GetsockoptInt(h, syscall.SOL_SOCKET, windows.SO_TYPE); err == nil { - kind = "net" - } - } - } nonBlocking, _ := windows.IsNonblock(syscall.Handle(fd)) - f := newFile(h, name, kind, nonBlocking) - if kind == "net" { - f.pfd.IsStream = sotype == syscall.SOCK_STREAM - f.pfd.ZeroReadIsEOF = sotype != syscall.SOCK_DGRAM && sotype != syscall.SOCK_RAW - } - return f + return newFile(h, name, "file", nonBlocking) } func epipecheck(file *File, e error) {