package File::Send;
{
$File::Send::VERSION = '0.001';
}
use strict;
use warnings;
use Carp;
use Sub::Exporter -setup => { exports => ['sendfile'], groups => { default => ['sendfile'] } };
use Fcntl 'SEEK_CUR';
sub _systell {
return sysseek $_[0], 0, SEEK_CUR;
}
my $backend = eval { require Sys::Sendfile; 'Sys::Sendfile' } || eval { require File::Map; 'File::Map' } || '';
if ($backend eq 'Sys::Sendfile') {
*sendfile = sub {
my $ret = Sys::Sendfile::sendfile(@_);
croak "Couldn't sendfile: $!" if not defined $ret;
return $ret;
}
}
elsif ($backend eq 'File::Map') {
*sendfile = sub {
my ($out, $in, $length) = @_;
my $offset = _systell $in;
$length ||= (-s $in) - $offset;
my $retval = 0;
File::Map::map_handle(my $map, $in, '<', $offset, $length);
while ($length) {
my $ret = syswrite $out, $map;
defined $retval ? return $retval : croak "Couldn't sendfile: $!" if not defined $ret;
$retval += $ret;
$offset += $ret;
$length -= $ret;
}
return $retval;
}
}
else {
croak 'No backend for File::Send installed';
}
1;
=pod
=head1 NAME
File::Send - Sending files over a socket efficiently and cross-platform
=head1 VERSION
version 0.001
=head1 SYNOPSIS
=head1 DESCRIPTION
File::Send provides access to your operating system's C<sendfile> facility, or if that is not available uses L<File::Map> and C<syswrite> to achieve a similarly efficient io function. It allows you to efficiently transfer data from one filehandle to another. Typically the source is a file on disk and the sink is a socket, and some operating systems may not even support other usage.
=head1 FUNCTIONS
=head2 sendfile $out, $in, $count
This function sends up to C<$count> B<bytes> from C<$in> to C<$out>. If $count isn't given, it will send all remaining bytes in $in. C<$in> and C<$out> can be a bareword, constant, scalar expression, typeglob, or a reference to a typeglob. It returns the number of bytes actually sent. On error it throws an exception describing the problem. This function is exported by default.
=encoding utf8
=head1 FUNCTIONS
=head1 AUTHOR
Leon Timmermans <leont@cpan.org>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2011 by Leon Timmermans.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut
__END__
#ABSTRACT: Sending files over a socket efficiently and cross-platform