ui/termstatus: extract background handling code

This commit is contained in:
Michael Eischer
2025-09-07 12:15:27 +02:00
parent 6ff7cd9050
commit 48cbbf9651
11 changed files with 18 additions and 17 deletions

View File

@@ -1,24 +0,0 @@
//go:build unix
package termstatus
import "github.com/restic/restic/internal/debug"
// IsProcessBackground reports whether the current process is running in the
// background. fd must be a file descriptor for the terminal.
func IsProcessBackground(fd uintptr) bool {
bg, err := isProcessBackground(int(fd))
if err != nil {
debug.Log("Can't check if we are in the background. Using default behaviour. Error: %s\n", err.Error())
return false
}
return bg
}
func isProcessBackground(fd int) (bg bool, err error) {
pgid, err := Tcgetpgrp(fd)
if err != nil {
return false, err
}
return pgid != Getpgrp(), nil
}

View File

@@ -1,22 +0,0 @@
//go:build unix
package termstatus
import (
"os"
"testing"
rtest "github.com/restic/restic/internal/test"
)
func TestIsProcessBackground(t *testing.T) {
tty, err := os.Open("/dev/tty")
if err != nil {
t.Skipf("can't open terminal: %v", err)
}
_, err = isProcessBackground(int(tty.Fd()))
rtest.OK(t, err)
_ = tty.Close()
}

View File

@@ -1,7 +0,0 @@
package termstatus
// IsProcessBackground reports whether the current process is running in the
// background. Not implemented for this platform.
func IsProcessBackground(_ uintptr) bool {
return false
}

View File

@@ -1,8 +0,0 @@
package termstatus
import "golang.org/x/sys/unix"
func Getpgrp() int {
pid, _ := unix.Getpgrp()
return pid
}

View File

@@ -1,7 +0,0 @@
//go:build unix && !solaris
package termstatus
import "golang.org/x/sys/unix"
func Getpgrp() int { return unix.Getpgrp() }

View File

@@ -12,6 +12,8 @@ import (
"golang.org/x/term"
"golang.org/x/text/width"
"github.com/restic/restic/internal/terminal"
)
// Terminal is used to write messages and display status lines which can be
@@ -101,14 +103,14 @@ func (t *Terminal) run(ctx context.Context) {
for {
select {
case <-ctx.Done():
if !IsProcessBackground(t.fd) {
if !terminal.IsProcessBackground(t.fd) {
t.writeStatus([]string{})
}
return
case msg := <-t.msg:
if IsProcessBackground(t.fd) {
if terminal.IsProcessBackground(t.fd) {
// ignore all messages, do nothing, we are in the background process group
continue
}
@@ -140,7 +142,7 @@ func (t *Terminal) run(ctx context.Context) {
}
case stat := <-t.status:
if IsProcessBackground(t.fd) {
if terminal.IsProcessBackground(t.fd) {
// ignore all messages, do nothing, we are in the background process group
continue
}

View File

@@ -1,12 +0,0 @@
package termstatus
import "golang.org/x/sys/unix"
func Tcgetpgrp(ttyfd int) (int, error) {
// We need to use IoctlGetUint32 here, because pid_t is 32-bit even on
// 64-bit Linux. IoctlGetInt doesn't work on big-endian platforms:
// https://github.com/golang/go/issues/45585
// https://github.com/golang/go/issues/60429
pid, err := unix.IoctlGetUint32(ttyfd, unix.TIOCGPGRP)
return int(pid), err
}

View File

@@ -1,9 +0,0 @@
//go:build unix && !linux
package termstatus
import "golang.org/x/sys/unix"
func Tcgetpgrp(ttyfd int) (int, error) {
return unix.IoctlGetInt(ttyfd, unix.TIOCGPGRP)
}

View File

@@ -1,10 +0,0 @@
package termstatus
import "golang.org/x/sys/unix"
func Tcsetpgrp(fd int, pid int) error {
// The second argument to IoctlSetPointerInt has type int on AIX,
// but the constant overflows 64-bit int, hence the two-step cast.
req := uint(unix.TIOCSPGRP)
return unix.IoctlSetPointerInt(fd, int(req), pid)
}

View File

@@ -1,9 +0,0 @@
//go:build unix && !aix
package termstatus
import "golang.org/x/sys/unix"
func Tcsetpgrp(fd int, pid int) error {
return unix.IoctlSetPointerInt(fd, unix.TIOCSPGRP, pid)
}