summaryrefslogtreecommitdiff
path: root/libopie2/opiecore/ofilenotify.cpp
Unidiff
Diffstat (limited to 'libopie2/opiecore/ofilenotify.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiecore/ofilenotify.cpp159
1 files changed, 159 insertions, 0 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 @@
1/*
2                This file is part of the Opie Project
3 =. Copyright (C) 2004 Michael 'Mickey' Lauer <mickey@Vanille.de>
4 .=l. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5          .>+-=
6_;:,     .>    :=|. This program is free software; you can
7.> <`_,   >  .   <= redistribute it and/or modify it under
8:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
9.="- .-=="i,     .._ License as published by the Free Software
10- .   .-<_>     .<> Foundation; either version 2 of the License,
11    ._= =}       : or (at your option) any later version.
12   .%`+i>       _;_.
13   .i_,=:_.      -<s. This program is distributed in the hope that
14    +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
15   : ..    .:,     . . . without even the implied warranty of
16   =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
17 _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
18..}^=.=       =       ; Library General Public License for more
19++=   -.     .`     .: details.
20:     =  ...= . :.=-
21-.   .:....=;==+<; You should have received a copy of the GNU
22 -_. . .   )=.  = Library General Public License along with
23   --        :-=` this library; see the file COPYING.LIB.
24 If not, write to the Free Software Foundation,
25 Inc., 59 Temple Place - Suite 330,
26 Boston, MA 02111-1307, USA.
27*/
28
29#include "ofilenotify.h"
30using namespace Opie::Core;
31
32/* OPIE */
33
34/* QT */
35#include <qsignal.h>
36#include <qintdict.h>
37#include <qdir.h>
38
39/* STD */
40#include <sys/types.h>
41#include <sys/stat.h>
42#include <fcntl.h>
43#include <string.h>
44#include <errno.h>
45
46namespace Opie {
47namespace Core {
48
49class OFileNotification
50{
51 public:
52 OFileNotification( QObject* receiver, const char* member, OFileNotificationType type ) : _type( type )
53 {
54 _signal.connect( receiver, member );
55 }
56 ~OFileNotification()
57 {
58 }
59
60 void activate()
61 {
62 _signal.activate();
63 }
64
65 OFileNotificationType type()
66 {
67 return _type;
68 }
69
70 private:
71 OFileNotificationType _type;
72 QSignal _signal;
73};
74
75
76static QIntDict<OFileNotification> notification_list;
77
78
79void OFileNotifier::singleShot( const QString& path, QObject* receiver, const char* member, OFileNotificationType type )
80{
81 int fd = ::open( (const char*) path, O_RDONLY );
82 if ( fd != -1 )
83 {
84 if ( notification_list.isEmpty() )
85 {
86 OFileNotifier::registerSignalHandler();
87 }
88 int result = ::fcntl( fd, F_SETSIG, SIGRTMIN );
89 if ( result == -1 )
90 {
91 qWarning( "OFileNotifier::singleShot(): Can't subscribe to '%s': %s.", (const char*) path, strerror( errno ) );
92 return;
93 }
94 result = ::fcntl( fd, F_NOTIFY, type );
95 if ( result == -1 )
96 {
97 qWarning( "OFileNotifier::singleShot(): Can't subscribe to '%s': %s.", (const char*) path, strerror( errno ) );
98 return;
99 }
100 qDebug( "OFileNotifier::singleShot(): Subscribed for changes to %s (fd = %d)", (const char*) path, fd );
101 notification_list.insert( fd, new OFileNotification( receiver, member, type ) );
102 }
103 else
104 {
105 qWarning( "OFileNotifier::singleShot(): Error with path '%s': %s.", (const char*) path, strerror( errno ) );
106 }
107}
108
109
110void OFileNotifier::__signalHandler( int sig, siginfo_t *si, void *data )
111{
112 qWarning( "OFileNotifier::__signalHandler(): reached." );
113 int fd = si->si_fd;
114 OFileNotification* fn = notification_list[fd];
115 if ( fn )
116 {
117 fn->activate();
118 #if 1
119 if ( !(fn->type() & Multi) )
120 {
121 qDebug( "OFileNotifier::__signalHandler(): '%d' was singleShot. Removing from list.", fd );
122 notification_list.remove( fd );
123 if ( notification_list.isEmpty() )
124 {
125 OFileNotifier::unregisterSignalHandler();
126 }
127 }
128 #endif
129 }
130 else
131 {
132 qWarning( "OFileNotifier::__signalHandler(): D'oh! Called without fd in notification_list. Race condition?" );
133 }
134}
135
136
137void OFileNotifier::registerSignalHandler()
138{
139 struct sigaction act;
140 act.sa_sigaction = OFileNotifier::__signalHandler;
141 ::sigemptyset( &act.sa_mask );
142 act.sa_flags = SA_SIGINFO;
143 ::sigaction( SIGRTMIN, &act, NULL );
144 qDebug( "OFileNotifier::registerSignalHandler(): done" );
145}
146
147
148void OFileNotifier::unregisterSignalHandler()
149{
150 struct sigaction act;
151 act.sa_sigaction = ( void (*)(int, siginfo_t*, void*) ) SIG_DFL;
152 sigemptyset( &act.sa_mask );
153 ::sigaction( SIGRTMIN, &act, NULL );
154 qDebug( "OFileNotifier::unregisterSignalHandler(): done" );
155}
156
157
158}
159}