1
0
mirror of https://github.com/golang/go synced 2024-11-23 14:00:03 -07:00

os: don't refer directly to Sysfd in epipecheck

Instead record in the File whether it is stdout/stderr. This avoids a
race between a call to epipecheck and closing the file.

Fixes #21994

Change-Id: Ic3d552ffa83402136276bcb5029ec3e6691042c2
Reviewed-on: https://go-review.googlesource.com/65750
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
Ian Lance Taylor 2017-09-23 22:00:53 -07:00
parent 14a1d934b6
commit 9f7fd893dc

View File

@ -45,10 +45,11 @@ func rename(oldname, newname string) error {
// can overwrite this data, which could cause the finalizer // can overwrite this data, which could cause the finalizer
// to close the wrong file descriptor. // to close the wrong file descriptor.
type file struct { type file struct {
pfd poll.FD pfd poll.FD
name string name string
dirinfo *dirInfo // nil unless directory being read dirinfo *dirInfo // nil unless directory being read
nonblock bool // whether we set nonblocking mode nonblock bool // whether we set nonblocking mode
stdoutOrErr bool // whether this is stdout or stderr
} }
// Fd returns the integer Unix file descriptor referencing the open file. // Fd returns the integer Unix file descriptor referencing the open file.
@ -90,7 +91,8 @@ func newFile(fd uintptr, name string, pollable bool) *File {
IsStream: true, IsStream: true,
ZeroReadIsEOF: true, ZeroReadIsEOF: true,
}, },
name: name, name: name,
stdoutOrErr: fdi == 1 || fdi == 2,
}} }}
// Don't try to use kqueue with regular files on FreeBSD. // Don't try to use kqueue with regular files on FreeBSD.
@ -130,7 +132,7 @@ type dirInfo struct {
// output or standard error. See the SIGPIPE docs in os/signal, and // output or standard error. See the SIGPIPE docs in os/signal, and
// issue 11845. // issue 11845.
func epipecheck(file *File, e error) { func epipecheck(file *File, e error) {
if e == syscall.EPIPE && (file.pfd.Sysfd == 1 || file.pfd.Sysfd == 2) { if e == syscall.EPIPE && file.stdoutOrErr {
sigpipe() sigpipe()
} }
} }