github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/pkg/domain/infra/abi/terminal/terminal_linux.go (about) 1 package terminal 2 3 import ( 4 "bufio" 5 "context" 6 "fmt" 7 "os" 8 9 "github.com/hanks177/podman/v4/libpod" 10 "github.com/hanks177/podman/v4/libpod/define" 11 "github.com/pkg/errors" 12 "github.com/sirupsen/logrus" 13 "golang.org/x/term" 14 ) 15 16 // ExecAttachCtr execs and attaches to a container 17 func ExecAttachCtr(ctx context.Context, ctr *libpod.Container, execConfig *libpod.ExecConfig, streams *define.AttachStreams) (int, error) { 18 var resize chan define.TerminalSize 19 haveTerminal := term.IsTerminal(int(os.Stdin.Fd())) 20 21 // Check if we are attached to a terminal. If we are, generate resize 22 // events, and set the terminal to raw mode 23 if haveTerminal && execConfig.Terminal { 24 resize = make(chan define.TerminalSize) 25 cancel, oldTermState, err := handleTerminalAttach(ctx, resize) 26 if err != nil { 27 return -1, err 28 } 29 defer cancel() 30 defer func() { 31 if err := restoreTerminal(oldTermState); err != nil { 32 logrus.Errorf("Unable to restore terminal: %q", err) 33 } 34 }() 35 } 36 return ctr.Exec(execConfig, streams, resize) 37 } 38 39 // StartAttachCtr starts and (if required) attaches to a container 40 // if you change the signature of this function from os.File to io.Writer, it will trigger a downstream 41 // error. we may need to just lint disable this one. 42 func StartAttachCtr(ctx context.Context, ctr *libpod.Container, stdout, stderr, stdin *os.File, detachKeys string, sigProxy bool, startContainer bool) error { //nolint: interfacer 43 resize := make(chan define.TerminalSize) 44 45 haveTerminal := term.IsTerminal(int(os.Stdin.Fd())) 46 47 // Check if we are attached to a terminal. If we are, generate resize 48 // events, and set the terminal to raw mode 49 if haveTerminal && ctr.Spec().Process.Terminal { 50 cancel, oldTermState, err := handleTerminalAttach(ctx, resize) 51 if err != nil { 52 return err 53 } 54 defer func() { 55 if err := restoreTerminal(oldTermState); err != nil { 56 logrus.Errorf("Unable to restore terminal: %q", err) 57 } 58 }() 59 defer cancel() 60 } 61 62 streams := new(define.AttachStreams) 63 streams.OutputStream = stdout 64 streams.ErrorStream = stderr 65 streams.InputStream = bufio.NewReader(stdin) 66 streams.AttachOutput = true 67 streams.AttachError = true 68 streams.AttachInput = true 69 70 if stdout == nil { 71 logrus.Debugf("Not attaching to stdout") 72 streams.AttachOutput = false 73 } 74 if stderr == nil { 75 logrus.Debugf("Not attaching to stderr") 76 streams.AttachError = false 77 } 78 if stdin == nil { 79 logrus.Debugf("Not attaching to stdin") 80 streams.AttachInput = false 81 } 82 83 if !startContainer { 84 if sigProxy { 85 ProxySignals(ctr) 86 } 87 88 return ctr.Attach(streams, detachKeys, resize) 89 } 90 91 attachChan, err := ctr.StartAndAttach(ctx, streams, detachKeys, resize, true) 92 if err != nil { 93 return err 94 } 95 96 if sigProxy { 97 ProxySignals(ctr) 98 } 99 100 if stdout == nil && stderr == nil { 101 fmt.Printf("%s\n", ctr.ID()) 102 } 103 104 err = <-attachChan 105 if err != nil { 106 return errors.Wrapf(err, "error attaching to container %s", ctr.ID()) 107 } 108 109 return nil 110 }