develooper Front page | perl.perl5.porters | Postings from April 2011

sysread on PerlIO::scalar

From:
H.Merijn Brand
Date:
April 29, 2011 04:54
Subject:
sysread on PerlIO::scalar
Message ID:
20110429135414.741ac7f8@pc09.procura.nl
That obviously doesn't work:

$ cat sr.pl
use strict;
use warnings;
use autodie;

my $data = "abcd" x 128;
my $rec  = "    " x 4;

open my $fh, "<", \$data;
sysread $fh, $rec, 16, 0;
print $rec, "\n";
$ perl sr.pl
Can't sysread($fh, '                ', '16', '0'): Bad file descriptor at sr.pl line 11
Exit 255
$

However, the docs are not (very) clear about that:

   sysread FILEHANDLE,SCALAR,LENGTH,OFFSET
   sysread FILEHANDLE,SCALAR,LENGTH

       Attempts to read LENGTH bytes 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 the perlio or stdio layers usually buffers data.
       Returns the number of bytes actually read, 0 at end of file, or
       undef if there was an error (in the latter case $! is also
       set).  SCALAR will be grown or shrunk so that the last byte
       actually read is the last byte of the scalar after the read.

       An OFFSET may be specified to place the read data at some place
       in the string other than the beginning.  A negative OFFSET
       specifies placement at that many characters counting backwards
       from the end of the string.  A positive OFFSET greater than the
       length of SCALAR results in the string being padded to the
       required size with "\0" bytes before the result of the read is
       appended.

       There is no syseof() function, which is ok, since eof() doesn't
       work very well on device files (like ttys) anyway.  Use
       sysread() and check for a return value for 0 to decide whether
       you're done.

       Note that if the filehandle has been marked as ":utf8" Unicode
       characters are read instead of bytes (the LENGTH, OFFSET, and
       the return value of sysread() are in Unicode characters).  The
       ":encoding(...)" layer implicitly introduces the ":utf8" layer.
       See "binmode", "open", and the "open" pragma, open.


My point being that is a module deep down that accepts file-handles and
uses unbuffered sysread on those, will get nasty surprises when the
filehandle is opened as above.

-- 
H.Merijn Brand  http://tux.nl      Perl Monger  http://amsterdam.pm.org/
using 5.00307 through 5.12 and porting perl5.13.x on HP-UX 10.20, 11.00,
11.11, 11.23 and 11.31, OpenSuSE 10.1, 11.0 .. 11.3 and AIX 5.2 and 5.3.
http://mirrors.develooper.com/hpux/           http://www.test-smoke.org/
http://qa.perl.org      http://www.goldmark.org/jeff/stupid-disclaimers/



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About