in reply to Re^2: Don't understand why can't get 'size' assoc w/STDOUT
in thread Don't understand why can't get 'size' assoc w/STDOUT
Is that better? Does it help?=head2 ioctl ioctl R<FILEHANDLE>, R<FUNCTION>, R<SCALAR> X<ioctl function> X<input;using ioctl for> X<output;using ioctl for> This function implements the I<ioctl>(2) syscall which controls I/O. To get the correct function definitions, first you'll probably have to say: require "sys/ioctl.ph"; # perhaps /usr/local/lib/perl/sys/ioctl.ph If I<sys/ioctl.ph> doesn't exist or doesn't have the correct definitions, you'll have to roll your own based on your C header files such as I<sys/ioctl.h>. (The Perl distribution includes a script called I<h2ph> to help you do this, but running it is nontrivial.) R<SCALAR> will be read or written (or both) depending on the R<FUNCTION>--a pointer to the string value of R<SCALAR> will be passed as the third argument of the actual I<ioctl>(2) call. If R<SCALAR> has no string value but does have a numeric value, that value will be passed directly rather than a pointer to the string value. The C<pack> and C<unpack> functions are useful for manipulating the values of structures used by C<ioctl>. If the C<ioctl> needs to write data into your R<SCALAR>, it is up to you to ensure that the string is long enough to hold what needs to be written, often by initializing it to a dummy value of the correct size using C<pack>. The following example determines how many bytes are available for reading using the C<FIONREAD> C<ioctl>: X<buffer;pre-allocation> X<unpack function;example of use> X<ioctl function;example of use> require "sys/ioctl.ph"; # pre-allocate the right size buffer: $size = pack("L", 0); ioctl(FH, FIONREAD(), $size) || die "Couldn't call ioctl: $!\n"; $size = unpack("L", $size); Here is how to detect the current window sizeN<Or rather, how to get the window size associated with the STDOUT filehandle.> in rows and columns: X<window size; determining> require "sys/ioctl.ph"; # four unsigned shorts of the native size $template = "S!4"; # pre-allocate the right size buffer: my $ws = pack($template, ()); ioctl(STDOUT, TIOCGWINSZ(), $ws) || die "Couldn't call ioctl: $!"; ($rows, $cols, $xpix, $ypix) = unpack($template, $ws); If I<h2ph> wasn't installed or doesn't work for you, you can I<grep> the include files by hand or write a small C program to print out the value. You may also have to look at C code to determine the stucture template layout and size needed for your system. X<ioctl function;return value> X<fcntl function;return value> X<"0 but true"; special true value> The return value of C<ioctl> (and C<fcntl>) is as follows: =begin table picture =headrow =row =cell Syscall Returns =cell Perl Returns =bodyrows =row =cell C<-1> =cell C<undef> =row =cell C<0> =cell String "C<0 but true>" =row =cell Anything else =cell That number =end table Thus Perl returns true on success and false on failure, yet you can still easily determine the actual value returned by the operating system: $retval = ioctl(...) || -1; printf "ioctl actually returned %d\n", $retval; The special string "C<0 but true>" is exempt from warnings about improper numeric conversions from the B<-w> command-line option or the C<use warnings> pragma. Calls to C<ioctl> should not be considered portable. If, say, you're merely turning off echo once for the whole script, it's more portable to say: system "stty -echo"; # Works on most Unix boxen. Just because you I<can> do something in Perl doesn't mean you I<ought> to. For still better portability, you might look at the C<Term::ReadKey> module from CPAN. For almost anything you might want to use C<ioctl> on, there probably exists a CPAN module that already does that, and more portably, too, because they usually rope your system's C compiler into doing the heavy lifting for you.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^4: Don't understand why can't get 'size' assoc w/STDOUT
by perl-diddler (Chaplain) on Apr 19, 2011 at 01:41 UTC |