/** @author Sepul Sepehr Taghdisian Copyright (c) 2024 Martín Lucas Golini Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. This software is a fork of the "simplefilewatcher" by James Wynn (james@jameswynn.com) http://code.google.com/p/simplefilewatcher/ also MIT licensed. */ /** This is the C API wrapper of EFSW */ #ifndef ESFW_H #define ESFW_H #ifdef __cplusplus extern "C" { #endif #if defined( _WIN32 ) #ifdef EFSW_DYNAMIC // Windows platforms #ifdef EFSW_EXPORTS // From DLL side, we must export #define EFSW_API __declspec( dllexport ) #else // From client application side, we must import #define EFSW_API __declspec( dllimport ) #endif #else // No specific directive needed for static build #ifndef EFSW_API #define EFSW_API #endif #endif #else #if ( __GNUC__ >= 4 ) && defined( EFSW_EXPORTS ) #define EFSW_API __attribute__( ( visibility( "default" ) ) ) #endif // Other platforms don't need to define anything #ifndef EFSW_API #define EFSW_API #endif #endif /// Type for a watch id typedef long efsw_watchid; /// Type for watcher typedef void* efsw_watcher; enum efsw_action { EFSW_ADD = 1, /// Sent when a file is created or renamed EFSW_DELETE = 2, /// Sent when a file is deleted or renamed EFSW_MODIFIED = 3, /// Sent when a file is modified EFSW_MOVED = 4 /// Sent when a file is moved }; enum efsw_error { EFSW_NOTFOUND = -1, EFSW_REPEATED = -2, EFSW_OUTOFSCOPE = -3, EFSW_NOTREADABLE = -4, EFSW_REMOTE = -5, EFSW_WATCHER_FAILED = -6, EFSW_UNSPECIFIED = -7 }; enum efsw_option { /// For Windows, the default buffer size of 63*1024 bytes sometimes is not enough and /// file system events may be dropped. For that, using a different (bigger) buffer size /// can be defined here, but note that this does not work for network drives, /// because a buffer larger than 64K will fail the folder being watched, see /// http://msdn.microsoft.com/en-us/library/windows/desktop/aa365465(v=vs.85).aspx) EFSW_OPT_WIN_BUFFER_SIZE = 1, /// For Windows, per default all events are captured but we might only be interested /// in a subset; the value of the option should be set to a bitwise or'ed set of /// FILE_NOTIFY_CHANGE_* flags. EFSW_OPT_WIN_NOTIFY_FILTER = 2, /// For macOS (FSEvents backend), per default all modified event types are capture but we might // only be interested in a subset; the value of the option should be set to a set of bitwise // from: // kFSEventStreamEventFlagItemFinderInfoMod // kFSEventStreamEventFlagItemModified // kFSEventStreamEventFlagItemInodeMetaMod // Default configuration will set the 3 flags EFSW_OPT_MAC_MODIFIED_FILTER = 3, /// macOS sometimes informs incorrect or old file states that may confuse the consumer /// The events sanitizer will try to sanitize incorrectly reported events in favor of reducing /// the number of events reported. This will have an small performance and memory impact as a /// consequence. EFSW_OPT_MAC_SANITIZE_EVENTS = 4, /// Linux does not support natively recursive watchers. This means that when using recursive /// watches efsw registers new watchers for each directory. If new file are created between /// the time efsw takes to register the new directory those events might be missed. To avoid /// missing new file notifications efsw will trigger synthetic new file events for existing /// files in the new directroy watched. This might have the unintended consequence of sending /// duplicated created events due to the system also emitting this event. LINUX_PRODUCE_SYNTHETIC_EVENTS = 5, }; /// Basic interface for listening for file events. typedef void ( *efsw_pfn_fileaction_callback )( efsw_watcher watcher, efsw_watchid watchid, const char* dir, const char* filename, enum efsw_action action, const char* old_filename, void* param ); typedef struct { enum efsw_option option; int value; } efsw_watcher_option; /** * Creates a new file-watcher * @param generic_mode Force the use of the Generic file watcher */ efsw_watcher EFSW_API efsw_create( int generic_mode ); /// Release the file-watcher and unwatch any directories void EFSW_API efsw_release( efsw_watcher watcher ); /// Retrieve last error occured by file-watcher EFSW_API const char* efsw_getlasterror(); /// Reset file-watcher last error EFSW_API void efsw_clearlasterror(); /// Add a directory watch /// On error returns WatchID with Error type. efsw_watchid EFSW_API efsw_addwatch( efsw_watcher watcher, const char* directory, efsw_pfn_fileaction_callback callback_fn, int recursive, void* param ); /// Add a directory watch, specifying options /// @param options Pointer to an array of watcher options /// @param nr_options Number of options referenced by \p options efsw_watchid EFSW_API efsw_addwatch_withoptions( efsw_watcher watcher, const char* directory, efsw_pfn_fileaction_callback callback_fn, int recursive, efsw_watcher_option* options, int options_number, void* param ); /// Remove a directory watch. This is a brute force search O(nlogn). void EFSW_API efsw_removewatch( efsw_watcher watcher, const char* directory ); /// Remove a directory watch. This is a map lookup O(logn). void EFSW_API efsw_removewatch_byid( efsw_watcher watcher, efsw_watchid watchid ); /// Starts watching ( in other thread ) void EFSW_API efsw_watch( efsw_watcher watcher ); /** * Allow recursive watchers to follow symbolic links to other directories * followSymlinks is disabled by default */ void EFSW_API efsw_follow_symlinks( efsw_watcher watcher, int enable ); /** @return If can follow symbolic links to directorioes */ int EFSW_API efsw_follow_symlinks_isenabled( efsw_watcher watcher ); /** * When enable this it will allow symlinks to watch recursively out of the pointed directory. * follorSymlinks must be enabled to this work. * For example, added symlink to /home/folder, and the symlink points to /, this by default is not * allowed, it's only allowed to symlink anything from /home/ and deeper. This is to avoid great * levels of recursion. Enabling this could lead in infinite recursion, and crash the watcher ( it * will try not to avoid this ). Buy enabling out of scope links, it will allow this behavior. * allowOutOfScopeLinks are disabled by default. */ void EFSW_API efsw_allow_outofscopelinks( efsw_watcher watcher, int allow ); /// @return Returns if out of scope links are allowed int EFSW_API efsw_outofscopelinks_isallowed( efsw_watcher watcher ); #ifdef __cplusplus } #endif #endif