SYNOPSIS<watchpath path=$path [changes=$changes]
[subtree] [symlink] [linkedonly] [dironly]
callback=$callback [userdata=$userdata]>
DESCRIPTION
The watchpath
function watches the existing file or directory $path for changes (e.g. files modified, created, moved etc.). A
user-defined callback function is then called whenever a change is
detected in $path or one of its files/subdirs.
Options are:
path=$path
The file or directory to watch. Under Windows, this must be a directory; to watch a file, watch its parent dir instead and look for events matching the appropriate filename.
changes=$changes
The list of changes to watch for, and report via callback
.
Each element of $changes must be a whitespace/comma-separated
list of zero or more change tokens, listed in a table below. The
default if no tokens given is all. Note that some requested
change tokens are reported in the callback as different tokens,
due to OS limitations; see table below. The operators "+"
and "-" may be used to add or subtract, respectively, all
following tokens (until the next operator) from the currently
computed list. E.g. "-create modify" would watch all
changes (the default), except create and modify.
subtree
By default, just $path and its immediate children (if a
directory) are watched. If subtree
is given, the entire
subtree directory hierarchy at $path will be monitored as
well. Only supported on certain platforms (e.g. Windows); check
for the watchpathsubtree
feature in
<vxinfo features>
(here) to
determine support. Note that trying to work around lack of
subtree
support on a platform by recursing $path
manually and opening a watch for every subdirectory can be
time-consuming, lead to race conditions that miss events, and
possibly run out of memory or other resources.
symlink
Watch $path, not the path it points to, if a symlink; i.e. do not dereference the last component of $path if a symlink. Only supported under Unix.
linkedonly
Only return events for linked children of $path, i.e. do not return events for children once they are unlinked. This can reduce traffic when watching e.g. /tmp and files continue to be modified (via open handles) after they have been deleted. Only supported under Linux 3.10 and later.
dironly
Only watch $path if it is a directory (fail otherwise). This can be used to avoid a race condition after creating $path as a directory and then wathing it: it could have been removed and re-created as a file in between directory creation and watch creation. Only supported under Unix.
callback=$callback
The Vortex script function to call when a change event occurs.
See below for parameters to this function that will be set when
called. To keep the order of callbacks the same as the original
order of events, callbacks are blocking: no callback will be
interrupted by any other <watchpath>
callback (from the
same or different watchpath
call). A callback will awaken
a <sleep $sec wake> statement (here ASAP/early;
however without the wake
parameter the <sleep>
will
likely sleep to completion.
userdata=$userdata
If given, $userdata
will be passed to each callback
call. Can be used to avoid global variable usage for user data in
the callback, or to help distinguish multiple watchpath
calls to the same callback.
The following change tokens are defined. Most, when given to the
changes
option, will request the same event across all
platforms, and will return the same change token in the
callback
function. However, due to underlying API differences,
some requested changes have events that differ across platforms, or
are unsupported and will cause watchpath
to fail with an error.
Additionally, some requested change tokens will return a different
token in the callback; these differences are noted in the Windows
Callback Event column. Requesting solely the other event
may cause an error on some platforms. The unmount, overflow,
and removewatch events are unsupported on some platforms
and may cause an error (e.g. Linux 2.6.18).
Token | Unix Callback Event | Windows Callback Event |
access | Path read | modify: last-access time changed |
create | Path created | Path created |
delete | Path deleted | Path deleted |
modify | Path content modified | Last-write time changed |
movefrom | Path renamed (source) | Path renamed (source) |
moveto | Path renamed (target) | Path renamed (target) |
attribute | Attribute changed | modify: attribute change |
size | Unsupported; use modify | modify: file size changed |
security | Unsupported | modify: security descriptor changed |
creationtime | Unsupported; use attribute | modify: creation time changed |
open | Path opened | Unsupported |
closewrite | Writable descriptor closed | Unsupported |
closenonwrite | Non-writable descriptor closed | Unsupported |
unmount | Filesystem unmounted | Unsupported |
overflow | Too many events; some lost | Too many events; some lost |
removewatch | Watch removed (error) | Watch removed (error) |
other | Unknown event | Unknown event |
all | All supported events | All supported events |
Note that paths moved out of the $path tree will not generate a matching moveto event, and paths moved into the $path tree from outside will not generate a matching movefrom event.
The following parameters to the callback
function will be set
on each event call:
userdata
Set to the userdata
value given in the watchpath
call.path
Path to the event, relative to the watchpath
$path.
Note that if the event is on the watchpath
$path
itself, this parameter will be an empty string. Absolute paths
are not reliably possible, because the watchpath
$path might get moved - but its destination path may not be
known at that time.change
The change that triggered the event. One of the watchpath
change
tokens defined above.flags
Zero or more of the following string flags:
path
was a directory. Note that under
Windows, this flag cannot be determined for modify
events, which will always have it unset, even for directories.
eventtime
The time the event was read from the OS. This may be slightly
later than the event actually occurred, due to OS, thread and/or
read delays, but should be close. However it may be significantly
earlier than when the Vortex callback occurs, e.g. if an event
happens during a time-consuming Vortex statement and is delayed.
Thus the eventtime
value more closely reflects when the
event occurred than evaluating "now" during the callback.id
A dword
value that may be set to associate movefrom
and moveto events: pairs of such events that refer to the
same (atomic) rename operation will have the same id
value.
Note that this information is not available for non-move events,
nor under Windows; in such cases, it will have the value 0.
DIAGNOSTICSwatchpath
returns a handle to an internal watchPath
object. Like MIME, XML etc. objects, this handle need not be closed
explicitly; it is closed - and the watch stops - when the last
Vortex variable reference to it is cleared (e.g. by assignment) or
goes out of scope. It is undefined whether events already queued
(but not passed to the callback) at the time of watch closure will be
reported.
If the watchpath
statement fails, nothing is returned.
EXAMPLE<a name=watchpathCallback private
userdata path change flags eventtime id>
<fmt "At %t " $eventtime> path `$path' ($flags)
received change `$change'
<flush>
</a>
...
<watchpath path="/some/random/dir"
changes="create,delete,movefrom,moveto"
callback="watchpathCallback">
<$WatchHandle = $ret>
<if "" eq $WatchHandle>
Could not watch path.
</if>
... perform other tasks here ...
Ending watch: <$WatchHandle = >
CAVEATS
The watchpath
function was added in version 8. It is only
supported on Linux 2.6.18 and later, and Windows. The subtree
option is only supported on Windows. Use <vxinfo features>
(here) to determine availability of either.
As the callback function can be called at unpredictable times,
it should save and restore any global data it alters, such as
$ret
, $loop
etc. to avoid side effects in other code.
While unlikely, it is possible for events to occur while a
watchpath
is active that do not trigger its callback - despite
matching the filter criteria. This may happen due to load, high event
frequency, limited buffer space, etc. An overflow event may (or
may not) be generated in such cases. Thus, if detection of an event
is critical, it should be backed up with a periodic poll
(e.g. <stat>
) of the path in question, in addition to the
watchpath
.
SEE ALSOstat