Perl Cd Bookshelf [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Perl Cd Bookshelf [Electronic resources] - نسخه متنی

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید

7.21. Determining the Number of Unread Bytes


7.21.1. Problem


You want to know how many unread bytes
are available for reading from a filehandle.

7.21.2. 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

Make sure the input filehandle is unbuffered (because you've used an
I/O layer like :unix on it), or use only
sysread.

7.21.3. 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

If you install Inline::C from CPAN, you can write a C subroutine to
obtain the constant for you:

use Inline C;
$FIONREAD = get_FIONREAD( );
# ...
_ _END_ _
_ _C_ _
#include <sys/ioctl.h>
int get_FIONREAD( ) {
return FIONREAD;
}

If all else fails, 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.c
% ./fionread
0x4004667f

Then hardcode 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 a filehandle connected to a
stream, which means sockets, pipes, and tty devices all work, but
regular files don't.

If this is too much system programming for you, try to think outside
the problem. Read from the filehandle in non-blocking mode (see
Recipe 7.20). Then, if you manage to read
something, that's how much was there waiting to be read. If you
couldn't read anything, you know there was nothing to be read. This
might get you in trouble with other users (or other processes) who
are using the same system, though— because it uses busy-wait
I/O, it's a drain on system resources.

7.21.4. See Also


Recipe 7.20; your system's
ioctl(2) manpage; the ioctl
function in perlfunc(1) and in Chapter 29 of
Programming Perl; the documentation for the
Inline::C module from CPAN

/ 875