github.com/yamamoto-febc/docker@v1.9.0/pkg/term/windows/console.go (about)

     1  // +build windows
     2  
     3  package windows
     4  
     5  import (
     6  	"io"
     7  	"os"
     8  	"syscall"
     9  
    10  	"github.com/Azure/go-ansiterm/winterm"
    11  )
    12  
    13  // ConsoleStreams returns a wrapped version for each standard stream referencing a console,
    14  // that handles ANSI character sequences.
    15  func ConsoleStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
    16  	if IsConsole(os.Stdin.Fd()) {
    17  		stdIn = newAnsiReader(syscall.STD_INPUT_HANDLE)
    18  	} else {
    19  		stdIn = os.Stdin
    20  	}
    21  
    22  	if IsConsole(os.Stdout.Fd()) {
    23  		stdOut = newAnsiWriter(syscall.STD_OUTPUT_HANDLE)
    24  	} else {
    25  		stdOut = os.Stdout
    26  	}
    27  
    28  	if IsConsole(os.Stderr.Fd()) {
    29  		stdErr = newAnsiWriter(syscall.STD_ERROR_HANDLE)
    30  	} else {
    31  		stdErr = os.Stderr
    32  	}
    33  
    34  	return stdIn, stdOut, stdErr
    35  }
    36  
    37  // GetHandleInfo returns file descriptor and bool indicating whether the file is a console.
    38  func GetHandleInfo(in interface{}) (uintptr, bool) {
    39  	switch t := in.(type) {
    40  	case *ansiReader:
    41  		return t.Fd(), true
    42  	case *ansiWriter:
    43  		return t.Fd(), true
    44  	}
    45  
    46  	var inFd uintptr
    47  	var isTerminal bool
    48  
    49  	if file, ok := in.(*os.File); ok {
    50  		inFd = file.Fd()
    51  		isTerminal = IsConsole(inFd)
    52  	}
    53  	return inFd, isTerminal
    54  }
    55  
    56  // IsConsole returns true if the given file descriptor is a Windows Console.
    57  // The code assumes that GetConsoleMode will return an error for file descriptors that are not a console.
    58  func IsConsole(fd uintptr) bool {
    59  	_, e := winterm.GetConsoleMode(fd)
    60  	return e == nil
    61  }