src: Add DMA localagent
[barometer.git] / src / dma / vendor / github.com / mattn / go-isatty / isatty_windows.go
diff --git a/src/dma/vendor/github.com/mattn/go-isatty/isatty_windows.go b/src/dma/vendor/github.com/mattn/go-isatty/isatty_windows.go
new file mode 100644 (file)
index 0000000..af51cbc
--- /dev/null
@@ -0,0 +1,94 @@
+// +build windows
+// +build !appengine
+
+package isatty
+
+import (
+       "strings"
+       "syscall"
+       "unicode/utf16"
+       "unsafe"
+)
+
+const (
+       fileNameInfo uintptr = 2
+       fileTypePipe         = 3
+)
+
+var (
+       kernel32                         = syscall.NewLazyDLL("kernel32.dll")
+       procGetConsoleMode               = kernel32.NewProc("GetConsoleMode")
+       procGetFileInformationByHandleEx = kernel32.NewProc("GetFileInformationByHandleEx")
+       procGetFileType                  = kernel32.NewProc("GetFileType")
+)
+
+func init() {
+       // Check if GetFileInformationByHandleEx is available.
+       if procGetFileInformationByHandleEx.Find() != nil {
+               procGetFileInformationByHandleEx = nil
+       }
+}
+
+// IsTerminal return true if the file descriptor is terminal.
+func IsTerminal(fd uintptr) bool {
+       var st uint32
+       r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0)
+       return r != 0 && e == 0
+}
+
+// Check pipe name is used for cygwin/msys2 pty.
+// Cygwin/MSYS2 PTY has a name like:
+//   \{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master
+func isCygwinPipeName(name string) bool {
+       token := strings.Split(name, "-")
+       if len(token) < 5 {
+               return false
+       }
+
+       if token[0] != `\msys` && token[0] != `\cygwin` {
+               return false
+       }
+
+       if token[1] == "" {
+               return false
+       }
+
+       if !strings.HasPrefix(token[2], "pty") {
+               return false
+       }
+
+       if token[3] != `from` && token[3] != `to` {
+               return false
+       }
+
+       if token[4] != "master" {
+               return false
+       }
+
+       return true
+}
+
+// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2
+// terminal.
+func IsCygwinTerminal(fd uintptr) bool {
+       if procGetFileInformationByHandleEx == nil {
+               return false
+       }
+
+       // Cygwin/msys's pty is a pipe.
+       ft, _, e := syscall.Syscall(procGetFileType.Addr(), 1, fd, 0, 0)
+       if ft != fileTypePipe || e != 0 {
+               return false
+       }
+
+       var buf [2 + syscall.MAX_PATH]uint16
+       r, _, e := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(),
+               4, fd, fileNameInfo, uintptr(unsafe.Pointer(&buf)),
+               uintptr(len(buf)*2), 0, 0)
+       if r == 0 || e != 0 {
+               return false
+       }
+
+       l := *(*uint32)(unsafe.Pointer(&buf))
+       return isCygwinPipeName(string(utf16.Decode(buf[2 : 2+l/2])))
+}