AnyEvent

 view release on metacpan or  search on metacpan

lib/AnyEvent/IO.pm  view on Meta::CPAN

         or return AE::log error => "...";

=head2 CAVEAT: RELATIVE PATHS

When a path is specified, this path I<must be an absolute> path, unless
you make certain that nothing in your process calls C<chdir> or an
equivalent function while the request executes.

=head2 CAVEAT: OTHER SHARED STATE

Changing the C<umask> while any requests execute that create files (or
otherwise rely on the current umask) results in undefined behaviour -
likewise changing anything else that would change the outcome, such as
your effective user or group ID.

=head2 CALLBACKS MIGHT BE CALLED BEFORE FUNCTION RETURNS TO CALLER

Unlike other functions in the AnyEvent module family, these functions
I<may> call your callback instantly, before returning. This should not be
a real problem, as these functions never return anything useful.

=head2 BEHAVIOUR AT PROGRAM EXIT

Both L<AnyEvent::IO::Perl> and L<AnyEvent::IO::IOAIO> implementations
make sure that operations that have started will be finished on a clean
programs exit. That makes programs work that start some I/O operations and
then exit. For example this complete program:

   use AnyEvent::IO;

   aio_stat "path1", sub {
      aio_stat "path2", sub {
         warn "both stats done\n";
      };
   };

Starts a C<stat> operation and then exits by "falling off the end" of
the program. Nevertheless, I<both> C<stat> operations will be executed,
as AnyEvent::IO waits for all outstanding requests to finish and you can
start new requests from request callbacks.

In fact, since L<AnyEvent::IO::Perl> is currently synchronous, the
program will do both stats before falling off the end, but with
L<AnyEvent::IO::IOAIO>, the program first falls of the end, then the stats
are executed.

While not guaranteed, this behaviour will be present in future versions,
if reasonably possible (which is extreemly likely :).

=cut

package AnyEvent::IO;

use AnyEvent (); BEGIN { AnyEvent::common_sense }

use base "Exporter";

our @AIO_REQ = qw(
   aio_load aio_open aio_close aio_seek aio_read aio_write aio_truncate
   aio_utime aio_chown aio_chmod aio_stat aio_lstat
   aio_link aio_symlink aio_readlink aio_rename aio_unlink
   aio_mkdir aio_rmdir aio_readdir
);
*EXPORT = \@AIO_REQ;
our @FLAGS = qw(O_RDONLY O_WRONLY O_RDWR O_CREAT O_EXCL O_TRUNC O_APPEND);
*EXPORT_OK = \@FLAGS;
our %EXPORT_TAGS = (flags => \@FLAGS, aio => \@AIO_REQ);

our $MODEL;

if ($MODEL) {
   AE::log 7 => "Found preloaded IO model '$MODEL', using it.";
} else {
   if ($ENV{PERL_ANYEVENT_IO_MODEL} =~ /^([a-zA-Z0-9:]+)$/) {
      if (eval { require "AnyEvent/IO/$ENV{PERL_ANYEVENT_IO_MODEL}.pm" }) {
         AE::log 7 => "Loaded IO model '$MODEL' (forced by \$ENV{PERL_ANYEVENT_IO_MODEL}), using it.";
      } else {
         undef $MODEL;
         AE::log 4 => "Unable to load IO model '$ENV{PERL_ANYEVENT_IO_MODEL}' (from \$ENV{PERL_ANYEVENT_IO_MODEL}):\n$@";
      }
   }

   unless ($MODEL) {
      if (eval { require IO::AIO; require AnyEvent::AIO; require AnyEvent::IO::IOAIO }) {
         AE::log 7 => "Autoloaded IO model 'IOAIO', using it.";
      } else {
         require AnyEvent::IO::Perl;
         AE::log 7 => "Autoloaded IO model 'Perl', using it.";
      }
   }
}

=head1 GLOBAL VARIABLES AND FUNCTIONS

=over 4

=item $AnyEvent::IO::MODEL

Contains the package name of the backend I/O model in use - at the moment,
this is usually C<AnyEvent::IO::Perl> or C<AnyEvent::IO::IOAIO>.

=item aio_load $path, $cb->($data)

Tries to open C<$path> and read its contents into memory (obviously,
should only be used on files that are "small enough"), then passes them to
the callback as a string.

Example: load F</etc/hosts>.

   aio_load "/etc/hosts", sub {
      my ($hosts) = @_
         or return AE::log error => "/etc/hosts: $!";

      AE::log info => "/etc/hosts contains ", ($hosts =~ y/\n/), " lines\n";
   };

=item aio_open $path, $flags, $mode, $cb->($fh)

Tries to open the file specified by C<$path> with the O_XXX-flags
C<$flags> (from the Fcntl module, or see below) and the mode C<$mode> (a
good value is 0666 for C<O_CREAT>, and C<0> otherwise).

lib/AnyEvent/IO.pm  view on Meta::CPAN

   aio_utime "file", undef, undef, sub { };

=item aio_chown $fh_or_path, $uid, $gid, $cb->($success)

Calls C<chown> on the path or perl file handle and passes a true value to
the callback on success.

If C<$uid> or C<$gid> can be specified as C<undef>, in which case the
uid or gid of the file is not changed. This differs from Perl's C<chown>
built-in, which wants C<-1> for this.

Example: update the group of F<file> to 0 (root), but leave the owner alone.

   aio_chown "file", undef, 0, sub {
      @_
         or return AE::log error => "chown 'file': $!";
   };

=item aio_chmod $fh_or_path, $perms, $cb->($success)

Calls C<chmod> on the path or perl file handle and passes a true value to
the callback on success.

Example: change F<file> to be user/group/world-readable, but leave the other flags
alone.

   aio_stat "file", sub {
      @_
         or return AE::log error => "file: $!";

      aio_chmod "file", (stat _)[2] & 07777 | 00444, sub { };
   };

=item aio_stat $fh_or_path, $cb->($success)

=item aio_lstat $path, $cb->($success)

Calls C<stat> or C<lstat> on the path or perl file handle and passes a
true value to the callback on success.

The stat data will be available by C<stat>'ing the C<_> file handle
(e.g. C<-x _>, C<stat _> and so on).

Example: see if we can find the number of subdirectories of F</etc>.

   aio_stat "/etc", sub {
      @_
         or return AE::log error => "/etc: $!";

      (stat _)[3] >= 2
         or return AE::log warn => "/etc has low link count - non-POSIX filesystem?";

      print "/etc has ", (stat _)[3] - 2, " subdirectories.\n";
   };

=item aio_link $oldpath, $newpath, $cb->($success)

Calls C<link> on the paths and passes a true value to the callback on
success.

Example: link "F<file> to F<file.bak>, then rename F<file.new> over F<file>,
to atomically replace it.

   aio_link "file", "file.bak", sub {
      @_
         or return AE::log error => "file: $!";

      aio_rename "file.new", "file", sub {
         @_
            or return AE::log error => "file.new: $!";

         print "file atomically replaced by file.new, backup file.bak\n";
      };
   };

=item aio_symlink $oldpath, $newpath, $cb->($success)

Calls C<symlink> on the paths and passes a true value to the callback on
success.

Example: create a symlink "F<slink> containing "random data".

   aio_symlink "random data", "slink", sub {
      @_
         or return AE::log error => "slink: $!";
   };

=item aio_readlink $path, $cb->($target)

Calls C<readlink> on the paths and passes the link target string to the
callback.

Example: read the symlink called Fyslink> and verify that it contains "random data".

  aio_readlink "slink", sub {
     my ($target) = @_
        or return AE::log error => "slink: $!";

     $target eq "random data"
        or AE::log critical => "omg, the world will end!";
  };

=item aio_rename $oldpath, $newpath, $cb->($success)

Calls C<rename> on the paths and passes a true value to the callback on
success.

See C<aio_link> for an example.

=item aio_unlink $path, $cb->($success)

Tries to unlink the object at C<$path> and passes a true value to the
callback on success.

Example: try to delete the file F<tmpfile.dat~>.

   aio_unlink "tmpfile.dat~", sub { };

=item aio_mkdir $path, $perms, $cb->($success)

Calls C<mkdir> on the path with the given permissions C<$perms> (when in
doubt, C<0777> is a good value) and passes a true value to the callback on
success.

Example: try to create the directory F<subdir> and leave it to whoeveer
comes after us to check whether it worked.

   aio_mkdir "subdir", 0777, sub { };

=item aio_rmdir $path, $cb->($success)

Tries to remove the directory at C<$path> and passes a true value to the
callback on success.

Example: try to remove the directory F<subdir> and don't give a damn if
that fails.

   aio_rmdir "subdir", sub { };

=item aio_readdir $path, $cb->(\@names)

Reads all filenames from the directory specified by C<$path> and passes
them to the callback, as an array reference with the names (without a path
prefix). The F<.> and F<..> names will be filtered out first.

The ordering of the file names is undefined - backends that are capable
of it (e.g. L<IO::AIO>) will return the ordering that most likely is
fastest to C<stat> through, and furthermore put entries that likely are
directories first in the array.

If you need best performance in recursive directory traversal or when
looking at really big directories, you are advised to use L<IO::AIO>
directly, specifically the C<aio_readdirx> and C<aio_scandir> functions,
which have more options to tune performance.

Example: recursively scan a directory hierarchy, silently skip diretcories
we couldn't read and print all others.

   sub scan($); # visibility-in-next statement is not so useful these days
   sub scan($) {
      my ($path) = @_;

      aio_readdir $path, sub {
         my ($names) = @_
            or return;



( run in 1.057 second using v1.01-cache-2.11-cpan-39bf76dae61 )