X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FFileHandle.pm;h=eec9b61f31bbd296d85b9d4c8bf72b8d4a76bff5;hb=b099ddc068b2498767e6f04ac167d9633b895ec4;hp=c45f446667491d40647c47ae184a2bc4398f1c46;hpb=a0d0e21ea6ea90a22318550944fe6cb09ae10cda;p=p5sagit%2Fp5-mst-13.2.git
diff --git a/lib/FileHandle.pm b/lib/FileHandle.pm
index c45f446..eec9b61 100644
--- a/lib/FileHandle.pm
+++ b/lib/FileHandle.pm
@@ -1,14 +1,19 @@
package FileHandle;
-# Note that some additional FileHandle methods are defined in POSIX.pm.
+use 5.003_11;
+use strict;
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
-require 5.000;
-use English;
-use Exporter;
+$VERSION = "2.00";
+
+require IO::File;
+@ISA = qw(IO::File);
+
+@EXPORT = qw(_IOFBF _IOLBF _IONBF);
+
+@EXPORT_OK = qw(
+ pipe
-@ISA = qw(Exporter);
-@EXPORT = qw(
- print
autoflush
output_field_separator
output_record_separator
@@ -21,154 +26,237 @@ use Exporter;
format_top_name
format_line_break_characters
format_formfeed
- cacheout
+
+ print
+ printf
+ getline
+ getlines
);
-sub print {
- local($this) = shift;
- print $this @_;
-}
+#
+# Everything we're willing to export, we must first import.
+#
+import IO::Handle grep { !defined(&$_) } @EXPORT, @EXPORT_OK;
-sub autoflush {
- local($old) = select($_[0]);
- local($prev) = $OUTPUT_AUTOFLUSH;
- $OUTPUT_AUTOFLUSH = @_ > 1 ? $_[1] : 1;
- select($old);
- $prev;
-}
+#
+# Some people call "FileHandle::function", so all the functions
+# that were in the old FileHandle class must be imported, too.
+#
+{
+ no strict 'refs';
-sub output_field_separator {
- local($old) = select($_[0]);
- local($prev) = $OUTPUT_FIELD_SEPARATOR;
- $OUTPUT_FIELD_SEPARATOR = $_[1] if @_ > 1;
- select($old);
- $prev;
+ my %import = (
+ 'IO::Handle' =>
+ [qw(DESTROY new_from_fd fdopen close fileno getc ungetc gets
+ eof flush error clearerr setbuf setvbuf _open_mode_string)],
+ 'IO::Seekable' =>
+ [qw(seek tell getpos setpos)],
+ 'IO::File' =>
+ [qw(new new_tmpfile open)]
+ );
+ for my $pkg (keys %import) {
+ for my $func (@{$import{$pkg}}) {
+ my $c = *{"${pkg}::$func"}{CODE}
+ or die "${pkg}::$func missing";
+ *$func = $c;
+ }
+ }
}
-sub output_record_separator {
- local($old) = select($_[0]);
- local($prev) = $OUTPUT_RECORD_SEPARATOR;
- $OUTPUT_RECORD_SEPARATOR = $_[1] if @_ > 1;
- select($old);
- $prev;
-}
+#
+# Specialized importer for Fcntl magic.
+#
+sub import {
+ my $pkg = shift;
+ my $callpkg = caller;
+ require Exporter;
+ Exporter::export($pkg, $callpkg, @_);
-sub input_record_separator {
- local($old) = select($_[0]);
- local($prev) = $INPUT_RECORD_SEPARATOR;
- $INPUT_RECORD_SEPARATOR = $_[1] if @_ > 1;
- select($old);
- $prev;
+ #
+ # If the Fcntl extension is available,
+ # export its constants.
+ #
+ eval {
+ require Fcntl;
+ Exporter::export('Fcntl', $callpkg);
+ };
}
-sub input_line_number {
- local($old) = select($_[0]);
- local($prev) = $INPUT_LINE_NUMBER;
- $INPUT_LINE_NUMBER = $_[1] if @_ > 1;
- select($old);
- $prev;
-}
+################################################
+# This is the only exported function we define;
+# the rest come from other classes.
+#
-sub format_page_number {
- local($old) = select($_[0]);
- local($prev) = $FORMAT_PAGE_NUMBER;
- $FORMAT_PAGE_NUMBER = $_[1] if @_ > 1;
- select($old);
- $prev;
+sub pipe {
+ my $r = new IO::Handle;
+ my $w = new IO::Handle;
+ CORE::pipe($r, $w) or return undef;
+ ($r, $w);
}
-sub format_lines_per_page {
- local($old) = select($_[0]);
- local($prev) = $FORMAT_LINES_PER_PAGE;
- $FORMAT_LINES_PER_PAGE = $_[1] if @_ > 1;
- select($old);
- $prev;
-}
+# Rebless standard file handles
+bless *STDIN{IO}, "FileHandle" if ref *STDIN{IO} eq "IO::Handle";
+bless *STDOUT{IO}, "FileHandle" if ref *STDOUT{IO} eq "IO::Handle";
+bless *STDERR{IO}, "FileHandle" if ref *STDERR{IO} eq "IO::Handle";
-sub format_lines_left {
- local($old) = select($_[0]);
- local($prev) = $FORMAT_LINES_LEFT;
- $FORMAT_LINES_LEFT = $_[1] if @_ > 1;
- select($old);
- $prev;
-}
+1;
-sub format_name {
- local($old) = select($_[0]);
- local($prev) = $FORMAT_NAME;
- $FORMAT_NAME = $_[1] if @_ > 1;
- select($old);
- $prev;
-}
+__END__
-sub format_top_name {
- local($old) = select($_[0]);
- local($prev) = $FORMAT_TOP_NAME;
- $FORMAT_TOP_NAME = $_[1] if @_ > 1;
- select($old);
- $prev;
-}
+=head1 NAME
-sub format_line_break_characters {
- local($old) = select($_[0]);
- local($prev) = $FORMAT_LINE_BREAK_CHARACTERS;
- $FORMAT_LINE_BREAK_CHARACTERS = $_[1] if @_ > 1;
- select($old);
- $prev;
-}
+FileHandle - supply object methods for filehandles
-sub format_formfeed {
- local($old) = select($_[0]);
- local($prev) = $FORMAT_FORMFEED;
- $FORMAT_FORMFEED = $_[1] if @_ > 1;
- select($old);
- $prev;
-}
+=head1 SYNOPSIS
+ use FileHandle;
-# --- cacheout functions ---
-
-# Open in their package.
-
-sub cacheout_open {
- my $pack = caller(1);
- open(*{$pack . '::' . $_[0]}, $_[1]);
-}
+ $fh = new FileHandle;
+ if ($fh->open("< file")) {
+ print <$fh>;
+ $fh->close;
+ }
-sub cacheout_close {
- my $pack = caller(1);
- close(*{$pack . '::' . $_[0]});
-}
+ $fh = new FileHandle "> FOO";
+ if (defined $fh) {
+ print $fh "bar\n";
+ $fh->close;
+ }
-# But only this sub name is visible to them.
-
-sub cacheout {
- ($file) = @_;
- if (!$cacheout_maxopen){
- if (open(PARAM,'/usr/include/sys/param.h')) {
- local($.);
- while () {
- $cacheout_maxopen = $1 - 4
- if /^\s*#\s*define\s+NOFILE\s+(\d+)/;
- }
- close PARAM;
- }
- $cacheout_maxopen = 16 unless $cacheout_maxopen;
+ $fh = new FileHandle "file", "r";
+ if (defined $fh) {
+ print <$fh>;
+ undef $fh; # automatically closes the file
}
- if (!$isopen{$file}) {
- if (++$cacheout_numopen > $cacheout_maxopen) {
- local(@lru) = sort {$isopen{$a} <=> $isopen{$b};} keys(%isopen);
- splice(@lru, $cacheout_maxopen / 3);
- $cacheout_numopen -= @lru;
- for (@lru) { &cacheout_close($_); delete $isopen{$_}; }
- }
- &cacheout_open($file, ($saw{$file}++ ? '>>' : '>') . $file)
- || croak("Can't create $file: $!");
+
+ $fh = new FileHandle "file", O_WRONLY|O_APPEND;
+ if (defined $fh) {
+ print $fh "corge\n";
+ undef $fh; # automatically closes the file
}
- $isopen{$file} = ++$cacheout_seq;
-}
-$cacheout_seq = 0;
-$cacheout_numopen = 0;
+ $pos = $fh->getpos;
+ $fh->setpos($pos);
-1;
+ $fh->setvbuf($buffer_var, _IOLBF, 1024);
+
+ ($readfh, $writefh) = FileHandle::pipe;
+
+ autoflush STDOUT 1;
+
+=head1 DESCRIPTION
+
+NOTE: This class is now a front-end to the IO::* classes.
+
+C creates a C, which is a reference to a
+newly created symbol (see the C package). If it receives any
+parameters, they are passed to C; if the open fails,
+the C object is destroyed. Otherwise, it is returned to
+the caller.
+
+C creates a C like C does.
+It requires two parameters, which are passed to C;
+if the fdopen fails, the C object is destroyed.
+Otherwise, it is returned to the caller.
+
+C accepts one parameter or two. With one parameter,
+it is just a front end for the built-in C function. With two
+parameters, the first parameter is a filename that may include
+whitespace or other special characters, and the second parameter is
+the open mode, optionally followed by a file permission value.
+
+If C receives a Perl mode string (">", "+<", etc.)
+or a POSIX fopen() mode string ("w", "r+", etc.), it uses the basic
+Perl C operator.
+
+If C is given a numeric mode, it passes that mode
+and the optional permissions value to the Perl C operator.
+For convenience, C tries to import the O_XXX
+constants from the Fcntl module. If dynamic loading is not available,
+this may fail, but the rest of FileHandle will still work.
+
+C is like C except that its first parameter
+is not a filename but rather a file handle name, a FileHandle object,
+or a file descriptor number.
+
+If the C functions fgetpos() and fsetpos() are available, then
+C returns an opaque value that represents the
+current position of the FileHandle, and C uses
+that value to return to a previously visited position.
+
+If the C function setvbuf() is available, then C
+sets the buffering policy for the FileHandle. The calling sequence
+for the Perl function is the same as its C counterpart, including the
+macros C<_IOFBF>, C<_IOLBF>, and C<_IONBF>, except that the buffer
+parameter specifies a scalar variable to use as a buffer. WARNING: A
+variable used as a buffer by C must not be
+modified in any way until the FileHandle is closed or until
+C is called again, or memory corruption may
+result!
+
+See L for complete descriptions of each of the following
+supported C methods, which are just front ends for the
+corresponding built-in functions:
+
+ close
+ fileno
+ getc
+ gets
+ eof
+ clearerr
+ seek
+ tell
+
+See L for complete descriptions of each of the following
+supported C 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
+
+Furthermore, for doing normal I/O you might need these:
+
+=over
+
+=item $fh->print
+
+See L.
+
+=item $fh->printf
+
+See L.
+
+=item $fh->getline
+
+This works like <$fh> described in L
+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.
+
+=back
+
+There are many other functions available since FileHandle is descended
+from IO::File, IO::Seekable, and IO::Handle. Please see those
+respective pages for documentation on more functions.
+
+=head1 SEE ALSO
+
+The B extension,
+L,
+L.
+
+=cut