+=head2 C<ev_stat> - did the file attributes just change?
+
+This watches a filesystem path for attribute changes. That is, it calls
+C<stat> regularly (or when the OS says it changed) and sees if it changed
+compared to the last time, invoking the callback if it did.
+
+The path does not need to exist: changing from "path exists" to "path does
+not exist" is a status change like any other. The condition "path does
+not exist" is signified by the C<st_nlink> field being zero (which is
+otherwise always forced to be at least one) and all the other fields of
+the stat buffer having unspecified contents.
+
+The path I<should> be absolute and I<must not> end in a slash. If it is
+relative and your working directory changes, the behaviour is undefined.
+
+Since there is no standard to do this, the portable implementation simply
+calls C<stat (2)> regularly on the path to see if it changed somehow. You
+can specify a recommended polling interval for this case. If you specify
+a polling interval of C<0> (highly recommended!) then a I<suitable,
+unspecified default> value will be used (which you can expect to be around
+five seconds, although this might change dynamically). Libev will also
+impose a minimum interval which is currently around C<0.1>, but thats
+usually overkill.
+
+This watcher type is not meant for massive numbers of stat watchers,
+as even with OS-supported change notifications, this can be
+resource-intensive.
+
+At the time of this writing, only the Linux inotify interface is
+implemented (implementing kqueue support is left as an exercise for the
+reader). Inotify will be used to give hints only and should not change the
+semantics of C<ev_stat> watchers, which means that libev sometimes needs
+to fall back to regular polling again even with inotify, but changes are
+usually detected immediately, and if the file exists there will be no
+polling.
+
+=head3 Inotify
+
+When C<inotify (7)> support has been compiled into libev (generally only
+available on Linux) and present at runtime, it will be used to speed up
+change detection where possible. The inotify descriptor will be created lazily
+when the first C<ev_stat> watcher is being started.
+
+Inotify presense does not change the semantics of C<ev_stat> watchers
+except that changes might be detected earlier, and in some cases, to avoid
+making regular C<stat> calls. Even in the presense of inotify support
+there are many cases where libev has to resort to regular C<stat> polling.
+
+(There is no support for kqueue, as apparently it cannot be used to
+implement this functionality, due to the requirement of having a file
+descriptor open on the object at all times).
+
+=head3 The special problem of stat time resolution
+
+The C<stat ()> syscall only supports full-second resolution portably, and
+even on systems where the resolution is higher, many filesystems still
+only support whole seconds.
+
+That means that, if the time is the only thing that changes, you might
+miss updates: on the first update, C<ev_stat> detects a change and calls
+your callback, which does something. When there is another update within
+the same second, C<ev_stat> will be unable to detect it.
+
+The solution to this is to delay acting on a change for a second (or till
+the next second boundary), using a roughly one-second delay C<ev_timer>
+(C<ev_timer_set (w, 0., 1.01); ev_timer_again (loop, w)>). The C<.01>
+is added to work around small timing inconsistencies of some operating
+systems.
+
+=head3 Watcher-Specific Functions and Data Members
+
+=over 4
+
+=item ev_stat_init (ev_stat *, callback, const char *path, ev_tstamp interval)
+
+=item ev_stat_set (ev_stat *, const char *path, ev_tstamp interval)
+
+Configures the watcher to wait for status changes of the given
+C<path>. The C<interval> is a hint on how quickly a change is expected to
+be detected and should normally be specified as C<0> to let libev choose
+a suitable value. The memory pointed to by C<path> must point to the same
+path for as long as the watcher is active.
+
+The callback will be receive C<EV_STAT> when a change was detected,
+relative to the attributes at the time the watcher was started (or the
+last change was detected).
+
+=item ev_stat_stat (ev_stat *)
+
+Updates the stat buffer immediately with new values. If you change the
+watched path in your callback, you could call this fucntion to avoid
+detecting this change (while introducing a race condition). Can also be
+useful simply to find out the new values.
+
+=item ev_statdata attr [read-only]
+
+The most-recently detected attributes of the file. Although the type is of
+C<ev_statdata>, this is usually the (or one of the) C<struct stat> types
+suitable for your system. If the C<st_nlink> member is C<0>, then there
+was some error while C<stat>ing the file.
+
+=item ev_statdata prev [read-only]
+
+The previous attributes of the file. The callback gets invoked whenever
+C<prev> != C<attr>.
+
+=item ev_tstamp interval [read-only]
+
+The specified interval.
+
+=item const char *path [read-only]
+
+The filesystem path that is being watched.
+
+=back
+
+=head3 Examples
+
+Example: Watch C</etc/passwd> for attribute changes.
+
+ static void
+ passwd_cb (struct ev_loop *loop, ev_stat *w, int revents)
+ {
+ /* /etc/passwd changed in some way */
+ if (w->attr.st_nlink)
+ {
+ printf ("passwd current size %ld\n", (long)w->attr.st_size);
+ printf ("passwd current atime %ld\n", (long)w->attr.st_mtime);
+ printf ("passwd current mtime %ld\n", (long)w->attr.st_mtime);
+ }
+ else
+ /* you shalt not abuse printf for puts */
+ puts ("wow, /etc/passwd is not there, expect problems. "
+ "if this is windows, they already arrived\n");
+ }
+
+ ...
+ ev_stat passwd;
+
+ ev_stat_init (&passwd, passwd_cb, "/etc/passwd", 0.);
+ ev_stat_start (loop, &passwd);
+
+Example: Like above, but additionally use a one-second delay so we do not
+miss updates (however, frequent updates will delay processing, too, so
+one might do the work both on C<ev_stat> callback invocation I<and> on
+C<ev_timer> callback invocation).
+
+ static ev_stat passwd;
+ static ev_timer timer;
+
+ static void
+ timer_cb (EV_P_ ev_timer *w, int revents)
+ {
+ ev_timer_stop (EV_A_ w);
+
+ /* now it's one second after the most recent passwd change */
+ }
+
+ static void
+ stat_cb (EV_P_ ev_stat *w, int revents)
+ {
+ /* reset the one-second timer */
+ ev_timer_again (EV_A_ &timer);
+ }
+
+ ...
+ ev_stat_init (&passwd, stat_cb, "/etc/passwd", 0.);
+ ev_stat_start (loop, &passwd);
+ ev_timer_init (&timer, timer_cb, 0., 1.01);
+
+