]> Cypherpunks repositories - gostls13.git/commitdiff
os: make Stdin.Stat() return ModeCharDevice if Stdin is console
authorAlex Brainman <alex.brainman@gmail.com>
Tue, 6 Dec 2016 23:49:45 +0000 (10:49 +1100)
committerAlex Brainman <alex.brainman@gmail.com>
Tue, 7 Feb 2017 23:59:31 +0000 (23:59 +0000)
CL 20845 changed Stdin.Stat() so it returns ModeNamedPipe.
But introduced TestStatStdin does not test what Stdin.Stat()
returns when Stdin is console.

This CL adjusts both TestStatStdin and Stdin.Stat
implementations to handle console. Return ModeCharDevice
from Stdin.Stat() when Stdin is console on windows,
just like it does on unix.

Fixes #14853.

Change-Id: I54d73caee2aea45a99618d11600d8e82fe20d0c0
Reviewed-on: https://go-review.googlesource.com/34090
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/os/os_test.go
src/os/stat_windows.go
src/os/types_windows.go

index 7ad9aac70e25101ffca31b7a7ba4cad98cd166c8..9d74070e7f30d2685a412b1211632326e50cb76d 100644 (file)
@@ -1669,6 +1669,17 @@ func TestStatStdin(t *testing.T) {
                Exit(0)
        }
 
+       fi, err := Stdin.Stat()
+       if err != nil {
+               t.Fatal(err)
+       }
+       switch mode := fi.Mode(); {
+       case mode&ModeCharDevice != 0:
+       case mode&ModeNamedPipe != 0:
+       default:
+               t.Fatalf("unexpected Stdin mode (%v), want ModeCharDevice or ModeNamedPipe", mode)
+       }
+
        var cmd *osexec.Cmd
        if runtime.GOOS == "windows" {
                cmd = osexec.Command("cmd", "/c", "echo output | "+Args[0]+" -test.run=TestStatStdin")
index fdabf73cba5e21428c1a537c573338ed56cadf59..c8379381b1870fb5bcc891d743516c6622114ae7 100644 (file)
@@ -31,8 +31,9 @@ func (file *File) Stat() (FileInfo, error) {
        if err != nil {
                return nil, &PathError{"GetFileType", file.name, err}
        }
-       if ft == syscall.FILE_TYPE_PIPE {
-               return &fileStat{name: basename(file.name), pipe: true}, nil
+       switch ft {
+       case syscall.FILE_TYPE_PIPE, syscall.FILE_TYPE_CHAR:
+               return &fileStat{name: basename(file.name), filetype: ft}, nil
        }
 
        var d syscall.ByHandleFileInformation
@@ -50,10 +51,10 @@ func (file *File) Stat() (FileInfo, error) {
                        FileSizeHigh:   d.FileSizeHigh,
                        FileSizeLow:    d.FileSizeLow,
                },
-               vol:   d.VolumeSerialNumber,
-               idxhi: d.FileIndexHigh,
-               idxlo: d.FileIndexLow,
-               pipe:  false,
+               filetype: ft,
+               vol:      d.VolumeSerialNumber,
+               idxhi:    d.FileIndexHigh,
+               idxlo:    d.FileIndexLow,
        }, nil
 }
 
index ad4e863fcbbd74eb23819b86db9f2fd9068e10ae..772b9e5d24abe8e365f10207cab27dcfead98d5a 100644 (file)
@@ -12,9 +12,9 @@ import (
 
 // A fileStat is the implementation of FileInfo returned by Stat and Lstat.
 type fileStat struct {
-       name string
-       sys  syscall.Win32FileAttributeData
-       pipe bool
+       name     string
+       sys      syscall.Win32FileAttributeData
+       filetype uint32 // what syscall.GetFileType returns
 
        // used to implement SameFile
        sync.Mutex
@@ -43,8 +43,11 @@ func (fs *fileStat) Mode() (m FileMode) {
        if fs.sys.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT != 0 {
                m |= ModeSymlink
        }
-       if fs.pipe {
+       switch fs.filetype {
+       case syscall.FILE_TYPE_PIPE:
                m |= ModeNamedPipe
+       case syscall.FILE_TYPE_CHAR:
+               m |= ModeCharDevice
        }
        return m
 }