forward handles the main signal event loop forwarding, resizing, or reaping depending on the signal received.
(process *libcontainer.Process, tty *tty, detach bool)
| 62 | // forward handles the main signal event loop forwarding, resizing, or reaping depending |
| 63 | // on the signal received. |
| 64 | func (h *signalHandler) forward(process *libcontainer.Process, tty *tty, detach bool) (int, error) { |
| 65 | // make sure we know the pid of our main process so that we can return |
| 66 | // after it dies. |
| 67 | if detach && h.notifySocket == nil { |
| 68 | return 0, nil |
| 69 | } |
| 70 | |
| 71 | pid1, err := process.Pid() |
| 72 | if err != nil { |
| 73 | return -1, err |
| 74 | } |
| 75 | |
| 76 | if h.notifySocket != nil { |
| 77 | if detach { |
| 78 | _ = h.notifySocket.run(pid1) |
| 79 | return 0, nil |
| 80 | } |
| 81 | _ = h.notifySocket.run(os.Getpid()) |
| 82 | go func() { _ = h.notifySocket.run(0) }() |
| 83 | } |
| 84 | |
| 85 | // Perform the initial tty resize. Always ignore errors resizing because |
| 86 | // stdout might have disappeared (due to races with when SIGHUP is sent). |
| 87 | _ = tty.resize() |
| 88 | // Handle and forward signals. |
| 89 | for s := range h.signals { |
| 90 | switch s { |
| 91 | case unix.SIGWINCH: |
| 92 | // Ignore errors resizing, as above. |
| 93 | _ = tty.resize() |
| 94 | case unix.SIGCHLD: |
| 95 | exits, err := h.reap() |
| 96 | if err != nil { |
| 97 | logrus.Error(err) |
| 98 | } |
| 99 | for _, e := range exits { |
| 100 | logrus.WithFields(logrus.Fields{ |
| 101 | "pid": e.pid, |
| 102 | "status": e.status, |
| 103 | }).Debug("process exited") |
| 104 | if e.pid == pid1 { |
| 105 | // call Wait() on the process even though we already have the exit |
| 106 | // status because we must ensure that any of the go specific process |
| 107 | // fun such as flushing pipes are complete before we return. |
| 108 | _, _ = process.Wait() |
| 109 | return e.status, nil |
| 110 | } |
| 111 | } |
| 112 | case unix.SIGURG: |
| 113 | // SIGURG is used by go runtime for async preemptive |
| 114 | // scheduling, so runc receives it from time to time, |
| 115 | // and it should not be forwarded to the container. |
| 116 | // Do nothing. |
| 117 | default: |
| 118 | us := s.(unix.Signal) |
| 119 | logrus.Debugf("forwarding signal %d (%s) to %d", int(us), unix.SignalName(us), pid1) |
| 120 | if err := process.Signal(s); err != nil { |
| 121 | logrus.Error(err) |