-rw-r--r-- | libopie2/opiecore/ofilenotify.cpp | 159 | ||||
-rw-r--r-- | libopie2/opiecore/ofilenotify.h | 72 | ||||
-rw-r--r-- | libopie2/opiecore/opiecore.pro | 4 |
3 files changed, 234 insertions, 1 deletions
diff --git a/libopie2/opiecore/ofilenotify.cpp b/libopie2/opiecore/ofilenotify.cpp new file mode 100644 index 0000000..2242570 --- a/dev/null +++ b/libopie2/opiecore/ofilenotify.cpp @@ -0,0 +1,159 @@ +/* + This file is part of the Opie Project + =. Copyright (C) 2004 Michael 'Mickey' Lauer <mickey@Vanille.de> + .=l. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .>+-= +_;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software +- . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. +: = ...= . :.=- +-. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "ofilenotify.h" +using namespace Opie::Core; + +/* OPIE */ + +/* QT */ +#include <qsignal.h> +#include <qintdict.h> +#include <qdir.h> + +/* STD */ +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> +#include <errno.h> + +namespace Opie { +namespace Core { + +class OFileNotification +{ + public: + OFileNotification( QObject* receiver, const char* member, OFileNotificationType type ) : _type( type ) + { + _signal.connect( receiver, member ); + } + ~OFileNotification() + { + } + + void activate() + { + _signal.activate(); + } + + OFileNotificationType type() + { + return _type; + } + + private: + OFileNotificationType _type; + QSignal _signal; +}; + + +static QIntDict<OFileNotification> notification_list; + + +void OFileNotifier::singleShot( const QString& path, QObject* receiver, const char* member, OFileNotificationType type ) +{ + int fd = ::open( (const char*) path, O_RDONLY ); + if ( fd != -1 ) + { + if ( notification_list.isEmpty() ) + { + OFileNotifier::registerSignalHandler(); + } + int result = ::fcntl( fd, F_SETSIG, SIGRTMIN ); + if ( result == -1 ) + { + qWarning( "OFileNotifier::singleShot(): Can't subscribe to '%s': %s.", (const char*) path, strerror( errno ) ); + return; + } + result = ::fcntl( fd, F_NOTIFY, type ); + if ( result == -1 ) + { + qWarning( "OFileNotifier::singleShot(): Can't subscribe to '%s': %s.", (const char*) path, strerror( errno ) ); + return; + } + qDebug( "OFileNotifier::singleShot(): Subscribed for changes to %s (fd = %d)", (const char*) path, fd ); + notification_list.insert( fd, new OFileNotification( receiver, member, type ) ); + } + else + { + qWarning( "OFileNotifier::singleShot(): Error with path '%s': %s.", (const char*) path, strerror( errno ) ); + } +} + + +void OFileNotifier::__signalHandler( int sig, siginfo_t *si, void *data ) +{ + qWarning( "OFileNotifier::__signalHandler(): reached." ); + int fd = si->si_fd; + OFileNotification* fn = notification_list[fd]; + if ( fn ) + { + fn->activate(); + #if 1 + if ( !(fn->type() & Multi) ) + { + qDebug( "OFileNotifier::__signalHandler(): '%d' was singleShot. Removing from list.", fd ); + notification_list.remove( fd ); + if ( notification_list.isEmpty() ) + { + OFileNotifier::unregisterSignalHandler(); + } + } + #endif + } + else + { + qWarning( "OFileNotifier::__signalHandler(): D'oh! Called without fd in notification_list. Race condition?" ); + } +} + + +void OFileNotifier::registerSignalHandler() +{ + struct sigaction act; + act.sa_sigaction = OFileNotifier::__signalHandler; + ::sigemptyset( &act.sa_mask ); + act.sa_flags = SA_SIGINFO; + ::sigaction( SIGRTMIN, &act, NULL ); + qDebug( "OFileNotifier::registerSignalHandler(): done" ); +} + + +void OFileNotifier::unregisterSignalHandler() +{ + struct sigaction act; + act.sa_sigaction = ( void (*)(int, siginfo_t*, void*) ) SIG_DFL; + sigemptyset( &act.sa_mask ); + ::sigaction( SIGRTMIN, &act, NULL ); + qDebug( "OFileNotifier::unregisterSignalHandler(): done" ); +} + + +} +} diff --git a/libopie2/opiecore/ofilenotify.h b/libopie2/opiecore/ofilenotify.h new file mode 100644 index 0000000..638eb6c --- a/dev/null +++ b/libopie2/opiecore/ofilenotify.h @@ -0,0 +1,72 @@ +/* + This file is part of the Opie Project + =. Copyright (C) 2004 Michael 'Mickey' Lauer <mickey@Vanille.de> + .=l. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .>+-= +_;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software +- . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. +: = ...= . :.=- +-. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef OFILENOTIFY_H +#define OFILENOTIFY_H + +/* QT */ +#include <qstring.h> +#include <qobject.h> + +/* STD */ +#include <signal.h> +#include <fcntl.h> + +namespace Opie { +namespace Core { + +enum OFileNotificationType { Single = 0x0000000, + Multi = DN_MULTISHOT, + Access = DN_ACCESS, + Modify = DN_MODIFY, + Create = DN_CREATE, + Delete = DN_DELETE, + Rename = DN_RENAME, + Attrib = DN_ATTRIB }; + +class OFileNotifier : public QObject +{ + public: + static void singleShot( const QString& path, + QObject *receiver, const char *member, + OFileNotificationType type = Modify ); + protected: + static void registerSignalHandler(); + static void unregisterSignalHandler(); + static void __signalHandler( int sig, siginfo_t *si, void *data ); + + private: + OFileNotifier(); + ~OFileNotifier(); +}; + +} +} + +#endif + diff --git a/libopie2/opiecore/opiecore.pro b/libopie2/opiecore/opiecore.pro index 171bb0c..ee42368 100644 --- a/libopie2/opiecore/opiecore.pro +++ b/libopie2/opiecore/opiecore.pro @@ -1,43 +1,45 @@ TEMPLATE = lib CONFIG += qt warn_on DESTDIR = $(OPIEDIR)/lib HEADERS = oapplication.h \ oconfig.h \ odebug.h \ + ofilenotify.h \ oglobal.h \ oglobalsettings.h \ okeyconfigmanager.h \ oprocess.h \ oprocctrl.h \ osmartpointer.h \ ostorageinfo.h \ xmltree.h SOURCES = oapplication.cpp \ oconfig.cpp \ odebug.cpp \ + ofilenotify.cpp \ oglobal.cpp \ oglobalsettings.cpp \ okeyconfigmanager.cpp \ oprocess.cpp \ oprocctrl.cpp \ ostorageinfo.cpp \ xmltree.cpp include ( device/device.pro ) INTERFACES = TARGET = opiecore2 -VERSION = 1.9.0 +VERSION = 1.9.1 INCLUDEPATH += $(OPIEDIR)/include DEPENDPATH += $(OPIEDIR)/include !contains( platform, x11 ) { LIBS = -lqpe include ( $(OPIEDIR)/include.pro ) } contains( platform, x11 ) { LIBS = -L$(OPIEDIR)/lib -Wl,-rpath,$(OPIEDIR)/lib } |