From 71b24a42daccd45fe80b2a669c3a88cfc5dcf608 Mon Sep 17 00:00:00 2001 From: mickeyl Date: Fri, 16 Apr 2004 18:09:45 +0000 Subject: initial checkin of file and directory notifying classes this is work in progress. don't look to close yet --- (limited to 'libopie2/opiecore/ofilenotify.cpp') 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 + .=l. Copyright (C) The Opie Team +          .>+-= +_;:,     .>    :=|. 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_,=:_.      -`: 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 +#include +#include + +/* STD */ +#include +#include +#include +#include +#include + +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 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" ); +} + + +} +} -- cgit v0.9.0.2