Skip to content

os: Windows: Stat fails on special files like 'con' #34900

@lifenjoiner

Description

@lifenjoiner

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

$ go version
go version go1.13.1 windows/386

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
set GOHOSTARCH=386
set GOHOSTOS=windows

What did you do?

try test_Stat-con.go to reproduce the issue

package main

import (
	"os"
)

func main() {
	_, err := os.Stat("con")
	if err != nil {
		panic(err)
	}
}

I have debugged and located that GetFileAttributesEx fails on special files like 'con':

err = syscall.GetFileAttributesEx(namep, syscall.GetFileExInfoStandard, (*byte)(unsafe.Pointer(&fa)))
if err == nil && fa.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT == 0 {
// Not a symlink.
fs := &fileStat{
FileAttributes: fa.FileAttributes,
CreationTime: fa.CreationTime,
LastAccessTime: fa.LastAccessTime,
LastWriteTime: fa.LastWriteTime,
FileSizeHigh: fa.FileSizeHigh,
FileSizeLow: fa.FileSizeLow,
}
if err := fs.saveInfoFromPath(name); err != nil {
return nil, err
}
return fs, nil
}

and only 'nul':

if isWindowsNulName(file.name) {
return &devNullStat, nil
}

if isWindowsNulName(file.name) {
return &devNullStat, nil
}

reserved names
CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9:
https://docs.microsoft.com/zh-cn/windows/win32/fileio/naming-a-file#naming-conventions
CONIN$ and CONOUT$:
https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea#consoles

ref:
https://github.com/gcc-mirror/gcc/blob/bbcdad768752f5cab6727242515bcd15706acbea/gcc/ada/adaint.c#L1606-L1618

What did you expect to see?

We can access these special Windows files, especially con for printing to stdout.

What did you see instead?

I found sometimes we need to use stdout as a file:
https://github.com/DNSCrypt/dnscrypt-proxy/blob/858957ce91015057a1f6c5a9a24f3ea2beb48537/dnscrypt-proxy/example-dnscrypt-proxy.toml#L339-L341
But con doesn't work.
By doing some research, I located the code here as described.
GetFileAttributesEx and CreateFile of Stat failed on the reserved file name con, and only 'nul' is considered as the special case.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions