diff --git a/filesystem/filesystem.c b/filesystem/filesystem.c index 5e9e3926..55826b1b 100644 --- a/filesystem/filesystem.c +++ b/filesystem/filesystem.c @@ -29,6 +29,9 @@ GNU General Public License for more details. #endif #include #include +#if XASH_LINUX +#include +#endif #include "port.h" #include "const.h" #include "crtlib.h" diff --git a/filesystem/filesystem.h b/filesystem/filesystem.h index 54eac76c..7f184f7c 100644 --- a/filesystem/filesystem.h +++ b/filesystem/filesystem.h @@ -120,6 +120,9 @@ typedef struct fs_globals_t int numgames; } fs_globals_t; +typedef void (*fs_event_callback_t)( const char *path ); + + typedef struct fs_api_t { qboolean (*InitStdio)( qboolean caseinsensitive, const char *rootdir, const char *basedir, const char *gamedir, const char *rodir ); @@ -174,6 +177,10 @@ typedef struct fs_api_t qboolean (*Delete)( const char *path ); qboolean (*SysFileExists)( const char *path, qboolean casesensitive ); const char *(*GetDiskPath)( const char *name, qboolean gamedironly ); + + // file watcher + void (*WatchFrame)( void ); // engine will read all events and call appropriate callbacks + qboolean (*AddWatch)( const char *path, fs_event_callback_t callback ); } fs_api_t; typedef struct fs_interface_t diff --git a/filesystem/filesystem_internal.h b/filesystem/filesystem_internal.h index 5f11f52f..99250189 100644 --- a/filesystem/filesystem_internal.h +++ b/filesystem/filesystem_internal.h @@ -189,6 +189,13 @@ void FS_SearchWAD( stringlist_t *list, wfile_t *wad, const char *pattern ); byte *FS_LoadWADFile( const char *path, fs_offset_t *sizeptr, qboolean gamedironly ); qboolean FS_AddWad_Fullpath( const char *wadfile, qboolean *already_loaded, int flags ); +// +// watch.c +// +qboolean FS_WatchInitialize( void ); +int FS_AddWatch( const char *path, fs_event_callback_t callback ); +void FS_WatchFrame( void ); + // // zip.c // diff --git a/filesystem/watch.c b/filesystem/watch.c new file mode 100644 index 00000000..1d4cf7ea --- /dev/null +++ b/filesystem/watch.c @@ -0,0 +1,117 @@ +#if 0 +#include "build.h" +#if XASH_LINUX +#include +#include +#include +#endif +#include "filesystem_internal.h" +#include "common/com_strings.h" + +#define MAX_FS_WATCHES 256 + +struct +{ +#if XASH_LINUX + int fd; + int count; + struct + { + fs_event_callback_t callback; + int fd; + } watch[MAX_FS_WATCHES]; +#endif // XASH_LINUX +} fsnotify; + +#if XASH_LINUX +static qboolean FS_InotifyInit( void ) +{ + int fd; + + if(( fd = inotify_init1( IN_NONBLOCK )) < 0 ) + { + Con_Printf( S_ERROR "inotify_init1 failed: %s", strerror( errno )); + return false; + } + + fsnotify.fd = fd; + return true; +} + +static qboolean FS_InotifyWasInit( void ) +{ + return fsnotify.fd >= 0; +} +#endif + +/* +=============== +FS_AddWatch + +Adds on-disk path to filesystem watcher list +Every file modification will call back +=============== +*/ +int FS_AddWatch( const char *path, fs_event_callback_t callback ) +{ +#if XASH_LINUX + int fd; + const uint mask = IN_CREATE | IN_DELETE | IN_MODIFY; + + if( !FS_InotifyWasInit() && !FS_InotifyInit()) + return false; + + if(( fd = inotify_add_watch( fsnotify.fd, path, mask )) < 0 ) + { + Con_Printf( S_ERROR "inotify_add_watch failed: %s", strerror( errno )); + return false; + } + + fsnotify.watch[fsnotify.count].fd = fd; + fsnotify.watch[fsnotify.count].callback = callback; + + return true; +#else + return false; +#endif +} + +/* +=============== +FS_WatchFrame + +Polls any changes and runs call backs +=============== +*/ +void FS_WatchFrame( void ) +{ +#if XASH_LINUX + int i; + + for( i = 0; i < fsnotify.count; i++ ) + { + struct inotify_event events; + } + +#endif +} + +/* +=============== +FS_WatchInitialize + +initializes filesystem watcher subsystem +=============== +*/ +qboolean FS_WatchInitialize( void ) +{ +#if XASH_LINUX + fsnotify.fd = -1; // only call inotify init when requested + fsnotify.count = 0; + + return true; +#else + return false; +#endif +} +#endif // 0