kill.go 1.7 KB

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