You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
package main
import (
"fmt""io""log""os""time"
)
funcmain() {
err:=Main()
iferr!=nil {
log.Fatal(err)
}
}
funcreadpart(r io.ReadCloser) error {
done:=make(chanstruct{})
deferfunc() { <-done }()
gofunc() {
// To be reasonably sure that the parent goroutine is already// in the call to Read().time.Sleep(50*time.Millisecond)
err:=r.Close()
fmt.Printf("close err %v\n", err)
done<-struct{}{}
}()
_, err:=r.Read(make([]byte, 128))
iferr!=nil {
returnerr
}
returnnil
}
funcgetfile() (*os.File, error) {
r, _, err:=os.Pipe()
returnr, err
}
funcMain() error {
f0, err:=getfile()
iferr!=nil {
returnerr
}
err=readpart(f0)
fmt.Printf("error of f0.Read(): %v\n", err)
f1, err:=getfile()
iferr!=nil {
returnerr
}
fmt.Printf("f1.Fd() %d\n", f1.Fd())
err=readpart(f1)
fmt.Printf("error of f1.Read(): %v\n", err)
returnnil
}
What did you expect to see?
The program exits with a successful error code. The program runs until the end because the Read() will return immediately after Close has been called on the underlying *os.File.
What did you see instead?
After f1.Close() has returned, the program blocks in a call to f1.Read().
Analysis with strace shows that close() is only called for f0. For f1, the Go stdlib never calls close(). From the side of my program, the only difference is that I called f1.Fd(), but not f0.Fd(). Remove the call to f1.Fd() and the program will terminate.
I am experiencing this issue while working with serial ports. In order to set the baud rate and other parameters, I need the file descriptor to deal with termios.
System details
go version go1.10.3 linux/amd64
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/joe/.cache/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/joe/gop"
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build575248038=/tmp/go-build -gno-record-gcc-switches"
GOROOT/bin/go version: go version go1.10.3 linux/amd64
GOROOT/bin/go tool compile -V: compile version go1.10.3
uname -sr: Linux 4.13.0-45-generic
Distributor ID: Ubuntu
Description: Ubuntu 16.04.4 LTS
Release: 16.04
Codename: xenial
/lib/x86_64-linux-gnu/libc.so.6: GNU C Library (Ubuntu GLIBC 2.23-0ubuntu10) stable release version 2.23, by Roland McGrath et al.
gdb --version: GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
The text was updated successfully, but these errors were encountered:
distributed
changed the title
os.File.Read() does not return after os.File.Read()
os.File.Read() does not return after os.File.Close() and os.File.Fd()
Jul 18, 2018
This is documented, somewhat cryptically, in the docs for the Fd method: "On Unix systems this will cause the SetDeadline methods to stop working." We've avoided a complete explanation in that method doc because it's complicated and lengthy and obscures the point of the method. To help clarify a little more, we recently expanded the docs for the Close method to add "On files that support SetDeadline, any pending I/O operations will be canceled and return immediately with an error." So putting these together, we see that if you call Fd the SetDeadline methods stop working, and then you no longer get the behavior you want from Close.
For your special purpose I recommend that you use syscall.Open, initialize the descriptor as needed, set it into non-blocking mode, and pass the descriptor to os.NewFile.
Closing this issue because I'm not sure there is anything we can change at this point.
What did you do?
Compile and run the following program.
What did you expect to see?
The program exits with a successful error code. The program runs until the end because the
Read()
will return immediately afterClose
has been called on the underlying*os.File
.What did you see instead?
After
f1.Close()
has returned, the program blocks in a call tof1.Read()
.Analysis with
strace
shows thatclose()
is only called forf0
. Forf1
, the Go stdlib never callsclose()
. From the side of my program, the only difference is that I calledf1.Fd()
, but notf0.Fd()
. Remove the call tof1.Fd()
and the program will terminate.I am experiencing this issue while working with serial ports. In order to set the baud rate and other parameters, I need the file descriptor to deal with termios.
System details
The text was updated successfully, but these errors were encountered: