termstatus: use errWriter if terminal commands fail

This commit is contained in:
Michael Eischer
2025-09-21 19:16:16 +02:00
parent 711194276c
commit f2b9ea6455
4 changed files with 26 additions and 18 deletions

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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).

View File

@@ -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)
}
}
}