예제 #1
0
파일: recvtty.go 프로젝트: jfrazelle/runc
func handleSingle(path string) error {
	// Open a socket.
	ln, err := net.Listen("unix", path)
	if err != nil {
		return err
	}
	defer ln.Close()

	// We only accept a single connection, since we can only really have
	// one reader for os.Stdin. Plus this is all a PoC.
	conn, err := ln.Accept()
	if err != nil {
		return err
	}
	defer conn.Close()

	// Close ln, to allow for other instances to take over.
	ln.Close()

	// Get the fd of the connection.
	unixconn, ok := conn.(*net.UnixConn)
	if !ok {
		return fmt.Errorf("failed to cast to unixconn")
	}

	socket, err := unixconn.File()
	if err != nil {
		return err
	}
	defer socket.Close()

	// Get the master file descriptor from runC.
	master, err := utils.RecvFd(socket)
	if err != nil {
		return err
	}

	// Print the file descriptor tag.
	ti, err := libcontainer.GetTerminalInfo(master.Name())
	if err != nil {
		return err
	}
	fmt.Printf("[recvtty] received masterfd: container '%s'\n", ti.ContainerID)

	// Copy from our stdio to the master fd.
	quitChan := make(chan struct{})
	go func() {
		io.Copy(os.Stdout, master)
		quitChan <- struct{}{}
	}()
	go func() {
		io.Copy(master, os.Stdin)
		quitChan <- struct{}{}
	}()

	// Only close the master fd once we've stopped copying.
	<-quitChan
	master.Close()
	return nil
}
예제 #2
0
파일: recvtty.go 프로젝트: jfrazelle/runc
func handleNull(path string) error {
	// Open a socket.
	ln, err := net.Listen("unix", path)
	if err != nil {
		return err
	}
	defer ln.Close()

	// As opposed to handleSingle we accept as many connections as we get, but
	// we don't interact with Stdin at all (and we copy stdout to /dev/null).
	for {
		conn, err := ln.Accept()
		if err != nil {
			return err
		}
		go func(conn net.Conn) {
			// Don't leave references lying around.
			defer conn.Close()

			// Get the fd of the connection.
			unixconn, ok := conn.(*net.UnixConn)
			if !ok {
				return
			}

			socket, err := unixconn.File()
			if err != nil {
				return
			}
			defer socket.Close()

			// Get the master file descriptor from runC.
			master, err := utils.RecvFd(socket)
			if err != nil {
				return
			}

			// Print the file descriptor tag.
			ti, err := libcontainer.GetTerminalInfo(master.Name())
			if err != nil {
				bail(err)
			}
			fmt.Printf("[recvtty] received masterfd: container '%s'\n", ti.ContainerID)

			// Just do a dumb copy to /dev/null.
			devnull, err := os.OpenFile("/dev/null", os.O_RDWR, 0)
			if err != nil {
				// TODO: Handle this nicely.
				return
			}

			io.Copy(devnull, master)
			devnull.Close()
		}(conn)
	}
}