kill.go#Action

  1. Action: func(context *cli.Context) error {
  2. if err := checkArgs(context, 1, minArgs); err != nil {
  3. return err
  4. }
  5. if err := checkArgs(context, 2, maxArgs); err != nil {
  6. return err
  7. }
  8. container, err := getContainer(context)
  9. if err != nil {
  10. return err
  11. }
  12. sigstr := context.Args().Get(1)
  13. if sigstr == "" {
  14. sigstr = "SIGTERM"
  15. }
  16. signal, err := parseSignal(sigstr)
  17. if err != nil {
  18. return err
  19. }
  20. return container.Signal(signal, context.Bool("all"))
  21. },
  22. func parseSignal(rawSignal string) (syscall.Signal, error) {
  23. s, err := strconv.Atoi(rawSignal)
  24. if err == nil {
  25. return syscall.Signal(s), nil
  26. }
  27. signal, ok := signalMap[strings.TrimPrefix(strings.ToUpper(rawSignal), "SIG")]
  28. if !ok {
  29. return -1, fmt.Errorf("unknown signal %q", rawSignal)
  30. }
  31. return signal, nil
  32. }

1) libcontainer/container_linux.go#linuxContainer.Signal

  1. func (c *linuxContainer) Signal(s os.Signal, all bool) error {
  2. if all {
  3. return signalAllProcesses(c.cgroupManager, s)
  4. }
  5. status, err := c.currentStatus()
  6. if err != nil {
  7. return err
  8. }
  9. // to avoid a PID reuse attack
  10. if status == Running || status == Created || status == Paused {
  11. if err := c.initProcess.signal(s); err != nil {
  12. return newSystemErrorWithCause(err, "signaling init process")
  13. }
  14. return nil
  15. }
  16. return newGenericError(fmt.Errorf("container not running"), ContainerNotRunning)
  17. }

1.1) libcontainer/process_linux.go#initProcess.signal

  1. func (p *initProcess) signal(sig os.Signal) error {
  2. s, ok := sig.(syscall.Signal)
  3. if !ok {
  4. return errors.New("os: unsupported signal type")
  5. }
  6. return unix.Kill(p.pid(), s)
  7. }