| 165 | } |
| 166 | |
| 167 | func (h *hijackedIOStreamer) beginInputStream(restoreInput func()) (doneC <-chan struct{}, detachedC <-chan error) { |
| 168 | inputDone := make(chan struct{}) |
| 169 | detached := make(chan error) |
| 170 | |
| 171 | go func() { |
| 172 | if h.inputStream != nil { |
| 173 | _, err := io.Copy(h.resp.Conn, h.inputStream) |
| 174 | // We should restore the terminal as soon as possible |
| 175 | // once the connection ends so any following print |
| 176 | // messages will be in normal type. |
| 177 | restoreInput() |
| 178 | |
| 179 | logrus.Debug("[hijack] End of stdin") |
| 180 | |
| 181 | if _, ok := err.(term.EscapeError); ok { |
| 182 | detached <- err |
| 183 | return |
| 184 | } |
| 185 | |
| 186 | if err != nil { |
| 187 | // This error will also occur on the receive |
| 188 | // side (from stdout) where it will be |
| 189 | // propagated back to the caller. |
| 190 | logrus.Debugf("Error sendStdin: %s", err) |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | if err := h.resp.CloseWrite(); err != nil { |
| 195 | logrus.Debugf("Couldn't send EOF: %s", err) |
| 196 | } |
| 197 | |
| 198 | close(inputDone) |
| 199 | }() |
| 200 | |
| 201 | return inputDone, detached |
| 202 | } |
| 203 | |
| 204 | func setRawTerminal(streams command.Streams) error { |
| 205 | if err := streams.In().SetRawTerminal(); err != nil { |