mirror of
https://github.com/golang/go
synced 2024-09-19 07:52:34 +00:00
os: fix Stdin.Stat() on windows
If name is /dev/{stdin,stdout,stderr}, return fileInfo. Fixes #14853. Change-Id: Ibf7d1ae7b9f3dc43f6ed7c905ea2c5102e1971cc Reviewed-on: https://go-review.googlesource.com/20845 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
This commit is contained in:
parent
ddcf8d402a
commit
ebd67ba588
|
@ -1583,6 +1583,41 @@ func TestStatDirModeExec(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestStatStdin(t *testing.T) {
|
||||
if runtime.GOOS == "plan9" {
|
||||
t.Skipf("skipping test on plan9")
|
||||
}
|
||||
|
||||
testenv.MustHaveExec(t)
|
||||
|
||||
if Getenv("GO_WANT_HELPER_PROCESS") == "1" {
|
||||
st, err := Stdin.Stat()
|
||||
if err != nil {
|
||||
t.Fatalf("Stat failed: %v", err)
|
||||
}
|
||||
fmt.Println(st.Mode() & ModeNamedPipe)
|
||||
Exit(0)
|
||||
}
|
||||
|
||||
var cmd *osexec.Cmd
|
||||
if runtime.GOOS == "windows" {
|
||||
cmd = osexec.Command("cmd", "/c", "echo output | "+Args[0]+" -test.run=TestStatStdin")
|
||||
} else {
|
||||
cmd = osexec.Command("/bin/sh", "-c", "echo output | "+Args[0]+" -test.run=TestStatStdin")
|
||||
}
|
||||
cmd.Env = append(Environ(), "GO_WANT_HELPER_PROCESS=1")
|
||||
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to spawn child process: %v %q", err, string(output))
|
||||
}
|
||||
|
||||
// result will be like "prw-rw-rw"
|
||||
if len(output) < 1 || output[0] != 'p' {
|
||||
t.Fatalf("Child process reports stdin is not pipe '%v'", string(output))
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadAtEOF(t *testing.T) {
|
||||
f := newFile("TestReadAtEOF", t)
|
||||
defer Remove(f.Name())
|
||||
|
|
|
@ -25,10 +25,19 @@ func (file *File) Stat() (FileInfo, error) {
|
|||
if file.name == DevNull {
|
||||
return &devNullStat, nil
|
||||
}
|
||||
|
||||
ft, err := syscall.GetFileType(file.fd)
|
||||
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
|
||||
}
|
||||
|
||||
var d syscall.ByHandleFileInformation
|
||||
e := syscall.GetFileInformationByHandle(syscall.Handle(file.fd), &d)
|
||||
if e != nil {
|
||||
return nil, &PathError{"GetFileInformationByHandle", file.name, e}
|
||||
err = syscall.GetFileInformationByHandle(syscall.Handle(file.fd), &d)
|
||||
if err != nil {
|
||||
return nil, &PathError{"GetFileInformationByHandle", file.name, err}
|
||||
}
|
||||
return &fileStat{
|
||||
name: basename(file.name),
|
||||
|
@ -43,6 +52,7 @@ func (file *File) Stat() (FileInfo, error) {
|
|||
vol: d.VolumeSerialNumber,
|
||||
idxhi: d.FileIndexHigh,
|
||||
idxlo: d.FileIndexLow,
|
||||
pipe: false,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
type fileStat struct {
|
||||
name string
|
||||
sys syscall.Win32FileAttributeData
|
||||
pipe bool
|
||||
|
||||
// used to implement SameFile
|
||||
sync.Mutex
|
||||
|
@ -42,6 +43,9 @@ func (fs *fileStat) Mode() (m FileMode) {
|
|||
if fs.sys.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT != 0 {
|
||||
m |= ModeSymlink
|
||||
}
|
||||
if fs.pipe {
|
||||
m |= ModeNamedPipe
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue