AnyEvent

 view release on metacpan or  search on metacpan

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

      @_               # check the number of elements directly
         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

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

      };
   };

=item aio_write $fh, $data, $cb->($length)

Tries to write the octets in C<$data> to the current position of C<$fh>
and passes the actual number of bytes written to the C<$cb>. Otherwise the
semantics are very much like those of Perl's C<syswrite>.

If less than C<length $data> octets have been written, C<$length> will
reflect that. If an error occurs, then nothing is passed to the callback.

Obviously, multiple C<aio_read>'s or C<aio_write>'s at the same time on file
handles sharing the underlying open file description results in undefined
behaviour, due to sharing of the current file offset (and less obviously
so, because OS X is not thread safe and corrupts data when you try).

=item aio_truncate $fh_or_path, $new_length, $cb->($success)

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

Example: truncate F</etc/passwd> to zero length - this only works on
systems that support C<truncate>, should not be tried out for obvious
reasons and debian will probably open yte another security bug about this
example.

   aio_truncate "/etc/passwd", sub {
      @_
         or return AE::log error => "/etc/passwd: $! - are you root enough?";
   };

=item aio_utime $fh_or_path, $atime, $mtime, $cb->($success)

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

The special case of both C<$atime> and C<$mtime> being C<undef> sets the
times to the current time, on systems that support this.

Example: try to touch F<file>.

   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.



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