<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">package IO::Handle;

use 5.008_001;
use strict;
use Carp;
use Symbol;
use SelectSaver;
use IO ();	# Load the XS module

require Exporter;
our @ISA = qw(Exporter);

our $VERSION = "1.40";

our @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
    say
    getline
    getlines

    printflush
    flush

    SEEK_SET
    SEEK_CUR
    SEEK_END
    _IOFBF
    _IOLBF
    _IONBF
);

################################################
## Constructors, destructors.
##

sub new {
    my $class = ref($_[0]) || $_[0] || "IO::Handle";
    if (@_ != 1) {
	# Since perl will automatically require IO::File if needed, but
	# also initialises IO::File's @ISA as part of the core we must
	# ensure IO::File is loaded if IO::Handle is. This avoids effect-
	# ively "half-loading" IO::File.
	if ($] &gt; 5.013 &amp;&amp; $class eq 'IO::File' &amp;&amp; !$INC{"IO/File.pm"}) {
	    require IO::File;
	    shift;
	    return IO::File::-&gt;new(@_);
	}
	croak "usage: $class-&gt;new()";
    }
    my $io = gensym;
    bless $io, $class;
}

sub new_from_fd {
    my $class = ref($_[0]) || $_[0] || "IO::Handle";
    @_ == 3 or croak "usage: $class-&gt;new_from_fd(FD, MODE)";
    my $io = gensym;
    shift;
    IO::Handle::fdopen($io, @_)
	or return undef;
    bless $io, $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 =~ /^\+?(&lt;|&gt;&gt;?)$/
      or $mode =~ s/^r(\+?)$/$1&lt;/
      or $mode =~ s/^w(\+?)$/$1&gt;/
      or $mode =~ s/^a(\+?)$/$1&gt;&gt;/
      or croak "IO::Handle: bad open mode: $mode";
    $mode;
}

sub fdopen {
    @_ == 3 or croak 'usage: $io-&gt;fdopen(FD, MODE)';
    my ($io, $fd, $mode) = @_;
    local(*GLOB);

    if (ref($fd) &amp;&amp; "$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($io, _open_mode_string($mode) . '&amp;' . $fd)
	? $io : undef;
}

sub close {
    @_ == 1 or croak 'usage: $io-&gt;close()';
    my($io) = @_;

    close($io);
}

################################################
## Normal I/O functions.
##

# flock
# select

sub opened {
    @_ == 1 or croak 'usage: $io-&gt;opened()';
    defined fileno($_[0]);
}

sub fileno {
    @_ == 1 or croak 'usage: $io-&gt;fileno()';
    fileno($_[0]);
}

sub getc {
    @_ == 1 or croak 'usage: $io-&gt;getc()';
    getc($_[0]);
}

sub eof {
    @_ == 1 or croak 'usage: $io-&gt;eof()';
    eof($_[0]);
}

sub print {
    @_ or croak 'usage: $io-&gt;print(ARGS)';
    my $this = shift;
    print $this @_;
}

sub printf {
    @_ &gt;= 2 or croak 'usage: $io-&gt;printf(FMT,[ARGS])';
    my $this = shift;
    printf $this @_;
}

sub say {
    @_ or croak 'usage: $io-&gt;say(ARGS)';
    my $this = shift;
    local $\ = "\n";
    print $this @_;
}

# Special XS wrapper to make them inherit lexical hints from the caller.
_create_getline_subs( &lt;&lt;'END' ) or die $@;
sub getline {
    @_ == 1 or croak 'usage: $io-&gt;getline()';
    my $this = shift;
    return scalar &lt;$this&gt;;
} 

sub getlines {
    @_ == 1 or croak 'usage: $io-&gt;getlines()';
    wantarray or
	croak 'Can\'t call $io-&gt;getlines in a scalar context, use $io-&gt;getline';
    my $this = shift;
    return &lt;$this&gt;;
}
1; # return true for error checking
END

*gets = \&amp;getline;  # deprecated

sub truncate {
    @_ == 2 or croak 'usage: $io-&gt;truncate(LEN)';
    truncate($_[0], $_[1]);
}

sub read {
    @_ == 3 || @_ == 4 or croak 'usage: $io-&gt;read(BUF, LEN [, OFFSET])';
    read($_[0], $_[1], $_[2], $_[3] || 0);
}

sub sysread {
    @_ == 3 || @_ == 4 or croak 'usage: $io-&gt;sysread(BUF, LEN [, OFFSET])';
    sysread($_[0], $_[1], $_[2], $_[3] || 0);
}

sub write {
    @_ &gt;= 2 &amp;&amp; @_ &lt;= 4 or croak 'usage: $io-&gt;write(BUF [, LEN [, OFFSET]])';
    local($\) = "";
    $_[2] = length($_[1]) unless defined $_[2];
    print { $_[0] } substr($_[1], $_[3] || 0, $_[2]);
}

sub syswrite {
    @_ &gt;= 2 &amp;&amp; @_ &lt;= 4 or croak 'usage: $io-&gt;syswrite(BUF [, LEN [, OFFSET]])';
    if (defined($_[2])) {
	syswrite($_[0], $_[1], $_[2], $_[3] || 0);
    } else {
	syswrite($_[0], $_[1]);
    }
}

sub stat {
    @_ == 1 or croak 'usage: $io-&gt;stat()';
    stat($_[0]);
}

################################################
## State modification functions.
##

sub autoflush {
    my $old = SelectSaver-&gt;new(qualify($_[0], caller));
    my $prev = $|;
    $| = @_ &gt; 1 ? $_[1] : 1;
    $prev;
}

sub output_field_separator {
    carp "output_field_separator is not supported on a per-handle basis"
	if ref($_[0]);
    my $prev = $,;
    $, = $_[1] if @_ &gt; 1;
    $prev;
}

sub output_record_separator {
    carp "output_record_separator is not supported on a per-handle basis"
	if ref($_[0]);
    my $prev = $\;
    $\ = $_[1] if @_ &gt; 1;
    $prev;
}

sub input_record_separator {
    carp "input_record_separator is not supported on a per-handle basis"
	if ref($_[0]);
    my $prev = $/;
    $/ = $_[1] if @_ &gt; 1;
    $prev;
}

sub input_line_number {
    local $.;
    () = tell qualify($_[0], caller) if ref($_[0]);
    my $prev = $.;
    $. = $_[1] if @_ &gt; 1;
    $prev;
}

sub format_page_number {
    my $old;
    $old = SelectSaver-&gt;new(qualify($_[0], caller)) if ref($_[0]);
    my $prev = $%;
    $% = $_[1] if @_ &gt; 1;
    $prev;
}

sub format_lines_per_page {
    my $old;
    $old = SelectSaver-&gt;new(qualify($_[0], caller)) if ref($_[0]);
    my $prev = $=;
    $= = $_[1] if @_ &gt; 1;
    $prev;
}

sub format_lines_left {
    my $old;
    $old = SelectSaver-&gt;new(qualify($_[0], caller)) if ref($_[0]);
    my $prev = $-;
    $- = $_[1] if @_ &gt; 1;
    $prev;
}

sub format_name {
    my $old;
    $old = SelectSaver-&gt;new(qualify($_[0], caller)) if ref($_[0]);
    my $prev = $~;
    $~ = qualify($_[1], caller) if @_ &gt; 1;
    $prev;
}

sub format_top_name {
    my $old;
    $old = SelectSaver-&gt;new(qualify($_[0], caller)) if ref($_[0]);
    my $prev = $^;
    $^ = qualify($_[1], caller) if @_ &gt; 1;
    $prev;
}

sub format_line_break_characters {
    carp "format_line_break_characters is not supported on a per-handle basis"
	if ref($_[0]);
    my $prev = $:;
    $: = $_[1] if @_ &gt; 1;
    $prev;
}

sub format_formfeed {
    carp "format_formfeed is not supported on a per-handle basis"
	if ref($_[0]);
    my $prev = $^L;
    $^L = $_[1] if @_ &gt; 1;
    $prev;
}

sub formline {
    my $io = shift;
    my $picture = shift;
    local($^A) = $^A;
    local($\) = "";
    formline($picture, @_);
    print $io $^A;
}

sub format_write {
    @_ &lt; 3 || croak 'usage: $io-&gt;write( [FORMAT_NAME] )';
    if (@_ == 2) {
	my ($io, $fmt) = @_;
	my $oldfmt = $io-&gt;format_name(qualify($fmt,caller));
	CORE::write($io);
	$io-&gt;format_name($oldfmt);
    } else {
	CORE::write($_[0]);
    }
}

sub fcntl {
    @_ == 3 || croak 'usage: $io-&gt;fcntl( OP, VALUE );';
    my ($io, $op) = @_;
    return fcntl($io, $op, $_[2]);
}

sub ioctl {
    @_ == 3 || croak 'usage: $io-&gt;ioctl( OP, VALUE );';
    my ($io, $op) = @_;
    return ioctl($io, $op, $_[2]);
}

# this sub is for compatibility with older releases of IO that used
# a sub called constant to determine if a constant existed -- GMB
#
# The SEEK_* and _IO?BF constants were the only constants at that time
# any new code should just check defined(&amp;CONSTANT_NAME)

sub constant {
    no strict 'refs';
    my $name = shift;
    (($name =~ /^(SEEK_(SET|CUR|END)|_IO[FLN]BF)$/) &amp;&amp; defined &amp;{$name})
	? &amp;{$name}() : undef;
}

# so that flush.pl can be deprecated

sub printflush {
    my $io = shift;
    my $old;
    $old = SelectSaver-&gt;new(qualify($io, caller)) if ref($io);
    local $| = 1;
    if(ref($io)) {
        print $io @_;
    }
    else {
	print @_;
    }
}

1;
</pre></body></html>