mirror of
https://github.com/restic/restic.git
synced 2025-12-11 18:47:50 +00:00
termstatus: use errWriter if terminal commands fail
This commit is contained in:
@@ -4,7 +4,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -18,22 +17,22 @@ const (
|
|||||||
|
|
||||||
// PosixClearCurrentLine removes all characters from the current line and resets the
|
// PosixClearCurrentLine removes all characters from the current line and resets the
|
||||||
// cursor position to the first column.
|
// cursor position to the first column.
|
||||||
func PosixClearCurrentLine(wr io.Writer, _ uintptr) {
|
func PosixClearCurrentLine(wr io.Writer, _ uintptr) error {
|
||||||
// clear current line
|
// clear current line
|
||||||
_, err := wr.Write([]byte(PosixControlMoveCursorHome + PosixControlClearLine))
|
_, err := wr.Write([]byte(PosixControlMoveCursorHome + PosixControlClearLine))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "write failed: %v\n", err)
|
return fmt.Errorf("write failed: %w", err)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PosixMoveCursorUp moves the cursor to the line n lines above the current one.
|
// PosixMoveCursorUp moves the cursor to the line n lines above the current one.
|
||||||
func PosixMoveCursorUp(wr io.Writer, _ uintptr, n int) {
|
func PosixMoveCursorUp(wr io.Writer, _ uintptr, n int) error {
|
||||||
data := []byte(PosixControlMoveCursorHome)
|
data := []byte(PosixControlMoveCursorHome)
|
||||||
data = append(data, bytes.Repeat([]byte(PosixControlMoveCursorUp), n)...)
|
data = append(data, bytes.Repeat([]byte(PosixControlMoveCursorUp), n)...)
|
||||||
_, err := wr.Write(data)
|
_, err := wr.Write(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "write failed: %v\n", err)
|
return fmt.Errorf("write failed: %w", err)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,12 +12,12 @@ import (
|
|||||||
|
|
||||||
// ClearCurrentLine removes all characters from the current line and resets the
|
// ClearCurrentLine removes all characters from the current line and resets the
|
||||||
// cursor position to the first column.
|
// cursor position to the first column.
|
||||||
func ClearCurrentLine(_ uintptr) func(io.Writer, uintptr) {
|
func ClearCurrentLine(_ uintptr) func(io.Writer, uintptr) error {
|
||||||
return PosixClearCurrentLine
|
return PosixClearCurrentLine
|
||||||
}
|
}
|
||||||
|
|
||||||
// MoveCursorUp moves the cursor to the line n lines above the current one.
|
// MoveCursorUp moves the cursor to the line n lines above the current one.
|
||||||
func MoveCursorUp(_ uintptr) func(io.Writer, uintptr, int) {
|
func MoveCursorUp(_ uintptr) func(io.Writer, uintptr, int) error {
|
||||||
return PosixMoveCursorUp
|
return PosixMoveCursorUp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import (
|
|||||||
|
|
||||||
// clearCurrentLine removes all characters from the current line and resets the
|
// clearCurrentLine removes all characters from the current line and resets the
|
||||||
// cursor position to the first column.
|
// cursor position to the first column.
|
||||||
func ClearCurrentLine(fd uintptr) func(io.Writer, uintptr) {
|
func ClearCurrentLine(fd uintptr) func(io.Writer, uintptr) error {
|
||||||
// easy case, the terminal is cmd or psh, without redirection
|
// easy case, the terminal is cmd or psh, without redirection
|
||||||
if isWindowsTerminal(fd) {
|
if isWindowsTerminal(fd) {
|
||||||
return windowsClearCurrentLine
|
return windowsClearCurrentLine
|
||||||
@@ -26,7 +26,7 @@ func ClearCurrentLine(fd uintptr) func(io.Writer, uintptr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// moveCursorUp moves the cursor to the line n lines above the current one.
|
// moveCursorUp moves the cursor to the line n lines above the current one.
|
||||||
func MoveCursorUp(fd uintptr) func(io.Writer, uintptr, int) {
|
func MoveCursorUp(fd uintptr) func(io.Writer, uintptr, int) error {
|
||||||
// easy case, the terminal is cmd or psh, without redirection
|
// easy case, the terminal is cmd or psh, without redirection
|
||||||
if isWindowsTerminal(fd) {
|
if isWindowsTerminal(fd) {
|
||||||
return windowsMoveCursorUp
|
return windowsMoveCursorUp
|
||||||
@@ -45,7 +45,7 @@ var (
|
|||||||
|
|
||||||
// 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(_ io.Writer, fd uintptr) {
|
func windowsClearCurrentLine(_ io.Writer, fd uintptr) error {
|
||||||
var info windows.ConsoleScreenBufferInfo
|
var info windows.ConsoleScreenBufferInfo
|
||||||
windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info)
|
windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info)
|
||||||
|
|
||||||
@@ -58,10 +58,11 @@ func windowsClearCurrentLine(_ io.Writer, fd uintptr) {
|
|||||||
count = uint32(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)))
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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(_ io.Writer, fd uintptr, n int) {
|
func windowsMoveCursorUp(_ io.Writer, fd uintptr, n int) error {
|
||||||
var info windows.ConsoleScreenBufferInfo
|
var info windows.ConsoleScreenBufferInfo
|
||||||
windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info)
|
windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info)
|
||||||
|
|
||||||
@@ -70,6 +71,7 @@ func windowsMoveCursorUp(_ io.Writer, fd uintptr, n int) {
|
|||||||
X: 0,
|
X: 0,
|
||||||
Y: info.CursorPosition.Y - int16(n),
|
Y: info.CursorPosition.Y - int16(n),
|
||||||
})
|
})
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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).
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ type Terminal struct {
|
|||||||
// yield a default value immediately
|
// yield a default value immediately
|
||||||
closed chan struct{}
|
closed chan struct{}
|
||||||
|
|
||||||
clearCurrentLine func(io.Writer, uintptr)
|
clearCurrentLine func(io.Writer, uintptr) error
|
||||||
moveCursorUp func(io.Writer, uintptr, int)
|
moveCursorUp func(io.Writer, uintptr, int) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type message struct {
|
type message struct {
|
||||||
@@ -214,7 +214,10 @@ func (t *Terminal) run(ctx context.Context) {
|
|||||||
// ignore all messages, do nothing, we are in the background process group
|
// ignore all messages, do nothing, we are in the background process group
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
t.clearCurrentLine(t.wr, t.fd)
|
if err := t.clearCurrentLine(t.wr, t.fd); err != nil {
|
||||||
|
_, _ = fmt.Fprintf(t.errWriter, "write failed: %v\n", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
var dst io.Writer
|
var dst io.Writer
|
||||||
if msg.err {
|
if msg.err {
|
||||||
@@ -256,7 +259,9 @@ func (t *Terminal) writeStatus(status []string) {
|
|||||||
t.lastStatusLen = statusLen
|
t.lastStatusLen = statusLen
|
||||||
|
|
||||||
for _, line := range status {
|
for _, line := range status {
|
||||||
t.clearCurrentLine(t.wr, t.fd)
|
if err := t.clearCurrentLine(t.wr, t.fd); err != nil {
|
||||||
|
_, _ = fmt.Fprintf(t.errWriter, "write failed: %v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
_, err := t.wr.Write([]byte(line))
|
_, err := t.wr.Write([]byte(line))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -265,7 +270,9 @@ func (t *Terminal) writeStatus(status []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(status) > 0 {
|
if len(status) > 0 {
|
||||||
t.moveCursorUp(t.wr, t.fd, len(status)-1)
|
if err := t.moveCursorUp(t.wr, t.fd, len(status)-1); err != nil {
|
||||||
|
_, _ = fmt.Fprintf(t.errWriter, "write failed: %v\n", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user