#include <efsw/FileSystem.hpp> #include <efsw/FileWatcherGeneric.hpp> #include <efsw/Lock.hpp> #include <efsw/System.hpp> namespace efsw { FileWatcherGeneric::FileWatcherGeneric( FileWatcher* parent ) : FileWatcherImpl( parent ), mThread( NULL ), mLastWatchID( 0 ) { mInitOK = true; mIsGeneric = true; } FileWatcherGeneric::~FileWatcherGeneric() { mInitOK = false; efSAFE_DELETE( mThread ); /// Delete the watches WatchList::iterator it = mWatches.begin(); for ( ; it != mWatches.end(); ++it ) { efSAFE_DELETE( ( *it ) ); } } WatchID FileWatcherGeneric::addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive ) { std::string dir( directory ); FileSystem::dirAddSlashAtEnd( dir ); FileInfo fi( dir ); if ( !fi.isDirectory() ) { return Errors::Log::createLastError( Errors::FileNotFound, dir ); } else if ( !fi.isReadable() ) { return Errors::Log::createLastError( Errors::FileNotReadable, dir ); } else if ( pathInWatches( dir ) ) { return Errors::Log::createLastError( Errors::FileRepeated, dir ); } std::string curPath; std::string link( FileSystem::getLinkRealPath( dir, curPath ) ); if ( "" != link ) { if ( pathInWatches( link ) ) { return Errors::Log::createLastError( Errors::FileRepeated, dir ); } else if ( !linkAllowed( curPath, link ) ) { return Errors::Log::createLastError( Errors::FileOutOfScope, dir ); } else { dir = link; } } mLastWatchID++; WatcherGeneric* pWatch = new WatcherGeneric( mLastWatchID, dir, watcher, this, recursive ); Lock lock( mWatchesLock ); mWatches.push_back( pWatch ); return pWatch->ID; } void FileWatcherGeneric::removeWatch( const std::string& directory ) { WatchList::iterator it = mWatches.begin(); for ( ; it != mWatches.end(); ++it ) { if ( ( *it )->Directory == directory ) { WatcherGeneric* watch = ( *it ); Lock lock( mWatchesLock ); mWatches.erase( it ); efSAFE_DELETE( watch ); return; } } } void FileWatcherGeneric::removeWatch( WatchID watchid ) { WatchList::iterator it = mWatches.begin(); for ( ; it != mWatches.end(); ++it ) { if ( ( *it )->ID == watchid ) { WatcherGeneric* watch = ( *it ); Lock lock( mWatchesLock ); mWatches.erase( it ); efSAFE_DELETE( watch ); return; } } } void FileWatcherGeneric::watch() { if ( NULL == mThread ) { mThread = new Thread( &FileWatcherGeneric::run, this ); mThread->launch(); } } void FileWatcherGeneric::run() { do { { Lock lock( mWatchesLock ); WatchList::iterator it = mWatches.begin(); for ( ; it != mWatches.end(); ++it ) { ( *it )->watch(); } } if ( mInitOK ) System::sleep( 1000 ); } while ( mInitOK ); } void FileWatcherGeneric::handleAction( Watcher*, const std::string&, unsigned long, std::string ) { /// Not used } std::list<std::string> FileWatcherGeneric::directories() { std::list<std::string> dirs; Lock lock( mWatchesLock ); WatchList::iterator it = mWatches.begin(); for ( ; it != mWatches.end(); ++it ) { dirs.push_back( ( *it )->Directory ); } return dirs; } bool FileWatcherGeneric::pathInWatches( const std::string& path ) { WatchList::iterator it = mWatches.begin(); for ( ; it != mWatches.end(); ++it ) { if ( ( *it )->Directory == path || ( *it )->pathInWatches( path ) ) { return true; } } return false; } } // namespace efsw