summaryrefslogtreecommitdiff
path: root/libopie2/opiecore/ofilenotify.cpp
authormickeyl <mickeyl>2004-04-18 18:25:24 (UTC)
committer mickeyl <mickeyl>2004-04-18 18:25:24 (UTC)
commitdf539f67050ebe61b5dc589f9c138bb9ef1719f6 (patch) (unidiff)
tree7baa2dc1e44be92dec2736b8205f9642fffc4302 /libopie2/opiecore/ofilenotify.cpp
parent56f49e8293110e488f3ea6bc6dad282981c81d4b (diff)
downloadopie-df539f67050ebe61b5dc589f9c138bb9ef1719f6.zip
opie-df539f67050ebe61b5dc589f9c138bb9ef1719f6.tar.gz
opie-df539f67050ebe61b5dc589f9c138bb9ef1719f6.tar.bz2
the notifier interface is shaping up
Brad: I sorted the "DN_xxx undeclared" issue out, please test
Diffstat (limited to 'libopie2/opiecore/ofilenotify.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiecore/ofilenotify.cpp160
1 files changed, 114 insertions, 46 deletions
diff --git a/libopie2/opiecore/ofilenotify.cpp b/libopie2/opiecore/ofilenotify.cpp
index 2242570..5e9f97b 100644
--- a/libopie2/opiecore/ofilenotify.cpp
+++ b/libopie2/opiecore/ofilenotify.cpp
@@ -32,6 +32,7 @@ using namespace Opie::Core;
32/* OPIE */ 32/* OPIE */
33 33
34/* QT */ 34/* QT */
35#include <qobject.h>
35#include <qsignal.h> 36#include <qsignal.h>
36#include <qintdict.h> 37#include <qintdict.h>
37#include <qdir.h> 38#include <qdir.h>
@@ -39,77 +40,136 @@ using namespace Opie::Core;
39/* STD */ 40/* STD */
40#include <sys/types.h> 41#include <sys/types.h>
41#include <sys/stat.h> 42#include <sys/stat.h>
42#include <fcntl.h> 43#ifndef _GNU_SOURCE
44 #define _GNU_SOURCE
45 #include <fcntl.h>
46 #undef _GNU_SOURCE
47#else
48 #include <fcntl.h>
49#endif
43#include <string.h> 50#include <string.h>
44#include <errno.h> 51#include <errno.h>
52#include <unistd.h>
53
54static QIntDict<OFileNotification> notification_list;
45 55
46namespace Opie { 56namespace Opie {
47namespace Core { 57namespace Core {
48 58
49class OFileNotification 59OFileNotification::OFileNotification( QObject* parent, const char* name )
60 :QObject( parent, name ), _active( false )
50{ 61{
51 public: 62 qDebug( "OFileNotification::OFileNotification()" );
52 OFileNotification( QObject* receiver, const char* member, OFileNotificationType type ) : _type( type ) 63}
53 {
54 _signal.connect( receiver, member );
55 }
56 ~OFileNotification()
57 {
58 }
59
60 void activate()
61 {
62 _signal.activate();
63 }
64 64
65 OFileNotificationType type()
66 {
67 return _type;
68 }
69 65
70 private: 66OFileNotification::~OFileNotification()
71 OFileNotificationType _type; 67{
72 QSignal _signal; 68 qDebug( "OFileNotification::~OFileNotification()" );
73}; 69}
74 70
75 71
76static QIntDict<OFileNotification> notification_list; 72bool OFileNotification::isActive() const
73{
74 return _active;
75}
77 76
78 77
79void OFileNotifier::singleShot( const QString& path, QObject* receiver, const char* member, OFileNotificationType type ) 78int OFileNotification::start( const QString& path, bool sshot, OFileNotificationType type )
80{ 79{
80 _path = QString::null;
81 _fd = 0;
82 if ( _active ) stop();
83
81 int fd = ::open( (const char*) path, O_RDONLY ); 84 int fd = ::open( (const char*) path, O_RDONLY );
82 if ( fd != -1 ) 85 if ( fd != -1 )
83 { 86 {
84 if ( notification_list.isEmpty() ) 87 if ( notification_list.isEmpty() )
85 { 88 {
86 OFileNotifier::registerSignalHandler(); 89 OFileNotification::registerSignalHandler();
87 } 90 }
88 int result = ::fcntl( fd, F_SETSIG, SIGRTMIN ); 91 int result = ::fcntl( fd, F_SETSIG, SIGRTMIN );
89 if ( result == -1 ) 92 if ( result == -1 )
90 { 93 {
91 qWarning( "OFileNotifier::singleShot(): Can't subscribe to '%s': %s.", (const char*) path, strerror( errno ) ); 94 qWarning( "OFileNotification::start(): Can't subscribe to '%s': %s.", (const char*) path, strerror( errno ) );
92 return; 95 return -1;
93 } 96 }
97 if ( !sshot ) (int) type |= (int) Multi;
94 result = ::fcntl( fd, F_NOTIFY, type ); 98 result = ::fcntl( fd, F_NOTIFY, type );
95 if ( result == -1 ) 99 if ( result == -1 )
96 { 100 {
97 qWarning( "OFileNotifier::singleShot(): Can't subscribe to '%s': %s.", (const char*) path, strerror( errno ) ); 101 qWarning( "OFileNotification::start(): Can't subscribe to '%s': %s.", (const char*) path, strerror( errno ) );
98 return; 102 return -1;
99 } 103 }
100 qDebug( "OFileNotifier::singleShot(): Subscribed for changes to %s (fd = %d)", (const char*) path, fd ); 104 qDebug( "OFileNotification::start(): Subscribed for changes to %s (fd = %d, mask = 0x%0x)", (const char*) path, fd, type );
101 notification_list.insert( fd, new OFileNotification( receiver, member, type ) ); 105 notification_list.insert( fd, this );
106 _type = type;
107 _path = path;
108 _fd = fd;
109 return fd;
102 } 110 }
103 else 111 else
104 { 112 {
105 qWarning( "OFileNotifier::singleShot(): Error with path '%s': %s.", (const char*) path, strerror( errno ) ); 113 qWarning( "OFileNotification::start(): Error with path '%s': %s.", (const char*) path, strerror( errno ) );
114 return -1;
106 } 115 }
107} 116}
108 117
109 118
110void OFileNotifier::__signalHandler( int sig, siginfo_t *si, void *data ) 119void OFileNotification::stop()
111{ 120{
112 qWarning( "OFileNotifier::__signalHandler(): reached." ); 121 if ( !_active ) return;
122
123 int result = ::fcntl( _fd, F_NOTIFY, 0 );
124 if ( result == -1 )
125 {
126 qWarning( "OFileNotification::stop(): Can't remove subscription to '%s': %s.", (const char*) _path, strerror( errno ) );
127 }
128 else
129 {
130 ::close( _fd );
131 _type = Single;
132 _path = QString::null;
133 _fd = 0;
134 _active = false;
135 }
136}
137
138
139OFileNotificationType OFileNotification::type() const
140{
141 return _type;
142}
143
144
145QString OFileNotification::path() const
146{
147 return _path;
148}
149
150int OFileNotification::fileno() const
151{
152 return _fd;
153}
154
155void OFileNotification::activate()
156{
157 emit triggered();
158 _signal.activate();
159}
160
161
162void OFileNotification::singleShot( const QString& path, QObject* receiver, const char* member, OFileNotificationType type )
163{
164 OFileNotification* ofn = new OFileNotification();
165 ofn->_signal.connect( receiver, member );
166 ofn->start( path, true, type );
167}
168
169
170void OFileNotification::__signalHandler( int sig, siginfo_t *si, void *data )
171{
172 qWarning( "OFileNotification::__signalHandler(): reached." );
113 int fd = si->si_fd; 173 int fd = si->si_fd;
114 OFileNotification* fn = notification_list[fd]; 174 OFileNotification* fn = notification_list[fd];
115 if ( fn ) 175 if ( fn )
@@ -118,40 +178,48 @@ void OFileNotifier::__signalHandler( int sig, siginfo_t *si, void *data )
118 #if 1 178 #if 1
119 if ( !(fn->type() & Multi) ) 179 if ( !(fn->type() & Multi) )
120 { 180 {
121 qDebug( "OFileNotifier::__signalHandler(): '%d' was singleShot. Removing from list.", fd ); 181 qDebug( "OFileNotification::__signalHandler(): '%d' was singleShot. Removing from list.", fd );
122 notification_list.remove( fd ); 182 notification_list.remove( fd );
123 if ( notification_list.isEmpty() ) 183 if ( notification_list.isEmpty() )
124 { 184 {
125 OFileNotifier::unregisterSignalHandler(); 185 OFileNotification::unregisterSignalHandler();
126 } 186 }
127 } 187 }
128 #endif 188 #endif
129 } 189 }
130 else 190 else
131 { 191 {
132 qWarning( "OFileNotifier::__signalHandler(): D'oh! Called without fd in notification_list. Race condition?" ); 192 qWarning( "OFileNotification::__signalHandler(): D'oh! Called without fd in notification_list. Race condition?" );
133 } 193 }
134} 194}
135 195
136 196
137void OFileNotifier::registerSignalHandler() 197bool OFileNotification::registerSignalHandler()
138{ 198{
139 struct sigaction act; 199 struct sigaction act;
140 act.sa_sigaction = OFileNotifier::__signalHandler; 200 act.sa_sigaction = OFileNotification::__signalHandler;
141 ::sigemptyset( &act.sa_mask ); 201 ::sigemptyset( &act.sa_mask );
142 act.sa_flags = SA_SIGINFO; 202 act.sa_flags = SA_SIGINFO;
143 ::sigaction( SIGRTMIN, &act, NULL ); 203 if ( ::sigaction( SIGRTMIN, &act, NULL ) == -1 )
144 qDebug( "OFileNotifier::registerSignalHandler(): done" ); 204 {
205 qWarning( "OFileNotification::registerSignalHandler(): couldn't register signal handler: %s", strerror( errno ) );
206 return false;
207 }
208 qDebug( "OFileNotification::registerSignalHandler(): done" );
145} 209}
146 210
147 211
148void OFileNotifier::unregisterSignalHandler() 212void OFileNotification::unregisterSignalHandler()
149{ 213{
150 struct sigaction act; 214 struct sigaction act;
151 act.sa_sigaction = ( void (*)(int, siginfo_t*, void*) ) SIG_DFL; 215 act.sa_sigaction = ( void (*)(int, siginfo_t*, void*) ) SIG_DFL;
152 sigemptyset( &act.sa_mask ); 216 ::sigemptyset( &act.sa_mask );
153 ::sigaction( SIGRTMIN, &act, NULL ); 217 if ( ::sigaction( SIGRTMIN, &act, NULL ) == -1 )
154 qDebug( "OFileNotifier::unregisterSignalHandler(): done" ); 218 if ( ::sigaction( SIGRTMIN, &act, NULL ) == -1 )
219 {
220 qWarning( "OFileNotification::unregisterSignalHandler(): couldn't deregister signal handler: %s", strerror( errno ) );
221 }
222 qDebug( "OFileNotification::unregisterSignalHandler(): done" );
155} 223}
156 224
157 225