forked from TrueCloudLab/restic
Use golang.org/x/sys/windows in termstatus
Some functionality is missing, but at least the types are all defined. Replaced short, word, dword by their Go names to match the x/sys convention.
This commit is contained in:
parent
c8a672fa29
commit
7447c44484
1 changed files with 20 additions and 52 deletions
|
@ -8,6 +8,7 @@ import (
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"golang.org/x/crypto/ssh/terminal"
|
"golang.org/x/crypto/ssh/terminal"
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
)
|
)
|
||||||
|
|
||||||
// clearCurrentLine removes all characters from the current line and resets the
|
// clearCurrentLine removes all characters from the current line and resets the
|
||||||
|
@ -19,7 +20,7 @@ func clearCurrentLine(wr io.Writer, fd uintptr) func(io.Writer, uintptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the output file type is a pipe (0x0003)
|
// check if the output file type is a pipe (0x0003)
|
||||||
if getFileType(fd) != fileTypePipe {
|
if isPipe(fd) {
|
||||||
// return empty func, update state is not possible on this terminal
|
// return empty func, update state is not possible on this terminal
|
||||||
return func(io.Writer, uintptr) {}
|
return func(io.Writer, uintptr) {}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +37,7 @@ func moveCursorUp(wr io.Writer, fd uintptr) func(io.Writer, uintptr, int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the output file type is a pipe (0x0003)
|
// check if the output file type is a pipe (0x0003)
|
||||||
if getFileType(fd) != fileTypePipe {
|
if isPipe(fd) {
|
||||||
// return empty func, update state is not possible on this terminal
|
// return empty func, update state is not possible on this terminal
|
||||||
return func(io.Writer, uintptr, int) {}
|
return func(io.Writer, uintptr, int) {}
|
||||||
}
|
}
|
||||||
|
@ -48,63 +49,37 @@ func moveCursorUp(wr io.Writer, fd uintptr) func(io.Writer, uintptr, int) {
|
||||||
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||||
|
|
||||||
var (
|
var (
|
||||||
procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
|
|
||||||
procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition")
|
procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition")
|
||||||
procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW")
|
procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW")
|
||||||
procFillConsoleOutputAttribute = kernel32.NewProc("FillConsoleOutputAttribute")
|
procFillConsoleOutputAttribute = kernel32.NewProc("FillConsoleOutputAttribute")
|
||||||
procGetFileType = kernel32.NewProc("GetFileType")
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
short int16
|
|
||||||
word uint16
|
|
||||||
dword uint32
|
|
||||||
|
|
||||||
coord struct {
|
|
||||||
x short
|
|
||||||
y short
|
|
||||||
}
|
|
||||||
smallRect struct {
|
|
||||||
left short
|
|
||||||
top short
|
|
||||||
right short
|
|
||||||
bottom short
|
|
||||||
}
|
|
||||||
consoleScreenBufferInfo struct {
|
|
||||||
size coord
|
|
||||||
cursorPosition coord
|
|
||||||
attributes word
|
|
||||||
window smallRect
|
|
||||||
maximumWindowSize coord
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// windowsClearCurrentLine removes all characters from the current line and
|
// windowsClearCurrentLine removes all characters from the current line and
|
||||||
// resets the cursor position to the first column.
|
// resets the cursor position to the first column.
|
||||||
func windowsClearCurrentLine(wr io.Writer, fd uintptr) {
|
func windowsClearCurrentLine(wr io.Writer, fd uintptr) {
|
||||||
var info consoleScreenBufferInfo
|
var info windows.ConsoleScreenBufferInfo
|
||||||
procGetConsoleScreenBufferInfo.Call(fd, uintptr(unsafe.Pointer(&info)))
|
windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info)
|
||||||
|
|
||||||
// clear the line
|
// clear the line
|
||||||
cursor := coord{
|
cursor := windows.Coord{
|
||||||
x: info.window.left,
|
X: info.Window.Left,
|
||||||
y: info.cursorPosition.y,
|
Y: info.CursorPosition.Y,
|
||||||
}
|
}
|
||||||
var count, w dword
|
var count, w uint32
|
||||||
count = dword(info.size.x)
|
count = uint32(info.Size.X)
|
||||||
procFillConsoleOutputAttribute.Call(fd, uintptr(info.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&w)))
|
procFillConsoleOutputAttribute.Call(fd, uintptr(info.Attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&w)))
|
||||||
procFillConsoleOutputCharacter.Call(fd, uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&w)))
|
procFillConsoleOutputCharacter.Call(fd, uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&w)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// windowsMoveCursorUp moves the cursor to the line n lines above the current one.
|
// windowsMoveCursorUp moves the cursor to the line n lines above the current one.
|
||||||
func windowsMoveCursorUp(wr io.Writer, fd uintptr, n int) {
|
func windowsMoveCursorUp(wr io.Writer, fd uintptr, n int) {
|
||||||
var info consoleScreenBufferInfo
|
var info windows.ConsoleScreenBufferInfo
|
||||||
procGetConsoleScreenBufferInfo.Call(fd, uintptr(unsafe.Pointer(&info)))
|
windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info)
|
||||||
|
|
||||||
// move cursor up by n lines and to the first column
|
// move cursor up by n lines and to the first column
|
||||||
info.cursorPosition.y -= short(n)
|
info.CursorPosition.Y -= int16(n)
|
||||||
info.cursorPosition.x = 0
|
info.CursorPosition.X = 0
|
||||||
procSetConsoleCursorPosition.Call(fd, uintptr(*(*int32)(unsafe.Pointer(&info.cursorPosition))))
|
procSetConsoleCursorPosition.Call(fd, uintptr(*(*int32)(unsafe.Pointer(&info.CursorPosition))))
|
||||||
}
|
}
|
||||||
|
|
||||||
// isWindowsTerminal return true if the file descriptor is a windows terminal (cmd, psh).
|
// isWindowsTerminal return true if the file descriptor is a windows terminal (cmd, psh).
|
||||||
|
@ -112,16 +87,9 @@ func isWindowsTerminal(fd uintptr) bool {
|
||||||
return terminal.IsTerminal(int(fd))
|
return terminal.IsTerminal(int(fd))
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileTypePipe = 0x0003
|
func isPipe(fd uintptr) bool {
|
||||||
|
typ, err := windows.GetFileType(windows.Handle(fd))
|
||||||
// getFileType returns the file type for the given fd.
|
return err == nil && typ == windows.FILE_TYPE_PIPE
|
||||||
// https://msdn.microsoft.com/de-de/library/windows/desktop/aa364960(v=vs.85).aspx
|
|
||||||
func getFileType(fd uintptr) int {
|
|
||||||
r, _, e := syscall.Syscall(procGetFileType.Addr(), 1, fd, 0, 0)
|
|
||||||
if e != 0 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return int(r)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// canUpdateStatus returns true if status lines can be printed, the process
|
// canUpdateStatus returns true if status lines can be printed, the process
|
||||||
|
@ -133,7 +101,7 @@ func canUpdateStatus(fd uintptr) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the output file type is a pipe (0x0003)
|
// check if the output file type is a pipe (0x0003)
|
||||||
if getFileType(fd) != fileTypePipe {
|
if isPipe(fd) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue