]> Cypherpunks repositories - gostls13.git/commitdiff
os: remove NewFile socket detection on Windows
authorqmuntal <quimmuntal@gmail.com>
Fri, 9 May 2025 14:55:00 +0000 (16:55 +0200)
committerQuim Muntal <quimmuntal@gmail.com>
Mon, 12 May 2025 18:57:30 +0000 (11:57 -0700)
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 <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
src/os/file_windows.go

index d1d3124eed2d470adb53781f23e41584e36925f6..c97307371c88ad1c59d3cb32c26d339bffd9fa6a 100644 (file)
@@ -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) {