go: os: os.ModeSocket is not set for domain socket files in Windows

What version of Go are you using (go version)?

$ go version
go version go1.12.4 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build497560436=/tmp/go-build -gno-record-gcc-switches"

What did you do?

I created a Windows golang program to listen on a Windows domain socket. In another Windows golang program, on the file corresponding to the socket, I invoked the following code:

fi, err := os.Stat(filename)
if err != nil {
	return fmt.Errorf("stat file %s failed: %v", filename, err)
}

if !fi.IsDir() {
	if fi.Mode()&os.ModeSocket == 0 {
		klog.V(5).Infof("Ignoring non socket file: %s", fi.Name())
                 return nil
	}
	klog.V(5).Infof("socket file found: %s", fi.Name())
        return nil
}

What did you expect to see?

socket file found: filename (as in Linux)

What did you see instead?

Ignoring non socket file: filename

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Comments: 25 (17 by maintainers)

Commits related to this issue

Most upvoted comments

Change https://golang.org/cl/338069 mentions this issue: os,net: fix file mode in unix domain socket on Windows

@mattn one of your related CL’s was mentioned here: https://github.com/microsoft/Windows-Containers/issues/97#issuecomment-887713195

Commenting so Github links them together.

But I wonder that Go have the way to create the file with AF_UNIX attribute.

Your patch is working for me with a socket created by net.Listen Environment: Windows 11 (22000.100)

package main

import (
	"fmt"
	"io/fs"
	"log"
	"net"
	"os"
)

func main() {
	log.SetFlags(log.Lshortfile)

	socketFilePath := "uds"

	unixListener, err := net.Listen("unix", socketFilePath)
	if err != nil {
		log.Fatal(err)
	}
	defer unixListener.Close()

	stat, err := os.Stat(socketFilePath)
	if err != nil {
		log.Print(err)
		return
	}

	fileMode := stat.Mode()
	fmt.Println(fileMode)
	fmt.Println("Has socket bit?", fileMode&fs.ModeSocket != 0)
}
> go version
go version go1.16.6 windows/amd64
> go run .\main.go
main.go:24: CreateFile uds: The file cannot be accessed by the system.
> go-tip
> go version
go version devel go1.17-7cd10c1149 Tue Jul 27 22:01:54 2021 +0000 windows/amd64
> go run .\main.go
Srw-rw-rw-
Has socket bit? true