func readData(conn net.Conn) (*container_daemon.ResponseMessage, error) { var b [2048]byte var oob [2048]byte var response container_daemon.ResponseMessage n, oobn, _, _, err := conn.(*net.UnixConn).ReadMsgUnix(b[:], oob[:]) if err != nil { return nil, fmt.Errorf("unix_socket: failed to read unix msg: %s (read: %d, %d)", err, n, oobn) } if n > 0 { err := json.Unmarshal(b[:n], &response) if err != nil { return nil, fmt.Errorf("unix_socket: Unmarshal failed: %s", err) } if response.ErrMessage != "" { return nil, errors.New(response.ErrMessage) } } else { return nil, errors.New("unix_socket: No response received") } scms, err := syscall.ParseSocketControlMessage(oob[:oobn]) if err != nil { return nil, fmt.Errorf("unix_socket: failed to parse socket control message: %s", err) } if len(scms) > 0 { scm := scms[0] fds, err := syscall.ParseUnixRights(&scm) if err != nil { return nil, fmt.Errorf("unix_socket: failed to parse unix rights: %s", err) } response.Files = make([]container_daemon.StreamingFile, len(fds)) for i, fd := range fds { response.Files[i] = os.NewFile(uintptr(fd), fmt.Sprintf("/dev/fake-fd-%d", i)) } } return &response, nil }
data, err := json.Marshal(&link.SignalMsg{Signal: signalSent}) Expect(err).ToNot(HaveOccurred()) signalWriter.Write(data) Eventually(socketConnector.ConnectCallCount).Should(Equal(1)) }) }) }) Context("when the process is interactive (i.e. connected to a TTY)", func() { BeforeEach(func() { process.Spec.TTY = &garden.TTYSpec{} }) It("makes stdin a raw terminal (because the remote terminal will handle echoing etc.)", func() { response.Files = []container_daemon.StreamingFile{FakeFd(0), FakeFd(0)} response.Pid = 0 socketConnector.ConnectReturns(response, nil) Expect(process.Start()).To(Succeed()) Expect(fakeTerm.SetRawTerminalCallCount()).To(Equal(1)) }) It("restores the terminal state when the process is cleaned up", func() { response.Files = []container_daemon.StreamingFile{FakeFd(0), FakeFd(0)} response.Pid = 0 socketConnector.ConnectReturns(response, nil) state := &term.State{}