github.com/opencontainers/runc@v1.2.0-rc.1.0.20240520010911-492dc558cdd6/kill.go (about)

     1  package main
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"strconv"
     7  	"strings"
     8  
     9  	"github.com/opencontainers/runc/libcontainer"
    10  	"github.com/urfave/cli"
    11  	"golang.org/x/sys/unix"
    12  )
    13  
    14  var killCommand = cli.Command{
    15  	Name:  "kill",
    16  	Usage: "kill sends the specified signal (default: SIGTERM) to the container's init process",
    17  	ArgsUsage: `<container-id> [signal]
    18  
    19  Where "<container-id>" is the name for the instance of the container and
    20  "[signal]" is the signal to be sent to the init process.
    21  
    22  EXAMPLE:
    23  For example, if the container id is "ubuntu01" the following will send a "KILL"
    24  signal to the init process of the "ubuntu01" container:
    25  
    26         # runc kill ubuntu01 KILL`,
    27  	Flags: []cli.Flag{
    28  		cli.BoolFlag{
    29  			Name:   "all, a",
    30  			Usage:  "(obsoleted, do not use)",
    31  			Hidden: true,
    32  		},
    33  	},
    34  	Action: func(context *cli.Context) error {
    35  		if err := checkArgs(context, 1, minArgs); err != nil {
    36  			return err
    37  		}
    38  		if err := checkArgs(context, 2, maxArgs); err != nil {
    39  			return err
    40  		}
    41  		container, err := getContainer(context)
    42  		if err != nil {
    43  			return err
    44  		}
    45  
    46  		sigstr := context.Args().Get(1)
    47  		if sigstr == "" {
    48  			sigstr = "SIGTERM"
    49  		}
    50  
    51  		signal, err := parseSignal(sigstr)
    52  		if err != nil {
    53  			return err
    54  		}
    55  		err = container.Signal(signal)
    56  		if errors.Is(err, libcontainer.ErrNotRunning) && context.Bool("all") {
    57  			err = nil
    58  		}
    59  		return err
    60  	},
    61  }
    62  
    63  func parseSignal(rawSignal string) (unix.Signal, error) {
    64  	s, err := strconv.Atoi(rawSignal)
    65  	if err == nil {
    66  		return unix.Signal(s), nil
    67  	}
    68  	sig := strings.ToUpper(rawSignal)
    69  	if !strings.HasPrefix(sig, "SIG") {
    70  		sig = "SIG" + sig
    71  	}
    72  	signal := unix.SignalNum(sig)
    73  	if signal == 0 {
    74  		return -1, fmt.Errorf("unknown signal %q", rawSignal)
    75  	}
    76  	return signal, nil
    77  }