github.com/lmars/docker@v1.6.0-rc2/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 container, err := daemon.Get(name) 42 if err != nil { 43 return job.Error(err) 44 } 45 46 // If no signal is passed, or SIGKILL, perform regular Kill (SIGKILL + wait()) 47 if sig == 0 || syscall.Signal(sig) == syscall.SIGKILL { 48 if err := container.Kill(); err != nil { 49 return job.Errorf("Cannot kill container %s: %s", name, err) 50 } 51 container.LogEvent("kill") 52 } else { 53 // Otherwise, just send the requested signal 54 if err := container.KillSig(int(sig)); err != nil { 55 return job.Errorf("Cannot kill container %s: %s", name, err) 56 } 57 // FIXME: Add event for signals 58 } 59 return engine.StatusOK 60 }