11/**
22 @author Sepul Sepehr Taghdisian
33
4- Copyright (c) 2013 Martin Lucas Golini
4+ Copyright (c) 2024 Martín Lucas Golini
55
66 Permission is hereby granted, free of charge, to any person obtaining a copy
77 of this software and associated documentation files (the "Software"), to deal
3232extern "C" {
3333#endif
3434
35- #if defined(_WIN32 )
36- #ifdef EFSW_DYNAMIC
37- // Windows platforms
38- #ifdef EFSW_EXPORTS
39- // From DLL side, we must export
40- #define EFSW_API __declspec(dllexport)
41- #else
42- // From client application side, we must import
43- #define EFSW_API __declspec(dllimport)
44- #endif
45- #else
46- // No specific directive needed for static build
47- #ifndef EFSW_API
48- #define EFSW_API
49- #endif
50- #endif
35+ #if defined( _WIN32 )
36+ #ifdef EFSW_DYNAMIC
37+ // Windows platforms
38+ #ifdef EFSW_EXPORTS
39+ // From DLL side, we must export
40+ #define EFSW_API __declspec( dllexport )
5141#else
52- #if ( __GNUC__ >= 4 ) && defined( EFSW_EXPORTS )
53- #define EFSW_API __attribute__ ((visibility("default")))
54- #endif
55-
56- // Other platforms don't need to define anything
57- #ifndef EFSW_API
58- #define EFSW_API
59- #endif
42+ // From client application side, we must import
43+ #define EFSW_API __declspec( dllimport )
44+ #endif
45+ #else
46+ // No specific directive needed for static build
47+ #ifndef EFSW_API
48+ #define EFSW_API
49+ #endif
50+ #endif
51+ #else
52+ #if ( __GNUC__ >= 4 ) && defined( EFSW_EXPORTS )
53+ #define EFSW_API __attribute__( ( visibility( "default" ) ) )
54+ #endif
55+
56+ // Other platforms don't need to define anything
57+ #ifndef EFSW_API
58+ #define EFSW_API
59+ #endif
6060#endif
6161
6262/// Type for a watch id
@@ -65,27 +65,24 @@ typedef long efsw_watchid;
6565/// Type for watcher
6666typedef void * efsw_watcher ;
6767
68- enum efsw_action
69- {
70- EFSW_ADD = 1 , /// Sent when a file is created or renamed
71- EFSW_DELETE = 2 , /// Sent when a file is deleted or renamed
72- EFSW_MODIFIED = 3 , /// Sent when a file is modified
73- EFSW_MOVED = 4 /// Sent when a file is moved
68+ enum efsw_action {
69+ EFSW_ADD = 1 , /// Sent when a file is created or renamed
70+ EFSW_DELETE = 2 , /// Sent when a file is deleted or renamed
71+ EFSW_MODIFIED = 3 , /// Sent when a file is modified
72+ EFSW_MOVED = 4 /// Sent when a file is moved
7473};
7574
76- enum efsw_error
77- {
78- EFSW_NOTFOUND = -1 ,
79- EFSW_REPEATED = -2 ,
80- EFSW_OUTOFSCOPE = -3 ,
81- EFSW_NOTREADABLE = -4 ,
82- EFSW_REMOTE = -5 ,
83- EFSW_WATCHER_FAILED = -6 ,
84- EFSW_UNSPECIFIED = -7
75+ enum efsw_error {
76+ EFSW_NOTFOUND = -1 ,
77+ EFSW_REPEATED = -2 ,
78+ EFSW_OUTOFSCOPE = -3 ,
79+ EFSW_NOTREADABLE = -4 ,
80+ EFSW_REMOTE = -5 ,
81+ EFSW_WATCHER_FAILED = -6 ,
82+ EFSW_UNSPECIFIED = -7
8583};
8684
87- enum efsw_option
88- {
85+ enum efsw_option {
8986 /// For Windows, the default buffer size of 63*1024 bytes sometimes is not enough and
9087 /// file system events may be dropped. For that, using a different (bigger) buffer size
9188 /// can be defined here, but note that this does not work for network drives,
@@ -95,19 +92,37 @@ enum efsw_option
9592 /// For Windows, per default all events are captured but we might only be interested
9693 /// in a subset; the value of the option should be set to a bitwise or'ed set of
9794 /// FILE_NOTIFY_CHANGE_* flags.
98- EFSW_OPT_WIN_NOTIFY_FILTER = 2
95+ EFSW_OPT_WIN_NOTIFY_FILTER = 2 ,
96+ /// For macOS (FSEvents backend), per default all modified event types are capture but we might
97+ // only be interested in a subset; the value of the option should be set to a set of bitwise
98+ // from:
99+ // kFSEventStreamEventFlagItemFinderInfoMod
100+ // kFSEventStreamEventFlagItemModified
101+ // kFSEventStreamEventFlagItemInodeMetaMod
102+ // Default configuration will set the 3 flags
103+ EFSW_OPT_MAC_MODIFIED_FILTER = 3 ,
104+ /// macOS sometimes informs incorrect or old file states that may confuse the consumer
105+ /// The events sanitizer will try to sanitize incorrectly reported events in favor of reducing
106+ /// the number of events reported. This will have an small performance and memory impact as a
107+ /// consequence.
108+ EFSW_OPT_MAC_SANITIZE_EVENTS = 4 ,
109+ /// Linux does not support natively recursive watchers. This means that when using recursive
110+ /// watches efsw registers new watchers for each directory. If new file are created between
111+ /// the time efsw takes to register the new directory those events might be missed. To avoid
112+ /// missing new file notifications efsw will trigger synthetic new file events for existing
113+ /// files in the new directroy watched. This might have the unintended consequence of sending
114+ /// duplicated created events due to the system also emitting this event.
115+ LINUX_PRODUCE_SYNTHETIC_EVENTS = 5 ,
99116};
100117
101118/// Basic interface for listening for file events.
102- typedef void (* efsw_pfn_fileaction_callback ) (
103- efsw_watcher watcher ,
104- efsw_watchid watchid ,
105- const char * dir ,
106- const char * filename ,
107- enum efsw_action action ,
108- const char * old_filename ,
109- void * param
110- );
119+ typedef void ( * efsw_pfn_fileaction_callback )( efsw_watcher watcher , efsw_watchid watchid ,
120+ const char * dir , const char * filename ,
121+ enum efsw_action action , const char * old_filename ,
122+ void * param );
123+
124+ typedef void ( * efsw_pfn_handle_missed_fileactions )( efsw_watcher watcher , efsw_watchid watchid ,
125+ const char * dir );
111126
112127typedef struct {
113128 enum efsw_option option ;
@@ -118,10 +133,10 @@ typedef struct {
118133 * Creates a new file-watcher
119134 * @param generic_mode Force the use of the Generic file watcher
120135 */
121- efsw_watcher EFSW_API efsw_create (int generic_mode );
136+ efsw_watcher EFSW_API efsw_create ( int generic_mode );
122137
123138/// Release the file-watcher and unwatch any directories
124- void EFSW_API efsw_release (efsw_watcher watcher );
139+ void EFSW_API efsw_release ( efsw_watcher watcher );
125140
126141/// Retrieve last error occured by file-watcher
127142EFSW_API const char * efsw_getlasterror ();
@@ -131,47 +146,49 @@ EFSW_API void efsw_clearlasterror();
131146
132147/// Add a directory watch
133148/// On error returns WatchID with Error type.
134- efsw_watchid EFSW_API efsw_addwatch (efsw_watcher watcher , const char * directory ,
135- efsw_pfn_fileaction_callback callback_fn , int recursive , void * param );
149+ efsw_watchid EFSW_API efsw_addwatch ( efsw_watcher watcher , const char * directory ,
150+ efsw_pfn_fileaction_callback callback_fn , int recursive ,
151+ void * param );
136152
137153/// Add a directory watch, specifying options
138154/// @param options Pointer to an array of watcher options
139155/// @param nr_options Number of options referenced by \p options
140- efsw_watchid EFSW_API efsw_addwatch_withoptions (efsw_watcher watcher , const char * directory ,
141- efsw_pfn_fileaction_callback callback_fn , int recursive , efsw_watcher_option * options ,
142- int options_number , void * param );
156+ efsw_watchid EFSW_API efsw_addwatch_withoptions (
157+ efsw_watcher watcher , const char * directory , efsw_pfn_fileaction_callback callback_fn ,
158+ int recursive , efsw_watcher_option * options , int options_number , void * param ,
159+ efsw_pfn_handle_missed_fileactions callback_fn_missed_file_actions );
143160
144161/// Remove a directory watch. This is a brute force search O(nlogn).
145- void EFSW_API efsw_removewatch (efsw_watcher watcher , const char * directory );
162+ void EFSW_API efsw_removewatch ( efsw_watcher watcher , const char * directory );
146163
147164/// Remove a directory watch. This is a map lookup O(logn).
148- void EFSW_API efsw_removewatch_byid (efsw_watcher watcher , efsw_watchid watchid );
165+ void EFSW_API efsw_removewatch_byid ( efsw_watcher watcher , efsw_watchid watchid );
149166
150167/// Starts watching ( in other thread )
151- void EFSW_API efsw_watch (efsw_watcher watcher );
168+ void EFSW_API efsw_watch ( efsw_watcher watcher );
152169
153170/**
154171 * Allow recursive watchers to follow symbolic links to other directories
155172 * followSymlinks is disabled by default
156173 */
157- void EFSW_API efsw_follow_symlinks (efsw_watcher watcher , int enable );
174+ void EFSW_API efsw_follow_symlinks ( efsw_watcher watcher , int enable );
158175
159176/** @return If can follow symbolic links to directorioes */
160- int EFSW_API efsw_follow_symlinks_isenabled (efsw_watcher watcher );
177+ int EFSW_API efsw_follow_symlinks_isenabled ( efsw_watcher watcher );
161178
162179/**
163180 * When enable this it will allow symlinks to watch recursively out of the pointed directory.
164181 * follorSymlinks must be enabled to this work.
165- * For example, added symlink to /home/folder, and the symlink points to /, this by default is not allowed,
166- * it's only allowed to symlink anything from /home/ and deeper. This is to avoid great levels of recursion.
167- * Enabling this could lead in infinite recursion, and crash the watcher ( it will try not to avoid this ).
168- * Buy enabling out of scope links, it will allow this behavior.
182+ * For example, added symlink to /home/folder, and the symlink points to /, this by default is not
183+ * allowed, it's only allowed to symlink anything from /home/ and deeper. This is to avoid great
184+ * levels of recursion. Enabling this could lead in infinite recursion, and crash the watcher ( it
185+ * will try not to avoid this ). Buy enabling out of scope links, it will allow this behavior.
169186 * allowOutOfScopeLinks are disabled by default.
170187 */
171- void EFSW_API efsw_allow_outofscopelinks (efsw_watcher watcher , int allow );
188+ void EFSW_API efsw_allow_outofscopelinks ( efsw_watcher watcher , int allow );
172189
173190/// @return Returns if out of scope links are allowed
174- int EFSW_API efsw_outofscopelinks_isallowed (efsw_watcher watcher );
191+ int EFSW_API efsw_outofscopelinks_isallowed ( efsw_watcher watcher );
175192
176193#ifdef __cplusplus
177194}
0 commit comments