IO-Async

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

        development and testing of the MSWin32 fixes

0.60    2013/09/19 14:26:22
        [CHANGES]
         * Updated for Future 0.16 - no longer needs 'return' argument for
           Future::Utils functions
         * $stream->connect() ought to default socktype => "stream"

        [BUGFIXES]
         * Fix unit tests to better handle INADDR_LOOPBACK not being 127.0.0.1
         * Skip-guard ->socket("inet6") unit tests on machines unable to
           socket(AF_INET6)
         * Remmeber to ->accept connections to testing socket in
           t/63handle-connect.t

0.59    CHANGES:
         * Allow IO::Async::Stream to define custom reader/writer methods
         * Support writeready-for-read and readready-for-write in Stream
         * Allow Stream->write() on_write and write_len args
         * Neatened and documented Future ->fail arguments and conventions
         * Added Stream on_writeable_{start,stop} events

Changes  view on Meta::CPAN

         * Print a deprecation warning on old loop classes with old timer
           support

0.54    CHANGES:
         * Use Future instead of CPS::Future
         * Created IO::Async::Future subclass
         * Initial support for Futures on Loops
         * Rewrite lots of internals to use Futures instead of MergePoints or
           other logic
         * Renamed all "task" to "future" in APIs
         * Allow packing of inet/inet6 address structures to omit the IP or
           port and presume passive or port 0
         * Removed $notifier->get_loop synonym
         * Make IO::Async::MergePoint throw a deprecation warning

0.53    CHANGES:
         * Added IO_ASYNC_WATCHDOG debugging support

        BUGFIXES:
         * Remember to return a task from Function->call even if it's queued
           (RT79248)

Changes  view on Meta::CPAN

         * Distribution now uses Test::Fatal rather than Test::Exception
         * Resolver is now a subclass of Function, not DetachedCode

        BUGFIXES:
         * More robust detection of Socket vs Socket::GetAddrInfo
         * Portability fix for ChildManager's FD_CLOEXEC flag

0.37    ADDITIONS:
         * Handle->close_read, ->close_write
         * Stream on_read_eof event
         * extract_addrinfo conveniences for 'inet', 'inet6' and 'unix'

        CHANGES:
         * Allow Process filehandles to set up plain pipes without read/write
           behaviour on the associated Stream
         * Renamed Loop->unpack_addrinfo to ->extract_addrinfo
         * Prepare for Socket::getaddrinfo() in core; prefer it to
           Socket::GetAddrInfo::getaddrinfo()

0.36    ADDITIONS:
         * IO::Async::Process

examples/echo-server.pl  view on Meta::CPAN

use IO::Async::Loop;
use IO::Async::Listener;

my $PORT = 12345;
my $FAMILY;
my $V6ONLY;

GetOptions(
   'port|p=i' => \$PORT,
   '4'        => sub { $FAMILY = "inet" },
   '6'        => sub { $FAMILY = "inet6" },
   'v6only=i' => \$V6ONLY,
) or exit 1;

my $loop = IO::Async::Loop->new;

my $listener = IO::Async::Listener->new(
   on_stream => sub {
      my $self = shift;
      my ( $stream ) = @_;

lib/IO/Async/OS.pm  view on Meta::CPAN


=back

=cut

=head2 getfamilybyname

   $family = IO::Async::OS->getfamilybyname( $name )

Return a protocol family value based on the given name. If C<$name> looks like
a number it will be returned as-is. The string values C<inet>, C<inet6> and
C<unix> will be converted to the appropriate C<AF_*> constant.

=cut

sub getfamilybyname
{
   shift;
   my ( $name ) = @_;

   return undef unless defined $name;

   return $name if $name =~ m/^\d+$/;

   return AF_INET    if $name eq "inet";
   return AF_INET6() if $name eq "inet6" and defined &AF_INET6;
   return AF_UNIX    if $name eq "unix";

   croak "Unrecognised socket family name '$name'";
}

=head2 getsocktypebyname

   $socktype = IO::Async::OS->getsocktypebyname( $name );

Return a socket type value based on the given name. If C<$name> looks like a

lib/IO/Async/OS.pm  view on Meta::CPAN

{
   my $self = shift;
   my ( $ai ) = @_;

   my $port = delete $ai->{port} || 0;
   my $ip   = delete $ai->{ip}   || "0.0.0.0";

   return pack_sockaddr_in( $port, inet_aton( $ip ) );
}

=item family => 'inet6'

Will pack an IP address and port number from keys called C<ip> and C<port>.
If C<ip> is missing it will be set to "::". If C<port> is missing it will be
set to 0. Optionally will also include values from C<scopeid> and C<flowinfo>
keys if provided.

This will only work if a C<pack_sockaddr_in6> function can be found in
C<Socket>

=cut

sub _extract_addrinfo_inet6
{
   my $self = shift;
   my ( $ai ) = @_;

   my $port     = delete $ai->{port}     || 0;
   my $ip       = delete $ai->{ip}       || "::";
   my $scopeid  = delete $ai->{scopeid}  || 0;
   my $flowinfo = delete $ai->{flowinfo} || 0;

   if( HAVE_SOCKADDR_IN6 ) {

lib/IO/Async/Resolver.pm  view on Meta::CPAN

aliased as simply C<getaddrinfo>.

The C<getaddrinfo_array> resolver behaves more like the C<Socket6> version of
the function. It takes hints in a flat list, and mangles the result of the
function, so that the returned value is more useful to the caller. It splits
up the list of 5-tuples into a list of ARRAY refs, where each referenced array
contains one of the tuples of 5 values.

As an extra convenience to the caller, both resolvers will also accept plain
string names for the C<family> argument, converting C<inet> and possibly
C<inet6> into the appropriate C<AF_*> value, and for the C<socktype> argument,
converting C<stream>, C<dgram> or C<raw> into the appropriate C<SOCK_*> value.

The C<getnameinfo> resolver returns its result in the same form as C<Socket>.

Because this module simply uses the system's C<getaddrinfo> resolver, it will
be fully IPv6-aware if the underlying platform's resolver is. This allows
programs to be fully IPv6-capable.

=cut

t/02os.t  view on Meta::CPAN


SKIP: {
   skip "No IO::Socket::IP", 2 unless eval { require IO::Socket::IP };

   my $S_inet = IO::Async::OS->socket( "inet", "stream" );
   isa_ok( $S_inet, [ "IO::Socket::IP" ], 'IO::Async::OS->socket("inet") isa IO::Socket::IP' );

   SKIP: {
      skip "No AF_INET6", 1 unless eval { socket( my $fh, AF_INET6, SOCK_STREAM, 0 ) };

      my $S_inet6 = IO::Async::OS->socket( "inet6", "stream" );
      isa_ok( $S_inet6, [ "IO::Socket::IP" ], 'IO::Async::OS->socket("inet6") isa IO::Socket::IP' );
   }
}

foreach my $family ( undef, "inet" ) {
   my ( $S1, $S2 ) = IO::Async::OS->socketpair( $family, "stream" )
      or die "Could not socketpair - $!";

   isa_ok( $S1, [ "IO::Socket" ], '$S1 isa IO::Socket' );
   isa_ok( $S2, [ "IO::Socket" ], '$S2 isa IO::Socket' );

t/02os.t  view on Meta::CPAN

      IO::Async::OS->make_addr_for_peer( AF_INET, pack_sockaddr_in( 567, inet_aton( "1.2.3.4" ) ) )
   );
   is( inet_ntoa( $host ), "1.2.3.4",   'make_addr_for_peer preserves AF_INET other host' );
}

SKIP: {
   my $sin6addr = eval { Socket::pack_sockaddr_in6( 1234, inet_pton( AF_INET6, "fe80::5678" ) ) };
   skip "No pack_sockaddr_in6", 1 unless defined $sin6addr;

   is( [ IO::Async::OS->extract_addrinfo( {
                  family   => "inet6",
                  socktype => "stream",
                  ip       => "fe80::5678",
                  port     => "1234",
                } ) ],
              [ AF_INET6, SOCK_STREAM, 0, $sin6addr ],
              'extract_addrinfo( HASH ) with inet6, ip+port' );

   # ->make_addr_for_peer should rewrite :: to ::1
   my ( $port, $host ) = unpack_sockaddr_in6(
      IO::Async::OS->make_addr_for_peer( AF_INET6, pack_sockaddr_in6( 567, inet_pton( AF_INET6, "::" ) ) )
   );
   is( $port,                        567,   'make_addr_for_peer preserves AF_INET6 port' );
   is( inet_ntop( AF_INET6, $host ), "::1", 'make_addr_for_peer rewrites IN6ADDR_ANY to _LOCALHOST' );

   ( undef, $host ) = unpack_sockaddr_in6(
      IO::Async::OS->make_addr_for_peer( AF_INET6, pack_sockaddr_in6( 567, inet_pton( AF_INET6, "fe80::1234" ) ) )



( run in 0.361 second using v1.01-cache-2.11-cpan-87723dcf8b7 )