# File lib/phusion_passenger/message_channel.rb, line 310
        def send_io(io)
                # We read a message before actually calling #send_io
                # in order to prevent the other side from accidentally
                # read()ing past the normal data and reading our file
                # descriptor too.
                #
                # For example suppose that side A looks like this:
                #
                #   read(fd, buf, 1024)
                #   read_io(fd)
                #
                # and side B:
                #
                #   write(fd, buf, 100)
                #   send_io(fd_to_pass)
                #
                # If B completes both write() and send_io(), then A's read() call
                # reads past the 100 bytes that B sent. On some platforms, like
                # Linux, this will cause read_io() to fail. And it just so happens
                # that Ruby's IO#read method slurps more than just the given amount
                # of bytes.
                result = read
                if !result
                        raise EOFError, "End of stream"
                elsif result != ["pass IO"]
                        raise IOError, "IO passing pre-negotiation header expected"
                else
                        @io.send_io(io)
                        # Once you've sent the IO you expect to be able to close it on the
                        # sender's side, even if the other side hasn't read the IO yet.
                        # Not so: on some operating systems (I'm looking at you OS X) this
                        # can cause the receiving side to receive a bad file descriptor.
                        # The post negotiation protocol ensures that we block until the
                        # other side has really received the IO.
                        result = read
                        if !result
                                raise EOFError, "End of stream"
                        elsif result != ["got IO"]
                                raise IOError, "IO passing post-negotiation header expected"
                        end
                end
        end