author | mickeyl <mickeyl> | 2005-05-06 19:47:16 (UTC) |
---|---|---|
committer | mickeyl <mickeyl> | 2005-05-06 19:47:16 (UTC) |
commit | 8b1a64ffe497f5395544c6702225003aca293f80 (patch) (side-by-side diff) | |
tree | 98d8aa7db946ae0bc9f96f51fd040627a125dceb /libopie2 | |
parent | e73cc9ec4596e1b5e9eed13af710606f358860ba (diff) | |
download | opie-8b1a64ffe497f5395544c6702225003aca293f80.zip opie-8b1a64ffe497f5395544c6702225003aca293f80.tar.gz opie-8b1a64ffe497f5395544c6702225003aca293f80.tar.bz2 |
fix a couple of issues with OFileNotification, seems to work with single and multiple file notifications now
add a named trigger
-rw-r--r-- | libopie2/opiecore/ofilenotify.cpp | 55 | ||||
-rw-r--r-- | libopie2/opiecore/ofilenotify.h | 42 |
2 files changed, 84 insertions, 13 deletions
diff --git a/libopie2/opiecore/ofilenotify.cpp b/libopie2/opiecore/ofilenotify.cpp index c221e58..efd041a 100644 --- a/libopie2/opiecore/ofilenotify.cpp +++ b/libopie2/opiecore/ofilenotify.cpp @@ -77,19 +77,36 @@ bool OFileNotification::isActive() const return _active; } int OFileNotification::watch( const QString& path, bool sshot, OFileNotificationType type ) { - if ( QFile::exists( path ) ) + // check if path exists and is a regular file + struct stat s; + if ( ::stat( (const char*) path, &s ) == -1 ) { + qWarning( "OFileNotification::watch(): Can't watch '%s': %s.", (const char*) path, strerror( errno ) ); + return -1; + } + if ( !S_ISREG( s.st_mode ) ) + { + qWarning( "OFileNotification::watch(): Can't watch '%s': %s.", (const char*) path, "not a regular file" ); + return -1; + } + if ( notification_list.isEmpty() ) { OFileNotification::registerEventHandler(); } + return startWatching( path, sshot, type ); +} + + +int OFileNotification::startWatching( const QString& path, bool sshot, OFileNotificationType type ) +{ struct inotify_watch_request iwr; ::memset( &iwr, 0, sizeof iwr ); iwr.name = const_cast<char*>( (const char*) path ); iwr.mask = type; _wd = ::ioctl( OFileNotification::_fd, INOTIFY_WATCH, &iwr ); @@ -98,24 +115,19 @@ int OFileNotification::watch( const QString& path, bool sshot, OFileNotification { qWarning( "OFileNotification::watch(): inotify can't watch '%s': %s.", (const char*) path, strerror( errno ) ); return -1; } notification_list.insert( _wd, this ); + _path = path; _multi = !sshot; _type = type; _active = true; qDebug( "OFileNotification::watch(): watching '%s' [wd=%d].", (const char*) path, _wd ); return _wd; } - else - { - qWarning( "OFileNotification::watch(): Can't watch '%s': %s.", (const char*) path, strerror( errno ) ); - return -1; - } -} void OFileNotification::stop() { notification_list.remove( _wd ); _path = QString::null; @@ -139,24 +151,24 @@ QString OFileNotification::path() const return _path; } bool OFileNotification::activate() { - emit triggered(); + emit triggered( _path ); _signal.activate(); if ( !_multi ) stop(); return true; } -void OFileNotification::singleShot( const QString& path, QObject* receiver, const char* member, OFileNotificationType type ) +bool OFileNotification::singleShot( const QString& path, QObject* receiver, const char* member, OFileNotificationType type ) { OFileNotification* ofn = new OFileNotification(); ofn->_signal.connect( receiver, member ); - ofn->watch( path, true, type ); + return ofn->watch( path, true, type ) != -1; } void OFileNotification::inotifyEventHandler() { qWarning( "OFileNotification::__eventHandler(): reached." ); @@ -215,14 +227,37 @@ bool OFileNotification::registerEventHandler() return true; } void OFileNotification::unregisterEventHandler() { + if ( _sn ) delete _sn; if ( OFileNotification::_fd ) ::close( OFileNotification::_fd ); qDebug( "OFileNotification::unregisterEventHandler(): done" ); } +//================================================================================================= +// ODirNotification +//================================================================================================= +ODirNotification::ODirNotification( QObject* parent, const char* name ) + :QObject( parent, name ) +{ + qDebug( "ODirNotification::ODirNotification()" ); +} + + +ODirNotification::~ODirNotification() +{ + qDebug( "ODirNotification::~ODirNotification()" ); +} + +int ODirNotification::watch( const QString& path, bool sshot, OFileNotificationType type, int recurse ) +{ + qDebug( "ODirNotification::watch( %s, %d, 0x%08x, %d )", (const char*) path, sshot, type, recurse ); + return 0; } + +} + } diff --git a/libopie2/opiecore/ofilenotify.h b/libopie2/opiecore/ofilenotify.h index ea525e9..41ba84d 100644 --- a/libopie2/opiecore/ofilenotify.h +++ b/libopie2/opiecore/ofilenotify.h @@ -95,13 +95,13 @@ enum OFileNotificationType *======================================================================================*/ /** * @brief Represents a file notification * * This class allows to watch for events happening to files. - * It uses the inotify kernel interface + * It uses the inotify linux (2.6.x) kernel interface. * * @see http://www.kernel.org/pub/linux/kernel/people/rml/inotify/ * * @author Michael 'Mickey' Lauer <mickey@vanille.de> * **/ @@ -137,13 +137,13 @@ class OFileNotification : public QObject * * This sample program automatically terminates when the file "/tmp/quit" has been created. * * * The @a receiver is the receiving object and the @a member is the slot. **/ - static void singleShot( const QString& path, QObject* receiver, const char* member, OFileNotificationType type = Modify ); + static bool singleShot( const QString& path, QObject* receiver, const char* member, OFileNotificationType type = Modify ); /** * Starts to watch for @a type changes to @a path. Set @a sshot to True if you want to be notified only once. * Note that in that case it may be more convenient to use @ref OFileNotification::singleShot() then. **/ int watch( const QString& path, bool sshot = false, OFileNotificationType type = Modify ); /** @@ -159,18 +159,22 @@ class OFileNotification : public QObject **/ QString path() const; /** * @returns if a file is currently being watched. **/ bool isActive() const; + /** + * @internal + */ + int startWatching( const QString& path, bool sshot = false, OFileNotificationType type = Modify ); signals: /** * This signal is emitted if an event happens of the specified type happens to the file being watched. **/ - void triggered(); + void triggered( const QString& name ); protected: bool activate(); private slots: void inotifyEventHandler(); @@ -186,11 +190,43 @@ class OFileNotification : public QObject bool _multi; static QSocketNotifier* _sn; int _wd; // inotify watch descriptor static int _fd; // inotify device descriptor }; +/*====================================================================================== + * ODirNotification + *======================================================================================*/ + +/** + * @brief Represents a directory notification + * + * This class allows to watch for events happening to directories + * It uses the OFileNotification class + * + * @see http://www.kernel.org/pub/linux/kernel/people/rml/inotify/ + * + * @author Michael 'Mickey' Lauer <mickey@vanille.de> + * + **/ + +class ODirNotification : public QObject +{ + Q_OBJECT + + public: + ODirNotification( QObject* parent = 0, const char* name = 0 ); + ~ODirNotification(); + /** + * Starts to watch for @a type changes to @a path. Recurse @a recurse levels down the filesystem tree, + * use 0 for no recursion and -1 for unlimited recursion. + * Set @a sshot to True if you want to be notified only once. + **/ + int watch( const QString& path, bool sshot = false, OFileNotificationType type = Modify, int recurse = 0 ); +}; + + } } #endif |