]> Cypherpunks repositories - gostls13.git/commitdiff
os: don't wait for Close if the File was returned by NewFile
authorWèi Cōngruì <crvv.mail@gmail.com>
Thu, 14 Dec 2017 02:54:11 +0000 (10:54 +0800)
committerIan Lance Taylor <iant@golang.org>
Thu, 14 Dec 2017 05:54:46 +0000 (05:54 +0000)
os.NewFile doesn't put the fd into non-blocking mode.
In most cases, an *os.File returned by os.NewFile is in blocking mode.

Updates #7970
Updates #21856
Updates #23111

Change-Id: Iab08432e41f7ac1b5e25aaa8855d478adb7f98ed
Reviewed-on: https://go-review.googlesource.com/83995
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/internal/poll/fd_unix.go
src/os/pipe_test.go

index 2bbf60216f24dd62dc62f23fdd6f5ba122a73e78..372dc816335a7d1075d62fa979a92a70492e2f17 100644 (file)
@@ -56,6 +56,7 @@ func (fd *FD) Init(net string, pollable bool) error {
                fd.isFile = true
        }
        if !pollable {
+               fd.isBlocking = true
                return nil
        }
        return fd.pd.init(fd)
index 50e11f1de5ae44a95a755a582c438b0d0fc3d384..aad6c27f1b11e8feccf6e894e1cc63e269000a2c 100644 (file)
@@ -10,6 +10,7 @@ package os_test
 import (
        "fmt"
        "internal/testenv"
+       "io"
        "io/ioutil"
        "os"
        osexec "os/exec"
@@ -222,12 +223,28 @@ func TestReadNonblockingFd(t *testing.T) {
        }
 }
 
-// Test that we don't let a blocking read prevent a close.
-func TestCloseWithBlockingRead(t *testing.T) {
+func TestCloseWithBlockingReadByNewFile(t *testing.T) {
+       var p [2]int
+       err := syscall.Pipe(p[:])
+       if err != nil {
+               t.Fatal(err)
+       }
+       // os.NewFile returns a blocking mode file.
+       testCloseWithBlockingRead(t, os.NewFile(uintptr(p[0]), "reader"), os.NewFile(uintptr(p[1]), "writer"))
+}
+
+func TestCloseWithBlockingReadByFd(t *testing.T) {
        r, w, err := os.Pipe()
        if err != nil {
                t.Fatal(err)
        }
+       // Calling Fd will put the file into blocking mode.
+       _ = r.Fd()
+       testCloseWithBlockingRead(t, r, w)
+}
+
+// Test that we don't let a blocking read prevent a close.
+func testCloseWithBlockingRead(t *testing.T, r, w *os.File) {
        defer r.Close()
        defer w.Close()
 
@@ -248,18 +265,18 @@ func TestCloseWithBlockingRead(t *testing.T) {
                close(c)
        }(c1)
 
-       // Calling Fd will put the file into blocking mode.
-       _ = r.Fd()
-
        wg.Add(1)
        go func(c chan bool) {
                defer wg.Done()
                var b [1]byte
-               _, err = r.Read(b[:])
+               _, err := r.Read(b[:])
                close(c)
                if err == nil {
                        t.Error("I/O on closed pipe unexpectedly succeeded")
                }
+               if err != io.EOF {
+                       t.Errorf("got %v, expected io.EOF", err)
+               }
        }(c2)
 
        for c1 != nil || c2 != nil {