You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by "Liu, Hui (GXS)" <Hu...@gxs.com> on 2003/03/04 18:30:20 UTC

Trouble with sysread in modperl

There appears to be a bug with the read and sysread functions when being
used in a loop to read STDIN.  We're using a loop to read from STDIN in 4k
blocks, and the read or sysread appears to work great until the very last
read to pick up the final partial block.  Here is the code:

   $readSize = &min($bytesLeft, $blockReadSize);                           
   $bufferLength  = length($buffer);                                       
   $bytesRead = sysread(STDIN, $dataRead, $readSize);                      
   &html("bytesRead=[$bytesRead . $bufferLength . $dataRead]") if ($debug);
   if (!(defined $bytesRead)) {                                            
       $bytesRead = 0;                                                     
   }                                                                       
   $buffer .= $dataRead;                                                   
In the last loop, the values that are returned in the debug statement are:
674 . 3268 . 
So sysread says that 674 bytes were read, however $dataRead is empty.  Both
read and sysread exhibit the same behavior, returning the right number of
bytes to be read, but not populating the variable with the actual data.
This code works fine in versions of Perl other than Apache modperl.  Has
anyone experienced this behavior and have any suggestions?

Re: Trouble with sysread in modperl

Posted by Stas Bekman <st...@stason.org>.
Liu, Hui (GXS) wrote:
> There appears to be a bug with the read and sysread functions when being 
> used in a loop to read STDIN.  We're using a loop to read from STDIN in 
> 4k blocks, and the read or sysread appears to work great until the very 
> last read to pick up the final partial block.  Here is the code:
> 
>    $readSize = &min($bytesLeft, $blockReadSize);                          
>    $bufferLength  = length($buffer);                                      
>    $bytesRead = sysread(STDIN, $dataRead, $readSize);                     
>    &html("bytesRead=[$bytesRead . $bufferLength . $dataRead]") if ($debug);
>    if (!(defined $bytesRead)) {                                           
>        $bytesRead = 0;                                                    
>    }                                                                      
>    $buffer .= $dataRead;                                                  
> In the last loop, the values that are returned in the debug statement 
> are:   674 . 3268 .
> So sysread says that 674 bytes were read, however $dataRead is empty.  
> Both read and sysread exhibit the same behavior, returning the right 
> number of bytes to be read, but not populating the variable with the 
> actual data.  This code works fine in versions of Perl other than Apache 
> modperl.  Has anyone experienced this behavior and have any suggestions?

Could it be the buffering issue as described in the manpage?

perldoc -f sysread:

        sysread FILEHANDLE,SCALAR,LENGTH,OFFSET
        sysread FILEHANDLE,SCALAR,LENGTH
                Attempts to read LENGTH characters of data into variable SCALAR
                from the specified FILEHANDLE, using the system call read(2).
                It bypasses buffered IO, so mixing this with other kinds of
                reads, "print", "write", "seek", "tell", or "eof" can cause
                confusion because stdio usually buffers data.  Returns the num-
                ber of characters actually read, 0 at end of file, or undef if
                there was an error.  SCALAR will be grown or shrunk so that the
                last byte actually read is the last byte of the scalar after
                the read.
                [...]

can you try whether you get all the data, by reading via <STDIN> (even though 
you have no control over chunks size)



__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


Re: Trouble with sysread in modperl

Posted by Larry Leszczynski <la...@furph.com>.
Hello -

> There appears to be a bug with the read and sysread functions when being
> used in a loop to read STDIN.  We're using a loop to read from STDIN in 4k
> blocks, and the read or sysread appears to work great until the very last
> read to pick up the final partial block.
[snip]

Not sure about that error, but by any chance are you trying to read POSTed
data from the request?  If so, all you need to do is:

   my $content;
   $r->read($content, $r->header_in('Content-length'));

(mod_perl cookbook recipe 3.6)


Larry Leszczynski
larryl@furph.com