github.com/containers/podman/v2@v2.2.2-0.20210501105131-c1e07d070c4c/pkg/domain/infra/abi/terminal/sigproxy_linux.go (about)

     1  package terminal
     2  
     3  import (
     4  	"os"
     5  	"syscall"
     6  
     7  	"github.com/containers/podman/v2/libpod"
     8  	"github.com/containers/podman/v2/libpod/define"
     9  	"github.com/containers/podman/v2/libpod/shutdown"
    10  	"github.com/containers/podman/v2/pkg/signal"
    11  	"github.com/pkg/errors"
    12  	"github.com/sirupsen/logrus"
    13  )
    14  
    15  // ProxySignals ...
    16  func ProxySignals(ctr *libpod.Container) {
    17  	// Stop catching the shutdown signals (SIGINT, SIGTERM) - they're going
    18  	// to the container now.
    19  	shutdown.Stop()
    20  
    21  	sigBuffer := make(chan os.Signal, 128)
    22  	signal.CatchAll(sigBuffer)
    23  
    24  	logrus.Debugf("Enabling signal proxying")
    25  
    26  	go func() {
    27  		for s := range sigBuffer {
    28  			// Ignore SIGCHLD and SIGPIPE - these are mostly likely
    29  			// intended for the podman command itself.
    30  			// SIGURG was added because of golang 1.14 and its preemptive changes
    31  			// causing more signals to "show up".
    32  			// https://github.com/containers/podman/issues/5483
    33  			if s == syscall.SIGCHLD || s == syscall.SIGPIPE || s == syscall.SIGURG {
    34  				continue
    35  			}
    36  
    37  			if err := ctr.Kill(uint(s.(syscall.Signal))); err != nil {
    38  				if errors.Cause(err) == define.ErrCtrStateInvalid {
    39  					logrus.Infof("Ceasing signal forwarding to container %s as it has stopped", ctr.ID())
    40  				} else {
    41  					logrus.Errorf("Error forwarding signal %d to container %s: %v", s, ctr.ID(), err)
    42  				}
    43  				// If the container dies, and we find out here,
    44  				// we need to forward that one signal to
    45  				// ourselves so that it is not lost, and then
    46  				// we terminate the proxy and let the defaults
    47  				// play out.
    48  				signal.StopCatch(sigBuffer)
    49  				if err := syscall.Kill(syscall.Getpid(), s.(syscall.Signal)); err != nil {
    50  					logrus.Errorf("failed to kill pid %d", syscall.Getpid())
    51  				}
    52  				return
    53  			}
    54  		}
    55  	}()
    56  }