github.com/alouche/packer@v0.3.7/stdin.go (about) 1 package main 2 3 import ( 4 "io" 5 "log" 6 "os" 7 "os/signal" 8 ) 9 10 // setupStdin switches out stdin for a pipe. We do this so that we can 11 // close the writer end of the pipe when we receive an interrupt so plugins 12 // blocked on reading from stdin are unblocked. 13 func setupStdin() { 14 // Create the pipe and swap stdin for the reader end 15 r, w, _ := os.Pipe() 16 originalStdin := os.Stdin 17 os.Stdin = r 18 19 // Create a goroutine that copies data from the original stdin 20 // into the writer end of the pipe forever. 21 go func() { 22 defer w.Close() 23 io.Copy(w, originalStdin) 24 }() 25 26 // Register a signal handler for interrupt in order to close the 27 // writer end of our pipe so that readers get EOF downstream. 28 ch := make(chan os.Signal, 1) 29 signal.Notify(ch, os.Interrupt) 30 31 go func() { 32 defer signal.Stop(ch) 33 defer w.Close() 34 <-ch 35 log.Println("Closing stdin because interrupt received.") 36 }() 37 }