github.com/fcwu/docker@v1.4.2-0.20150115145920-2a69ca89f0df/daemon/kill.go (about)

     1  package daemon
     2  
     3  import (
     4  	"strconv"
     5  	"strings"
     6  	"syscall"
     7  
     8  	"github.com/docker/docker/engine"
     9  	"github.com/docker/docker/pkg/signal"
    10  )
    11  
    12  // ContainerKill send signal to the container
    13  // If no signal is given (sig 0), then Kill with SIGKILL and wait
    14  // for the container to exit.
    15  // If a signal is given, then just send it to the container and return.
    16  func (daemon *Daemon) ContainerKill(job *engine.Job) engine.Status {
    17  	if n := len(job.Args); n < 1 || n > 2 {
    18  		return job.Errorf("Usage: %s CONTAINER [SIGNAL]", job.Name)
    19  	}
    20  	var (
    21  		name = job.Args[0]
    22  		sig  uint64
    23  		err  error
    24  	)
    25  
    26  	// If we have a signal, look at it. Otherwise, do nothing
    27  	if len(job.Args) == 2 && job.Args[1] != "" {
    28  		// Check if we passed the signal as a number:
    29  		// The largest legal signal is 31, so let's parse on 5 bits
    30  		sig, err = strconv.ParseUint(job.Args[1], 10, 5)
    31  		if err != nil {
    32  			// The signal is not a number, treat it as a string (either like "KILL" or like "SIGKILL")
    33  			sig = uint64(signal.SignalMap[strings.TrimPrefix(job.Args[1], "SIG")])
    34  		}
    35  
    36  		if sig == 0 {
    37  			return job.Errorf("Invalid signal: %s", job.Args[1])
    38  		}
    39  	}
    40  
    41  	if container := daemon.Get(name); container != nil {
    42  		// If no signal is passed, or SIGKILL, perform regular Kill (SIGKILL + wait())
    43  		if sig == 0 || syscall.Signal(sig) == syscall.SIGKILL {
    44  			if err := container.Kill(); err != nil {
    45  				return job.Errorf("Cannot kill container %s: %s", name, err)
    46  			}
    47  			container.LogEvent("kill")
    48  		} else {
    49  			// Otherwise, just send the requested signal
    50  			if err := container.KillSig(int(sig)); err != nil {
    51  				return job.Errorf("Cannot kill container %s: %s", name, err)
    52  			}
    53  			// FIXME: Add event for signals
    54  		}
    55  	} else {
    56  		return job.Errorf("No such container: %s", name)
    57  	}
    58  	return engine.StatusOK
    59  }