trace (PGconn)

    /*
     * call-seq:
     *    conn.trace( stream ) -> nil
     *
     * Enables tracing message passing between backend. The
     * trace message will be written to the stream _stream_,
     * which must implement a method +fileno+ that returns
     * a writable file descriptor.
     */
    static VALUE
    pgconn_trace(VALUE self, VALUE stream)
    {
            FILE *fp;
            VALUE fileno;
            FILE *new_fp;
            int old_fd, new_fd;
            VALUE new_file;

            if(rb_respond_to(stream,rb_intern("fileno")) == Qfalse)
                    rb_raise(rb_eArgError, "stream does not respond to method: fileno");

            fileno = rb_funcall(stream, rb_intern("fileno"), 0);
            if(fileno == Qnil)
                    rb_raise(rb_eArgError, "can't get file descriptor from stream");

            /* Duplicate the file descriptor and re-open
             * it. Then, make it into a ruby File object
             * and assign it to an instance variable.
             * This prevents a problem when the File
             * object passed to this function is closed
             * before the connection object is. */
            old_fd = NUM2INT(fileno);
            new_fd = dup(old_fd);
            new_fp = fdopen(new_fd, "w");

            if(new_fp == NULL)
                    rb_raise(rb_eArgError, "stream is not writable");

            new_file = rb_funcall(rb_cIO, rb_intern("new"), 1, INT2NUM(new_fd));
            rb_iv_set(self, "@trace_stream", new_file);

            PQtrace(get_pgconn(self), new_fp);
            return Qnil;
    }