mirror of
https://github.com/restic/restic.git
synced 2026-11-05 14:59:21 +00:00
ui/termstatus: extract background handling code
This commit is contained in:
1 parent
6ff7cd9050
commit
48cbbf9651
11 files changed
+18
-17
No files matched your search
@@ -0,0 +1,24 @@
|
||||
//go:build unix
|
||||
|
||||
package terminal
|
||||
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
//go:build unix
|
||||
|
||||
package terminal
|
||||
|
||||
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()
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package terminal
|
||||
|
||||
// IsProcessBackground reports whether the current process is running in the
|
||||
// background. Not implemented for this platform.
|
||||
func IsProcessBackground(_ uintptr) bool {
|
||||
return false
|
||||
}
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
|
||||
"github.com/restic/restic/internal/debug"
|
||||
"github.com/restic/restic/internal/errors"
|
||||
"github.com/restic/restic/internal/ui/termstatus"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
@@ -29,13 +28,13 @@ func startForeground(cmd *exec.Cmd) (bg func() error, err error) {
|
||||
}
|
||||
|
||||
// only move child process to foreground if restic is in the foreground
|
||||
prev, err := termstatus.Tcgetpgrp(int(tty.Fd()))
|
||||
prev, err := Tcgetpgrp(int(tty.Fd()))
|
||||
if err != nil {
|
||||
_ = tty.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
self := termstatus.Getpgrp()
|
||||
self := Getpgrp()
|
||||
if prev != self {
|
||||
debug.Log("restic is not controlling the tty; err = %v", err)
|
||||
if err := tty.Close(); err != nil {
|
||||
@@ -56,7 +55,7 @@ func startForeground(cmd *exec.Cmd) (bg func() error, err error) {
|
||||
}
|
||||
|
||||
// move the command's process group into the foreground
|
||||
err = termstatus.Tcsetpgrp(int(tty.Fd()), cmd.Process.Pid)
|
||||
err = Tcsetpgrp(int(tty.Fd()), cmd.Process.Pid)
|
||||
if err != nil {
|
||||
_ = tty.Close()
|
||||
return nil, err
|
||||
@@ -67,7 +66,7 @@ func startForeground(cmd *exec.Cmd) (bg func() error, err error) {
|
||||
signal.Reset(unix.SIGTTOU)
|
||||
|
||||
// reset the foreground process group
|
||||
err = termstatus.Tcsetpgrp(int(tty.Fd()), prev)
|
||||
err = Tcsetpgrp(int(tty.Fd()), prev)
|
||||
if err != nil {
|
||||
_ = tty.Close()
|
||||
return err
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package terminal
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
func Getpgrp() int {
|
||||
pid, _ := unix.Getpgrp()
|
||||
return pid
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
//go:build unix && !solaris
|
||||
|
||||
package terminal
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
func Getpgrp() int { return unix.Getpgrp() }
|
||||
@@ -0,0 +1,12 @@
|
||||
package terminal
|
||||
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
//go:build unix && !linux
|
||||
|
||||
package terminal
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
func Tcgetpgrp(ttyfd int) (int, error) {
|
||||
return unix.IoctlGetInt(ttyfd, unix.TIOCGPGRP)
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package terminal
|
||||
|
||||
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)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
//go:build unix && !aix
|
||||
|
||||
package terminal
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
func Tcsetpgrp(fd int, pid int) error {
|
||||
return unix.IoctlSetPointerInt(fd, unix.TIOCSPGRP, pid)
|
||||
}
|
||||
Reference in new issue
Block a user