mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-12-21 04:20:23 +00:00
91774fc936
Uses github.com/libopenstorage/secrets to communicate with Vault. This removes the need for maintaining our own limited Vault APIs. By adding the new dependency, several other packages got updated in the process. Unused indirect dependencies have been removed from go.mod. Signed-off-by: Niels de Vos <ndevos@redhat.com>
126 lines
3.3 KiB
Go
126 lines
3.3 KiB
Go
// +build windows
|
|
// +build !appengine
|
|
|
|
package isatty
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
"syscall"
|
|
"unicode/utf16"
|
|
"unsafe"
|
|
)
|
|
|
|
const (
|
|
objectNameInfo uintptr = 1
|
|
fileNameInfo = 2
|
|
fileTypePipe = 3
|
|
)
|
|
|
|
var (
|
|
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
|
ntdll = syscall.NewLazyDLL("ntdll.dll")
|
|
procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
|
|
procGetFileInformationByHandleEx = kernel32.NewProc("GetFileInformationByHandleEx")
|
|
procGetFileType = kernel32.NewProc("GetFileType")
|
|
procNtQueryObject = ntdll.NewProc("NtQueryObject")
|
|
)
|
|
|
|
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` &&
|
|
token[0] != `\Device\NamedPipe\msys` &&
|
|
token[0] != `\Device\NamedPipe\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
|
|
}
|
|
|
|
// getFileNameByHandle use the undocomented ntdll NtQueryObject to get file full name from file handler
|
|
// since GetFileInformationByHandleEx is not avilable under windows Vista and still some old fashion
|
|
// guys are using Windows XP, this is a workaround for those guys, it will also work on system from
|
|
// Windows vista to 10
|
|
// see https://stackoverflow.com/a/18792477 for details
|
|
func getFileNameByHandle(fd uintptr) (string, error) {
|
|
if procNtQueryObject == nil {
|
|
return "", errors.New("ntdll.dll: NtQueryObject not supported")
|
|
}
|
|
|
|
var buf [4 + syscall.MAX_PATH]uint16
|
|
var result int
|
|
r, _, e := syscall.Syscall6(procNtQueryObject.Addr(), 5,
|
|
fd, objectNameInfo, uintptr(unsafe.Pointer(&buf)), uintptr(2*len(buf)), uintptr(unsafe.Pointer(&result)), 0)
|
|
if r != 0 {
|
|
return "", e
|
|
}
|
|
return string(utf16.Decode(buf[4 : 4+buf[0]/2])), nil
|
|
}
|
|
|
|
// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2
|
|
// terminal.
|
|
func IsCygwinTerminal(fd uintptr) bool {
|
|
if procGetFileInformationByHandleEx == nil {
|
|
name, err := getFileNameByHandle(fd)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
return isCygwinPipeName(name)
|
|
}
|
|
|
|
// 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])))
|
|
}
|