watchpath - watch a file or directory for changes

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:

    • isdir The event 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.


DIAGNOSTICS
watchpath 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 ALSO
stat


Copyright © Thunderstone Software     Last updated: Apr 15 2024
Copyright © 2024 Thunderstone Software LLC. All rights reserved.