(Note: I'm no longer on the mailing list; so if you wish to respond
to me, please be certain to include my email address in the response.
Also, [EMAIL PROTECTED] no longer works FYI.  Thanks.)

Granted we're running an older copy of mod_perl; but when we noticed
that we were getting hammered by the spam of "rwrite returned -1"
in our log files, I took a look at the source code.  I then compared
it to the current source code; I believe I have found a programming
logic error that is still in the current version.  Below is the
code (from the current version) that I believe needs to be modified
for correctness (in the write_client function):

        while(len > 0) {
            sent = 0;
            if(len < HUGE_STRING_LEN) {
                sent = rwrite(buffer, len, r);
            }
            else {
                sent = rwrite(buffer, HUGE_STRING_LEN, r);
                buffer += HUGE_STRING_LEN;
            }
            if(sent < 0) {
                rwrite_neg_trace(r);
                break;
            }
            len -= sent;
            RETVAL += sent;
        }

Notice that if len < HUGE_STRING_LEN; we REQUEST to write 'len' bytes,
but we only write 'sent' bytes.  If 0 < sent < len; then we iterate
back over this while loop because len > 0 after the len -= sent command.
On the next write, however, we are rewriting from the position the
buffer had on the LAST write because the buffer was not incremented.

Notice also, that if len >= HUGE_STRING_LEN that we are requesting
to write HUGE_STRING_LEN bytes; but we only write 'sent' bytes.  Now,
if sent < HUGE_STRING_LEN, then we decrement our len by the correct
number of bytes--but we increment our buffer HUGE_STRING_LEN - sent
bytes beyond the correct position.

Below is code that corrects for these counting errors.  I've consolidated
the rwrite into one command using the ?: operator to decide the length
to request be written.  Then I've incremented buffer by the correct the
amount sent--no matter what is written this incrementation will be correct.

        while(len > 0) {
            sent = rwrite (buffer,
                          (len<HUGE_STRING_LEN) ? len : HUGE_STRING_LEN,
                          r );
            if(sent < 0) {
                rwrite_neg_trace(r);
                break;
            }
            buffer += sent;
            len -= sent;
            RETVAL += sent;
        }

I look forward to any comments you have on this; including "you've missed
the point of the function entirely" if that is the case. :)

-- 
Michael Douglass
Texas Networking, Inc.

  Any sufficiently advanced bug is indistinguishable for a feature.
    -- from some indian guy

Reply via email to