mirror of
https://github.com/octoleo/restic.git
synced 2024-12-26 04:17:29 +00:00
6b65a495b1
The termstatus must only be canceled once the command has returned. Otherwise output may be lost when the context gets canceled.
44 lines
1.1 KiB
Go
44 lines
1.1 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
|
|
"github.com/restic/restic/internal/ui"
|
|
"github.com/restic/restic/internal/ui/termstatus"
|
|
)
|
|
|
|
// setupTermstatus creates a new termstatus and reroutes globalOptions.{stdout,stderr} to it
|
|
// The returned function must be called to shut down the termstatus,
|
|
//
|
|
// Expected usage:
|
|
// ```
|
|
// term, cancel := setupTermstatus()
|
|
// defer cancel()
|
|
// // do stuff
|
|
// ```
|
|
func setupTermstatus() (*termstatus.Terminal, func()) {
|
|
var wg sync.WaitGroup
|
|
// only shutdown once cancel is called to ensure that no output is lost
|
|
cancelCtx, cancel := context.WithCancel(context.Background())
|
|
|
|
term := termstatus.New(globalOptions.stdout, globalOptions.stderr, globalOptions.Quiet)
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
term.Run(cancelCtx)
|
|
}()
|
|
|
|
// use the termstatus for stdout/stderr
|
|
prevStdout, prevStderr := globalOptions.stdout, globalOptions.stderr
|
|
stdioWrapper := ui.NewStdioWrapper(term)
|
|
globalOptions.stdout, globalOptions.stderr = stdioWrapper.Stdout(), stdioWrapper.Stderr()
|
|
|
|
return term, func() {
|
|
// shutdown termstatus
|
|
globalOptions.stdout, globalOptions.stderr = prevStdout, prevStderr
|
|
cancel()
|
|
wg.Wait()
|
|
}
|
|
}
|