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 }