Closing os.Stdin while trying to read from it?

133 views
Skip to first unread message

Matt Mueller

unread,
Mar 15, 2018, 4:40:41 AM3/15/18
to golang-nuts
Hey folks,

I'm trying to figure out how to cancel reading from stdin programmatically. Basically the same way that ctrl+d works on OSX.

I would have thought this would work, but this program will just run forever:

package main


import (
 
"io/ioutil"
 
"os"
 
"time"
)


func main
() {
 go func
() {
 time
.Sleep(time.Second)
 println
("closing...")
 os
.Stdin.Close()
 
}()

 _
, _ = ioutil.ReadAll(os.Stdin)
 println
("done")
}


Any help would be much appreciated – thanks!

roger peppe

unread,
Mar 15, 2018, 8:49:49 AM3/15/18
to Matt Mueller, golang-nuts
If it helps, you can set deadlines on *os.File now, as of Go 1.10:

https://play.golang.org/p/h3Pg9Ql0CMB

I don't see a way to cancel without deciding the deadline in advance though.
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Alex Efros

unread,
Mar 16, 2018, 8:30:03 AM3/16/18
to golang-nuts
Hi!

On Thu, Mar 15, 2018 at 12:49:15PM +0000, roger peppe wrote:
> If it helps, you can set deadlines on *os.File now, as of Go 1.10:
>
> https://play.golang.org/p/h3Pg9Ql0CMB
>
> I don't see a way to cancel without deciding the deadline in advance though.

Why? What makes os.Stdin so special?

If we add this at beginning of main() it'll work as expected:
os.Stdin, _ = os.Open("/dev/stdin")

--
WBR, Alex.

Ian Lance Taylor

unread,
Mar 16, 2018, 8:56:08 AM3/16/18
to golang-nuts
What is special about os.Stdin is the way it is initialized, which is
to say it is normally in blocking mode, and therefore reads block even
if you close the descriptor in a different goroutine. This would be
affected by changes to https://golang.org/issue/22939.

Ian

Matt Mueller

unread,
Mar 19, 2018, 8:52:52 AM3/19/18
to golang-nuts
Thanks for the great info! 

Out of curiosity, how is Go handling ctrl+d (sending EOF to stdin) right now? Is it part of the special case? A more generic way to ask this is: 

Is it possible to programmatically tell os.Stdin that we've reached EOF while you're trying to read from it?

Alex Efros

unread,
Mar 19, 2018, 9:51:19 AM3/19/18
to golang-nuts
Hi!

On Mon, Mar 19, 2018 at 05:52:52AM -0700, Matt Mueller wrote:
> Is it possible to programmatically tell os.Stdin that we've reached EOF
> while you're trying to read from it?

As default os.Stdin is in blocking mode then only way to have it read EOF
after calling Read() on it is to actually press Ctrl-D. If you need to
interrupt this Read() before it'll read actual EOF then you need to either
change os.Stdin to non-blocking or replace it with another *os.File.

--
WBR, Alex.
Reply all
Reply to author
Forward
0 new messages