package File::fgets; use strict; use warnings; use version; our $VERSION = qv("v0.0.4"); use XSLoader; XSLoader::load __PACKAGE__, $VERSION; use base qw(Exporter); our @EXPORT = qw(fgets); use Carp; =head1 NAME File::fgets - Read either one line or X characters from a file =head1 SYNOPSIS use File::fgets; open my $fh, $file; # Read either one line or the first 10 characters, which ever comes first my $line = fgets($fh, 10); =head1 DESCRIPTION An implementation of the C fgets() function. =head3 fgets my $string = fgets($fh, $limit); Reads either one line or at most $limit bytes from the $fh. Returns undef at end of file. NOTE: unlike C's fgets, this will read $limit characters not $limit - 1. Perl doesn't have to leave room for a null byte. =cut sub fgets { my($fh, $limit) = @_; croak "Invalid filehandle supplied to fgets()" unless defined $fh; croak "No limit supplied to fgets()" unless defined $limit; croak "fgets() on closed filehandle" if do { tell($fh) == -1; }; return if eof $fh; # fgets() is often buggy, returning garbage or silently reading # one character. Let's just not get it involved. return "" if $limit == 0; my $fd = eval { fileno($fh) }; my $has_fd = $fd && $fd != -1; return $has_fd ? xs_fgets($fh, $limit) : perl_fgets($fh, $limit); } # For dealing with filehandles that aren't real file descriptors sub perl_fgets { my($fh, $limit) = @_; my $char; # avoid reallocating it every iteration my $str = ''; for(1..$limit) { $char = getc $fh; last unless defined $char; $str .= $char; last if $char eq "\n"; } return $str; } 1; =head1 EXAMPLE The following example demonstrates using fgets() to read in at most 5 characters at a time. use File::fgets; open my $write_fh, ">", $file; print $write_fh <schwern@pobox.comE. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See F Send bugs, feedback, ideas and suggestions via L or Ebugs-File-fgets@rt.cpan.orgE The latest version of this software can be found at L =head1 SEE ALSO L =cut