home *** CD-ROM | disk | FTP | other *** search
-
- package IO::Handle;
-
- =head1 NAME
-
- IO::Handle - supply object methods for I/O handles
-
- =head1 SYNOPSIS
-
- use IO::Handle;
-
- $fh = new IO::Handle;
- if ($fh->fdopen(fileno(STDIN),"r")) {
- print $fh->getline;
- $fh->close;
- }
-
- $fh = new IO::Handle;
- if ($fh->fdopen(fileno(STDOUT),"w")) {
- $fh->print("Some text\n");
- }
-
- $fh->setvbuf($buffer_var, _IOLBF, 1024);
-
- undef $fh; # automatically closes the file if it's open
-
- autoflush STDOUT 1;
-
- =head1 DESCRIPTION
-
- C<IO::Handle> is the base class for all other IO handle classes. It is
- not intended that objects of C<IO::Handle> would be created directly,
- but instead C<IO::Handle> is inherited from by several other classes
- in the IO hierarchy.
-
- If you are reading this documentation, looking for a replacement for
- the C<FileHandle> package, then I suggest you read the documentation
- for C<IO::File>
-
- A C<IO::Handle> object is a reference to a symbol (see the C<Symbol> package)
-
- =head1 CONSTRUCTOR
-
- =over 4
-
- =item new ()
-
- Creates a new C<IO::Handle> object.
-
- =item new_from_fd ( FD, MODE )
-
- Creates a C<IO::Handle> like C<new> does.
- It requires two parameters, which are passed to the method C<fdopen>;
- if the fdopen fails, the object is destroyed. Otherwise, it is returned
- to the caller.
-
- =back
-
- =head1 METHODS
-
- See L<perlfunc> for complete descriptions of each of the following
- supported C<IO::Handle> methods, which are just front ends for the
- corresponding built-in functions:
-
- close
- fileno
- getc
- eof
- read
- truncate
- stat
- print
- printf
- sysread
- syswrite
-
- See L<perlvar> for complete descriptions of each of the following
- supported C<IO::Handle> methods:
-
- autoflush
- output_field_separator
- output_record_separator
- input_record_separator
- input_line_number
- format_page_number
- format_lines_per_page
- format_lines_left
- format_name
- format_top_name
- format_line_break_characters
- format_formfeed
- format_write
-
- Furthermore, for doing normal I/O you might need these:
-
- =over
-
- =item $fh->fdopen ( FD, MODE )
-
- C<fdopen> is like an ordinary C<open> except that its first parameter
- is not a filename but rather a file handle name, a IO::Handle object,
- or a file descriptor number.
-
- =item $fh->opened
-
- Returns true if the object is currently a valid file descriptor.
-
- =item $fh->getline
-
- This works like <$fh> described in L<perlop/"I/O Operators">
- except that it's more readable and can be safely called in an
- array context but still returns just one line.
-
- =item $fh->getlines
-
- This works like <$fh> when called in an array context to
- read all the remaining lines in a file, except that it's more readable.
- It will also croak() if accidentally called in a scalar context.
-
- =item $fh->ungetc ( ORD )
-
- Pushes a character with the given ordinal value back onto the given
- handle's input stream.
-
- =item $fh->write ( BUF, LEN [, OFFSET }\] )
-
- This C<write> is like C<write> found in C, that is it is the
- opposite of read. The wrapper for the perl C<write> function is
- called C<format_write>.
-
- =item $fh->flush
-
- Flush the given handle's buffer.
-
- =item $fh->error
-
- Returns a true value if the given handle has experienced any errors
- since it was opened or since the last call to C<clearerr>.
-
- =item $fh->clearerr
-
- Clear the given handle's error indicator.
-
- =back
-
- If the C functions setbuf() and/or setvbuf() are available, then
- C<IO::Handle::setbuf> and C<IO::Handle::setvbuf> set the buffering
- policy for an IO::Handle. The calling sequences for the Perl functions
- are the same as their C counterparts--including the constants C<_IOFBF>,
- C<_IOLBF>, and C<_IONBF> for setvbuf()--except that the buffer parameter
- specifies a scalar variable to use as a buffer. WARNING: A variable
- used as a buffer by C<setbuf> or C<setvbuf> must not be modified in any
- way until the IO::Handle is closed or C<setbuf> or C<setvbuf> is called
- again, or memory corruption may result!
-
- Lastly, there is a special method for working under B<-T> and setuid/gid
- scripts:
-
- =over
-
- =item $fh->untaint
-
- Marks the object as taint-clean, and as such data read from it will also
- be considered taint-clean. Note that this is a very trusting action to
- take, and appropriate consideration for the data source and potential
- vulnerability should be kept in mind.
-
- =back
-
- =head1 NOTE
-
- A C<IO::Handle> object is a GLOB reference. Some modules that
- inherit from C<IO::Handle> may want to keep object related variables
- in the hash table part of the GLOB. In an attempt to prevent modules
- trampling on each other I propose the that any such module should prefix
- its variables with its own name separated by _'s. For example the IO::Socket
- module keeps a C<timeout> variable in 'io_socket_timeout'.
-
- =head1 SEE ALSO
-
- L<perlfunc>,
- L<perlop/"I/O Operators">,
- L<IO::File>
-
- =head1 BUGS
-
- Due to backwards compatibility, all filehandles resemble objects
- of class C<IO::Handle>, or actually classes derived from that class.
- They actually aren't. Which means you can't derive your own
- class from C<IO::Handle> and inherit those methods.
-
- =head1 HISTORY
-
- Derived from FileHandle.pm by Graham Barr E<lt>F<bodg@tiuk.ti.com>E<gt>
-
- =cut
-
- require 5.000;
- use strict;
- use vars qw($VERSION $XS_VERSION @EXPORT_OK $AUTOLOAD @ISA);
- use Carp;
- use Symbol;
- use SelectSaver;
-
- require Exporter;
- @ISA = qw(Exporter);
-
- $VERSION = "1.1504";
- $XS_VERSION = "1.15";
-
- @EXPORT_OK = qw(
- autoflush
- output_field_separator
- output_record_separator
- input_record_separator
- input_line_number
- format_page_number
- format_lines_per_page
- format_lines_left
- format_name
- format_top_name
- format_line_break_characters
- format_formfeed
- format_write
-
- print
- printf
- getline
- getlines
-
- SEEK_SET
- SEEK_CUR
- SEEK_END
- _IOFBF
- _IOLBF
- _IONBF
- );
-
-
- ################################################
- ## Interaction with the XS.
- ##
-
- require DynaLoader;
- @IO::ISA = qw(DynaLoader);
- bootstrap IO $XS_VERSION;
-
- sub AUTOLOAD {
- if ($AUTOLOAD =~ /::(_?[a-z])/) {
- $AutoLoader::AUTOLOAD = $AUTOLOAD;
- goto &AutoLoader::AUTOLOAD
- }
- my $constname = $AUTOLOAD;
- $constname =~ s/.*:://;
- my $val = constant($constname);
- defined $val or croak "$constname is not a valid IO::Handle macro";
- no strict 'refs';
- *$AUTOLOAD = sub { $val };
- goto &$AUTOLOAD;
- }
-
-
- ################################################
- ## Constructors, destructors.
- ##
-
- sub new {
- my $class = ref($_[0]) || $_[0] || "IO::Handle";
- @_ == 1 or croak "usage: new $class";
- my $fh = gensym;
- bless $fh, $class;
- }
-
- sub new_from_fd {
- my $class = ref($_[0]) || $_[0] || "IO::Handle";
- @_ == 3 or croak "usage: new_from_fd $class FD, MODE";
- my $fh = gensym;
- shift;
- IO::Handle::fdopen($fh, @_)
- or return undef;
- bless $fh, $class;
- }
-
- #
- # There is no need for DESTROY to do anything, because when the
- # last reference to an IO object is gone, Perl automatically
- # closes its associated files (if any). However, to avoid any
- # attempts to autoload DESTROY, we here define it to do nothing.
- #
- sub DESTROY {}
-
-
- ################################################
- ## Open and close.
- ##
-
- sub _open_mode_string {
- my ($mode) = @_;
- $mode =~ /^\+?(<|>>?)$/
- or $mode =~ s/^r(\+?)$/$1</
- or $mode =~ s/^w(\+?)$/$1>/
- or $mode =~ s/^a(\+?)$/$1>>/
- or croak "IO::Handle: bad open mode: $mode";
- $mode;
- }
-
- sub fdopen {
- @_ == 3 or croak 'usage: $fh->fdopen(FD, MODE)';
- my ($fh, $fd, $mode) = @_;
- local(*GLOB);
-
- if (ref($fd) && "".$fd =~ /GLOB\(/o) {
- # It's a glob reference; Alias it as we cannot get name of anon GLOBs
- my $n = qualify(*GLOB);
- *GLOB = *{*$fd};
- $fd = $n;
- } elsif ($fd =~ m#^\d+$#) {
- # It's an FD number; prefix with "=".
- $fd = "=$fd";
- }
-
- open($fh, _open_mode_string($mode) . '&' . $fd)
- ? $fh : undef;
- }
-
- sub close {
- @_ == 1 or croak 'usage: $fh->close()';
- my($fh) = @_;
-
- close($fh);
- }
-
- ################################################
- ## Normal I/O functions.
- ##
-
- # flock
- # select
-
- sub opened {
- @_ == 1 or croak 'usage: $fh->opened()';
- defined fileno($_[0]);
- }
-
- sub fileno {
- @_ == 1 or croak 'usage: $fh->fileno()';
- fileno($_[0]);
- }
-
- sub getc {
- @_ == 1 or croak 'usage: $fh->getc()';
- getc($_[0]);
- }
-
- sub eof {
- @_ == 1 or croak 'usage: $fh->eof()';
- eof($_[0]);
- }
-
- sub print {
- @_ or croak 'usage: $fh->print([ARGS])';
- my $this = shift;
- print $this @_;
- }
-
- sub printf {
- @_ >= 2 or croak 'usage: $fh->printf(FMT,[ARGS])';
- my $this = shift;
- printf $this @_;
- }
-
- sub getline {
- @_ == 1 or croak 'usage: $fh->getline';
- my $this = shift;
- return scalar <$this>;
- }
-
- *gets = \&getline; # deprecated
-
- sub getlines {
- @_ == 1 or croak 'usage: $fh->getline()';
- wantarray or
- croak 'Can\'t call $fh->getlines in a scalar context, use $fh->getline';
- my $this = shift;
- return <$this>;
- }
-
- sub truncate {
- @_ == 2 or croak 'usage: $fh->truncate(LEN)';
- truncate($_[0], $_[1]);
- }
-
- sub read {
- @_ == 3 || @_ == 4 or croak '$fh->read(BUF, LEN [, OFFSET])';
- read($_[0], $_[1], $_[2], $_[3] || 0);
- }
-
- sub sysread {
- @_ == 3 || @_ == 4 or croak '$fh->sysread(BUF, LEN [, OFFSET])';
- sysread($_[0], $_[1], $_[2], $_[3] || 0);
- }
-
- sub write {
- @_ == 3 || @_ == 4 or croak '$fh->write(BUF, LEN [, OFFSET])';
- local($\) = "";
- print { $_[0] } substr($_[1], $_[3] || 0, $_[2]);
- }
-
- sub syswrite {
- @_ == 3 || @_ == 4 or croak '$fh->syswrite(BUF, LEN [, OFFSET])';
- syswrite($_[0], $_[1], $_[2], $_[3] || 0);
- }
-
- sub stat {
- @_ == 1 or croak 'usage: $fh->stat()';
- stat($_[0]);
- }
-
- ################################################
- ## State modification functions.
- ##
-
- sub autoflush {
- my $old = new SelectSaver qualify($_[0], caller);
- my $prev = $|;
- $| = @_ > 1 ? $_[1] : 1;
- $prev;
- }
-
- sub output_field_separator {
- my $old = new SelectSaver qualify($_[0], caller);
- my $prev = $,;
- $, = $_[1] if @_ > 1;
- $prev;
- }
-
- sub output_record_separator {
- my $old = new SelectSaver qualify($_[0], caller);
- my $prev = $\;
- $\ = $_[1] if @_ > 1;
- $prev;
- }
-
- sub input_record_separator {
- my $old = new SelectSaver qualify($_[0], caller);
- my $prev = $/;
- $/ = $_[1] if @_ > 1;
- $prev;
- }
-
- sub input_line_number {
- my $old = new SelectSaver qualify($_[0], caller);
- my $prev = $.;
- $. = $_[1] if @_ > 1;
- $prev;
- }
-
- sub format_page_number {
- my $old = new SelectSaver qualify($_[0], caller);
- my $prev = $%;
- $% = $_[1] if @_ > 1;
- $prev;
- }
-
- sub format_lines_per_page {
- my $old = new SelectSaver qualify($_[0], caller);
- my $prev = $=;
- $= = $_[1] if @_ > 1;
- $prev;
- }
-
- sub format_lines_left {
- my $old = new SelectSaver qualify($_[0], caller);
- my $prev = $-;
- $- = $_[1] if @_ > 1;
- $prev;
- }
-
- sub format_name {
- my $old = new SelectSaver qualify($_[0], caller);
- my $prev = $~;
- $~ = qualify($_[1], caller) if @_ > 1;
- $prev;
- }
-
- sub format_top_name {
- my $old = new SelectSaver qualify($_[0], caller);
- my $prev = $^;
- $^ = qualify($_[1], caller) if @_ > 1;
- $prev;
- }
-
- sub format_line_break_characters {
- my $old = new SelectSaver qualify($_[0], caller);
- my $prev = $:;
- $: = $_[1] if @_ > 1;
- $prev;
- }
-
- sub format_formfeed {
- my $old = new SelectSaver qualify($_[0], caller);
- my $prev = $^L;
- $^L = $_[1] if @_ > 1;
- $prev;
- }
-
- sub formline {
- my $fh = shift;
- my $picture = shift;
- local($^A) = $^A;
- local($\) = "";
- formline($picture, @_);
- print $fh $^A;
- }
-
- sub format_write {
- @_ < 3 || croak 'usage: $fh->write( [FORMAT_NAME] )';
- if (@_ == 2) {
- my ($fh, $fmt) = @_;
- my $oldfmt = $fh->format_name($fmt);
- write($fh);
- $fh->format_name($oldfmt);
- } else {
- write($_[0]);
- }
- }
-
- sub fcntl {
- @_ == 3 || croak 'usage: $fh->fcntl( OP, VALUE );';
- my ($fh, $op, $val) = @_;
- my $r = fcntl($fh, $op, $val);
- defined $r && $r eq "0 but true" ? 0 : $r;
- }
-
- sub ioctl {
- @_ == 3 || croak 'usage: $fh->ioctl( OP, VALUE );';
- my ($fh, $op, $val) = @_;
- my $r = ioctl($fh, $op, $val);
- defined $r && $r eq "0 but true" ? 0 : $r;
- }
-
- 1;
-