mirror of
https://github.com/restic/restic.git
synced 2025-12-10 21:21:48 +00:00
termstatus: use errWriter if terminal commands fail
This commit is contained in:
@@ -4,7 +4,6 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -18,22 +17,22 @@ const (
|
||||
|
||||
// PosixClearCurrentLine removes all characters from the current line and resets the
|
||||
// cursor position to the first column.
|
||||
func PosixClearCurrentLine(wr io.Writer, _ uintptr) {
|
||||
func PosixClearCurrentLine(wr io.Writer, _ uintptr) error {
|
||||
// clear current line
|
||||
_, err := wr.Write([]byte(PosixControlMoveCursorHome + PosixControlClearLine))
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "write failed: %v\n", err)
|
||||
return
|
||||
return fmt.Errorf("write failed: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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 = append(data, bytes.Repeat([]byte(PosixControlMoveCursorUp), n)...)
|
||||
_, err := wr.Write(data)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "write failed: %v\n", err)
|
||||
return
|
||||
return fmt.Errorf("write failed: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -12,12 +12,12 @@ import (
|
||||
|
||||
// ClearCurrentLine removes all characters from the current line and resets the
|
||||
// cursor position to the first column.
|
||||
func ClearCurrentLine(_ uintptr) func(io.Writer, uintptr) {
|
||||
func ClearCurrentLine(_ uintptr) func(io.Writer, uintptr) error {
|
||||
return PosixClearCurrentLine
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
|
||||
// clearCurrentLine removes all characters from the current line and resets the
|
||||
// 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
|
||||
if isWindowsTerminal(fd) {
|
||||
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.
|
||||
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
|
||||
if isWindowsTerminal(fd) {
|
||||
return windowsMoveCursorUp
|
||||
@@ -45,7 +45,7 @@ var (
|
||||
|
||||
// windowsClearCurrentLine removes all characters from the current line and
|
||||
// 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
|
||||
windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info)
|
||||
|
||||
@@ -58,10 +58,11 @@ func windowsClearCurrentLine(_ io.Writer, fd uintptr) {
|
||||
count = uint32(info.Size.X)
|
||||
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)))
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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
|
||||
windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info)
|
||||
|
||||
@@ -70,6 +71,7 @@ func windowsMoveCursorUp(_ io.Writer, fd uintptr, n int) {
|
||||
X: 0,
|
||||
Y: info.CursorPosition.Y - int16(n),
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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
|
||||
closed chan struct{}
|
||||
|
||||
clearCurrentLine func(io.Writer, uintptr)
|
||||
moveCursorUp func(io.Writer, uintptr, int)
|
||||
clearCurrentLine func(io.Writer, uintptr) error
|
||||
moveCursorUp func(io.Writer, uintptr, int) error
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
if msg.err {
|
||||
@@ -256,7 +259,9 @@ func (t *Terminal) writeStatus(status []string) {
|
||||
t.lastStatusLen = statusLen
|
||||
|
||||
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))
|
||||
if err != nil {
|
||||
@@ -265,7 +270,9 @@ func (t *Terminal) writeStatus(status []string) {
|
||||
}
|
||||
|
||||
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