helper/wrappedstreams: get original console input/output on Windows
Fixes #10266 panicwrap was using Extrafiles to get the original standard streams for `terraform console`. This doesn't work on Windows. Instead, we must use the Win32 APIs to get the exact handles.
This commit is contained in:
parent
50c1e875d0
commit
fd36b548c5
|
@ -38,10 +38,15 @@ func Stderr() *os.File {
|
|||
return stderr
|
||||
}
|
||||
|
||||
// These are the wrapped streams. There doesn't appear to be a negative
|
||||
// impact of opening these files even if the file descriptor doesn't exist.
|
||||
// These are the wrapped standard streams. These are setup by the
|
||||
// platform specific code in initPlatform.
|
||||
var (
|
||||
wrappedStdin = os.NewFile(uintptr(3), "stdin")
|
||||
wrappedStdout = os.NewFile(uintptr(4), "stdout")
|
||||
wrappedStderr = os.NewFile(uintptr(5), "stderr")
|
||||
wrappedStdin *os.File
|
||||
wrappedStdout *os.File
|
||||
wrappedStderr *os.File
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Initialize the platform-specific code
|
||||
initPlatform()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
// +build !windows
|
||||
|
||||
package wrappedstreams
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
func initPlatform() {
|
||||
// The standard streams are passed in via extra file descriptors.
|
||||
wrappedStdin = os.NewFile(uintptr(3), "stdin")
|
||||
wrappedStdout = os.NewFile(uintptr(4), "stdout")
|
||||
wrappedStderr = os.NewFile(uintptr(5), "stderr")
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
// +build windows
|
||||
|
||||
package wrappedstreams
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func initPlatform() {
|
||||
wrappedStdin = openConsole("CONIN$", os.Stdin)
|
||||
wrappedStdout = openConsole("CONOUT$", os.Stdout)
|
||||
wrappedStderr = wrappedStdout
|
||||
}
|
||||
|
||||
// openConsole opens a console handle, using a backup if it fails.
|
||||
// This is used to get the exact console handle instead of the redirected
|
||||
// handles from panicwrap.
|
||||
func openConsole(name string, backup *os.File) *os.File {
|
||||
// Convert to UTF16
|
||||
path, err := syscall.UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] wrappedstreams: %s", err)
|
||||
return backup
|
||||
}
|
||||
|
||||
// Determine the share mode
|
||||
var shareMode uint32
|
||||
switch name {
|
||||
case "CONIN$":
|
||||
shareMode = syscall.FILE_SHARE_READ
|
||||
case "CONOUT$":
|
||||
shareMode = syscall.FILE_SHARE_WRITE
|
||||
}
|
||||
|
||||
// Get the file
|
||||
h, err := syscall.CreateFile(
|
||||
path,
|
||||
syscall.GENERIC_READ|syscall.GENERIC_WRITE,
|
||||
shareMode,
|
||||
nil,
|
||||
syscall.OPEN_EXISTING,
|
||||
0, 0)
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] wrappedstreams: %s", err)
|
||||
return backup
|
||||
}
|
||||
|
||||
// Create the Go file
|
||||
return os.NewFile(uintptr(h), name)
|
||||
}
|
|
@ -16,6 +16,7 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"runtime"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
"time"
|
||||
|
@ -151,7 +152,13 @@ func Wrap(c *WrapConfig) (int, error) {
|
|||
cmd.Stdin = os.Stdin
|
||||
cmd.Stdout = stdout_w
|
||||
cmd.Stderr = stderr_w
|
||||
|
||||
// Windows doesn't support this, but on other platforms pass in
|
||||
// the original file descriptors so they can be used.
|
||||
if runtime.GOOS != "windows" {
|
||||
cmd.ExtraFiles = []*os.File{os.Stdin, os.Stdout, os.Stderr}
|
||||
}
|
||||
|
||||
if err := cmd.Start(); err != nil {
|
||||
return 1, err
|
||||
}
|
||||
|
|
|
@ -1915,10 +1915,10 @@
|
|||
"revision": "314aad379a39f6ad5bcca278e6757d9abbb3a52e"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "wqU8bs9c+xm0f07t6ajQFWYS+rE=",
|
||||
"checksumSHA1": "kTntIB9SdU1NsCqKwDkUr99qaj0=",
|
||||
"path": "github.com/mitchellh/panicwrap",
|
||||
"revision": "168f3680ad986108df63bae07da2978f51c4ac8e",
|
||||
"revisionTime": "2016-11-14T06:37:33Z"
|
||||
"revision": "fde185d0dfb5ecac6e6b201e8855da798ebcd76f",
|
||||
"revisionTime": "2016-11-21T18:34:54Z"
|
||||
},
|
||||
{
|
||||
"path": "github.com/mitchellh/prefixedio",
|
||||
|
|
Loading…
Reference in New Issue