Determining the Number of Bytes to Read
Problem
You want to know how many bytes to read from a filehandle with
read
or sysread
.
Solution
Use the FIONREAD ioctl call:
$size = pack("L", 0); ioctl(FH, $FIONREAD, $size) or die "Couldn't call ioctl: $!\n"; $size = unpack("L", $size); # $size bytes can be read
Discussion
The Perl ioctl
function is a direct interface to
the operating system’s ioctl (2) system
call. If your system doesn’t have the FIONREAD request or the
ioctl (2) call, you can’t use this recipe.
FIONREAD and the other ioctl (2) requests are
numeric values normally found lurking in C include files.
Perl’s h2ph tool tries to convert C
include files to Perl code, which can be require
d.
FIONREAD ends up defined as a function in the
sys/ioctl.ph file:
require 'sys/ioctl.ph'; $size = pack("L", 0); ioctl(FH, FIONREAD(), $size) or die "Couldn't call ioctl: $!\n"; $size = unpack("L", $size);
If h2ph wasn’t installed or doesn’t work for you, you can manually grep the include files:
% grep FIONREAD /usr/include/*/*
/usr/include/asm/ioctls.h:#define FIONREAD 0x541B
Or write a small C program using the editor of champions:
% cat > fionread.c
#include <sys/ioctl.h>
main() {
printf("%#08x\n", FIONREAD);
}
^D
% cc -o fionread fionread
% ./fionread
0x4004667f
Then hard-code it, leaving porting as an exercise to your successor.
$FIONREAD = 0x4004667f; # XXX: opsys dependent $size = pack("L", 0); ioctl(FH, $FIONREAD, $size) or die "Couldn't call ioctl: $!\n"; $size = unpack("L", $size);
FIONREAD requires ...
Get Perl Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.