From 41bd52b3fa2ac77e0180f29777309f65fda9fad0 Mon Sep 17 00:00:00 2001 From: qmuntal Date: Fri, 9 May 2025 16:55:00 +0200 Subject: [PATCH] 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 --- src/os/file_windows.go | 37 +------------------------------------ 1 file changed, 1 insertion(+), 36 deletions(-) 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) { -- 2.51.0