github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/pkg/domain/infra/abi/terminal/sigproxy_linux.go (about)

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