author | ulf69 <ulf69> | 2004-06-30 21:52:47 (UTC) |
---|---|---|
committer | ulf69 <ulf69> | 2004-06-30 21:52:47 (UTC) |
commit | b8957d8d6437880355312cb008addceac66e9eb2 (patch) (unidiff) | |
tree | b0b65cc826e57e2466f7240ca53f703b3cf6b333 | |
parent | 294b21a5360fdffec72c73bd2513837f14271a01 (diff) | |
download | kdepimpi-b8957d8d6437880355312cb008addceac66e9eb2.zip kdepimpi-b8957d8d6437880355312cb008addceac66e9eb2.tar.gz kdepimpi-b8957d8d6437880355312cb008addceac66e9eb2.tar.bz2 |
added debug information in case of errors
-rw-r--r-- | microkde/kdecore/klibloader.cpp | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/microkde/kdecore/klibloader.cpp b/microkde/kdecore/klibloader.cpp index 130cc7c..c07d50f 100644 --- a/microkde/kdecore/klibloader.cpp +++ b/microkde/kdecore/klibloader.cpp | |||
@@ -1,605 +1,612 @@ | |||
1 | /* This file is part of the KDE libraries | 1 | /* This file is part of the KDE libraries |
2 | Copyright (C) 1999 Torben Weis <weis@kde.org> | 2 | Copyright (C) 1999 Torben Weis <weis@kde.org> |
3 | Copyright (C) 2000 Michael Matz <matz@kde.org> | 3 | Copyright (C) 2000 Michael Matz <matz@kde.org> |
4 | 4 | ||
5 | This library is free software; you can redistribute it and/or | 5 | This library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Library General Public | 6 | modify it under the terms of the GNU Library General Public |
7 | License version 2 as published by the Free Software Foundation. | 7 | License version 2 as published by the Free Software Foundation. |
8 | 8 | ||
9 | This library is distributed in the hope that it will be useful, | 9 | This library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | Library General Public License for more details. | 12 | Library General Public License for more details. |
13 | 13 | ||
14 | You should have received a copy of the GNU Library General Public License | 14 | You should have received a copy of the GNU Library General Public License |
15 | along with this library; see the file COPYING.LIB. If not, write to | 15 | along with this library; see the file COPYING.LIB. If not, write to |
16 | the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 16 | the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
17 | Boston, MA 02111-1307, USA. | 17 | Boston, MA 02111-1307, USA. |
18 | */ | 18 | */ |
19 | //US #include <config.h> | 19 | //US #include <config.h> |
20 | #include <qclipboard.h> | 20 | #include <qclipboard.h> |
21 | #include <qfile.h> | 21 | #include <qfile.h> |
22 | #include <qtimer.h> | 22 | #include <qtimer.h> |
23 | #include <qobjectdict.h> | 23 | #include <qobjectdict.h> |
24 | #include <qwidgetlist.h> | 24 | #include <qwidgetlist.h> |
25 | #include <qwidget.h> | 25 | #include <qwidget.h> |
26 | 26 | ||
27 | #include "kapplication.h" | 27 | #include "kapplication.h" |
28 | #include "klibloader.h" | 28 | #include "klibloader.h" |
29 | #include "kstandarddirs.h" | 29 | #include "kstandarddirs.h" |
30 | #include "kdebug.h" | 30 | #include "kdebug.h" |
31 | #include "klocale.h" | 31 | #include "klocale.h" |
32 | 32 | ||
33 | //US #include "ltdl.h" | 33 | /*US |
34 | #ifndef NDEBUG | ||
35 | #include "ltdl.h" | ||
36 | #endif | ||
37 | */ | ||
34 | 38 | ||
35 | //US do everything through qlibrary | 39 | //US do everything through qlibrary |
36 | #ifndef DESKTOP_VERSION | 40 | #ifndef DESKTOP_VERSION |
37 | #include <qpe/qpeapplication.h> | 41 | #include <qpe/qpeapplication.h> |
38 | #include <qtopia/qlibrary.h> | 42 | #include <qtopia/qlibrary.h> |
39 | #endif | 43 | #endif |
40 | 44 | ||
41 | /*US | 45 | /*US |
42 | #ifdef Q_WS_X11 | 46 | #ifdef Q_WS_X11 |
43 | #include <X11/Xlib.h> | 47 | #include <X11/Xlib.h> |
44 | #include <X11/Xatom.h> | 48 | #include <X11/Xatom.h> |
45 | #endif | 49 | #endif |
46 | */ | 50 | */ |
47 | template class QAsciiDict<KLibrary>; | 51 | template class QAsciiDict<KLibrary>; |
48 | 52 | ||
49 | #include <stdlib.h> //getenv | 53 | #include <stdlib.h> //getenv |
50 | 54 | ||
51 | /*US | 55 | /*US |
52 | #if HAVE_DLFCN_H | 56 | #if HAVE_DLFCN_H |
53 | # include <dlfcn.h> | 57 | # include <dlfcn.h> |
54 | #endif | 58 | #endif |
55 | 59 | ||
56 | #ifdef RTLD_GLOBAL | 60 | #ifdef RTLD_GLOBAL |
57 | # define LT_GLOBAL RTLD_GLOBAL | 61 | # define LT_GLOBAL RTLD_GLOBAL |
58 | #else | 62 | #else |
59 | # ifdef DL_GLOBAL | 63 | # ifdef DL_GLOBAL |
60 | # define LT_GLOBAL DL_GLOBAL | 64 | # define LT_GLOBAL DL_GLOBAL |
61 | # endif | 65 | # endif |
62 | #endif | 66 | #endif |
63 | #ifndef LT_GLOBAL | 67 | #ifndef LT_GLOBAL |
64 | # define LT_GLOBAL 0 | 68 | # define LT_GLOBAL 0 |
65 | #endif | 69 | #endif |
66 | */ | 70 | */ |
67 | 71 | ||
68 | /*US | 72 | /*US |
69 | extern "C" { | 73 | extern "C" { |
70 | extern int lt_dlopen_flag; | 74 | extern int lt_dlopen_flag; |
71 | } | 75 | } |
72 | */ | 76 | */ |
73 | 77 | ||
74 | KLibFactory::KLibFactory( QObject* parent, const char* name ) | 78 | KLibFactory::KLibFactory( QObject* parent, const char* name ) |
75 | : QObject( parent, name ) | 79 | : QObject( parent, name ) |
76 | { | 80 | { |
77 | } | 81 | } |
78 | 82 | ||
79 | KLibFactory::~KLibFactory() | 83 | KLibFactory::~KLibFactory() |
80 | { | 84 | { |
81 | // kdDebug(150) << "Deleting KLibFactory " << this << endl; | 85 | // kdDebug(150) << "Deleting KLibFactory " << this << endl; |
82 | } | 86 | } |
83 | 87 | ||
84 | QObject* KLibFactory::create( QObject* parent, const char* name, const char* classname, const QStringList &args ) | 88 | QObject* KLibFactory::create( QObject* parent, const char* name, const char* classname, const QStringList &args ) |
85 | { | 89 | { |
86 | QObject* obj = createObject( parent, name, classname, args ); | 90 | QObject* obj = createObject( parent, name, classname, args ); |
87 | if ( obj ) | 91 | if ( obj ) |
88 | emit objectCreated( obj ); | 92 | emit objectCreated( obj ); |
89 | return obj; | 93 | return obj; |
90 | } | 94 | } |
91 | 95 | ||
92 | 96 | ||
93 | QObject* KLibFactory::createObject( QObject*, const char*, const char*, const QStringList &) | 97 | QObject* KLibFactory::createObject( QObject*, const char*, const char*, const QStringList &) |
94 | { | 98 | { |
95 | return 0; | 99 | return 0; |
96 | } | 100 | } |
97 | 101 | ||
98 | 102 | ||
99 | // ----------------------------------------------- | 103 | // ----------------------------------------------- |
100 | 104 | ||
101 | //US KLibrary::KLibrary( const QString& libname, const QString& filename, void * handle ) | 105 | //US KLibrary::KLibrary( const QString& libname, const QString& filename, void * handle ) |
102 | KLibrary::KLibrary( const QString& libname, const QString& filename, QLibrary* handle ) | 106 | KLibrary::KLibrary( const QString& libname, const QString& filename, QLibrary* handle ) |
103 | { | 107 | { |
104 | /* Make sure, we have a KLibLoader */ | 108 | /* Make sure, we have a KLibLoader */ |
105 | (void) KLibLoader::self(); | 109 | (void) KLibLoader::self(); |
106 | m_libname = libname; | 110 | m_libname = libname; |
107 | m_filename = filename; | 111 | m_filename = filename; |
108 | m_handle = handle; | 112 | m_handle = handle; |
109 | m_factory = 0; | 113 | m_factory = 0; |
110 | m_timer = 0; | 114 | m_timer = 0; |
111 | } | 115 | } |
112 | 116 | ||
113 | KLibrary::~KLibrary() | 117 | KLibrary::~KLibrary() |
114 | { | 118 | { |
115 | // kdDebug(150) << "Deleting KLibrary " << this << " " << m_libname << endl; | 119 | // kdDebug(150) << "Deleting KLibrary " << this << " " << m_libname << endl; |
116 | if ( m_timer && m_timer->isActive() ) | 120 | if ( m_timer && m_timer->isActive() ) |
117 | m_timer->stop(); | 121 | m_timer->stop(); |
118 | 122 | ||
119 | // If any object is remaining, delete | 123 | // If any object is remaining, delete |
120 | if ( m_objs.count() > 0 ) | 124 | if ( m_objs.count() > 0 ) |
121 | { | 125 | { |
122 | QPtrListIterator<QObject> it( m_objs ); | 126 | QPtrListIterator<QObject> it( m_objs ); |
123 | for ( ; it.current() ; ++it ) | 127 | for ( ; it.current() ; ++it ) |
124 | { | 128 | { |
125 | kdDebug(150) << "Factory still has object " << it.current() << " " << it.current()->name () << " Library = " << m_libname << endl; | 129 | kdDebug(150) << "Factory still has object " << it.current() << " " << it.current()->name () << " Library = " << m_libname << endl; |
126 | disconnect( it.current(), SIGNAL( destroyed() ), | 130 | disconnect( it.current(), SIGNAL( destroyed() ), |
127 | this, SLOT( slotObjectDestroyed() ) ); | 131 | this, SLOT( slotObjectDestroyed() ) ); |
128 | } | 132 | } |
129 | m_objs.setAutoDelete(true); | 133 | m_objs.setAutoDelete(true); |
130 | m_objs.clear(); | 134 | m_objs.clear(); |
131 | } | 135 | } |
132 | 136 | ||
133 | if ( m_factory ) { | 137 | if ( m_factory ) { |
134 | //kdDebug(150) << " ... deleting the factory " << m_factory << endl; | 138 | //kdDebug(150) << " ... deleting the factory " << m_factory << endl; |
135 | delete m_factory; | 139 | delete m_factory; |
136 | } | 140 | } |
137 | } | 141 | } |
138 | 142 | ||
139 | QString KLibrary::name() const | 143 | QString KLibrary::name() const |
140 | { | 144 | { |
141 | return m_libname; | 145 | return m_libname; |
142 | } | 146 | } |
143 | 147 | ||
144 | QString KLibrary::fileName() const | 148 | QString KLibrary::fileName() const |
145 | { | 149 | { |
146 | return m_filename; | 150 | return m_filename; |
147 | } | 151 | } |
148 | 152 | ||
149 | KLibFactory* KLibrary::factory() | 153 | KLibFactory* KLibrary::factory() |
150 | { | 154 | { |
151 | if ( m_factory ) | 155 | if ( m_factory ) |
152 | return m_factory; | 156 | return m_factory; |
153 | 157 | ||
154 | QCString symname; | 158 | QCString symname; |
155 | symname.sprintf("init_%s", name().latin1() ); | 159 | symname.sprintf("init_%s", name().latin1() ); |
156 | 160 | ||
157 | void* sym = symbol( symname ); | 161 | void* sym = symbol( symname ); |
158 | if ( !sym ) | 162 | if ( !sym ) |
159 | { | 163 | { |
160 | qDebug("KLibrary: The library %s does not offer an %s function", name().latin1(), symname.data()); | 164 | qDebug("KLibrary: The library %s does not offer an %s function", name().latin1(), symname.data()); |
165 | #ifndef NDEBUG | ||
166 | //US qDebug("KLibrary: errorcode: %s", lt_dlerror()); | ||
167 | #endif | ||
161 | kdWarning(150) << "KLibrary: The library " << name().latin1() << " does not offer an init_" << name().latin1() << " function" << endl; | 168 | kdWarning(150) << "KLibrary: The library " << name().latin1() << " does not offer an init_" << name().latin1() << " function" << endl; |
162 | return 0; | 169 | return 0; |
163 | } | 170 | } |
164 | 171 | ||
165 | typedef KLibFactory* (*t_func)(); | 172 | typedef KLibFactory* (*t_func)(); |
166 | t_func func = (t_func)sym; | 173 | t_func func = (t_func)sym; |
167 | m_factory = func(); | 174 | m_factory = func(); |
168 | 175 | ||
169 | if( !m_factory ) | 176 | if( !m_factory ) |
170 | { | 177 | { |
171 | kdWarning(150) << "KLibrary: The library " << name() << " does not offer a KDE compatible factory" << endl; | 178 | kdWarning(150) << "KLibrary: The library " << name() << " does not offer a KDE compatible factory" << endl; |
172 | return 0; | 179 | return 0; |
173 | } | 180 | } |
174 | 181 | ||
175 | connect( m_factory, SIGNAL( objectCreated( QObject * ) ), | 182 | connect( m_factory, SIGNAL( objectCreated( QObject * ) ), |
176 | this, SLOT( slotObjectCreated( QObject * ) ) ); | 183 | this, SLOT( slotObjectCreated( QObject * ) ) ); |
177 | 184 | ||
178 | return m_factory; | 185 | return m_factory; |
179 | } | 186 | } |
180 | 187 | ||
181 | void* KLibrary::symbol( const char* symname ) const | 188 | void* KLibrary::symbol( const char* symname ) const |
182 | { | 189 | { |
183 | //US void* sym = lt_dlsym( (lt_dlhandle) m_handle, symname ); | 190 | //US void* sym = lt_dlsym( (lt_dlhandle) m_handle, symname ); |
184 | void* sym = m_handle->resolve( symname ); | 191 | void* sym = m_handle->resolve( symname ); |
185 | if ( !sym ) | 192 | if ( !sym ) |
186 | { | 193 | { |
187 | //US kdWarning(150) << "KLibrary: " << lt_dlerror() << endl; | 194 | //US kdWarning(150) << "KLibrary: " << lt_dlerror() << endl; |
188 | kdWarning(150) << "KLibrary: " << m_libname << ", symbol:" << symname << " not found " << endl; | 195 | kdWarning(150) << "KLibrary: " << m_libname << ", symbol:" << symname << " not found " << endl; |
189 | return 0; | 196 | return 0; |
190 | } | 197 | } |
191 | 198 | ||
192 | return sym; | 199 | return sym; |
193 | } | 200 | } |
194 | 201 | ||
195 | bool KLibrary::hasSymbol( const char* symname ) const | 202 | bool KLibrary::hasSymbol( const char* symname ) const |
196 | { | 203 | { |
197 | //US void* sym = lt_dlsym( (lt_dlhandle) m_handle, symname ); | 204 | //US void* sym = lt_dlsym( (lt_dlhandle) m_handle, symname ); |
198 | void* sym = m_handle->resolve( symname ); | 205 | void* sym = m_handle->resolve( symname ); |
199 | return (sym != 0L ); | 206 | return (sym != 0L ); |
200 | } | 207 | } |
201 | 208 | ||
202 | void KLibrary::unload() const | 209 | void KLibrary::unload() const |
203 | { | 210 | { |
204 | if (KLibLoader::s_self) | 211 | if (KLibLoader::s_self) |
205 | KLibLoader::s_self->unloadLibrary(QFile::encodeName(name())); | 212 | KLibLoader::s_self->unloadLibrary(QFile::encodeName(name())); |
206 | } | 213 | } |
207 | 214 | ||
208 | void KLibrary::slotObjectCreated( QObject *obj ) | 215 | void KLibrary::slotObjectCreated( QObject *obj ) |
209 | { | 216 | { |
210 | if ( !obj ) | 217 | if ( !obj ) |
211 | return; | 218 | return; |
212 | 219 | ||
213 | if ( m_timer && m_timer->isActive() ) | 220 | if ( m_timer && m_timer->isActive() ) |
214 | m_timer->stop(); | 221 | m_timer->stop(); |
215 | 222 | ||
216 | if ( m_objs.containsRef( obj ) ) | 223 | if ( m_objs.containsRef( obj ) ) |
217 | return; // we know this object already | 224 | return; // we know this object already |
218 | 225 | ||
219 | connect( obj, SIGNAL( destroyed() ), | 226 | connect( obj, SIGNAL( destroyed() ), |
220 | this, SLOT( slotObjectDestroyed() ) ); | 227 | this, SLOT( slotObjectDestroyed() ) ); |
221 | 228 | ||
222 | m_objs.append( obj ); | 229 | m_objs.append( obj ); |
223 | } | 230 | } |
224 | 231 | ||
225 | void KLibrary::slotObjectDestroyed() | 232 | void KLibrary::slotObjectDestroyed() |
226 | { | 233 | { |
227 | m_objs.removeRef( sender() ); | 234 | m_objs.removeRef( sender() ); |
228 | 235 | ||
229 | if ( m_objs.count() == 0 ) | 236 | if ( m_objs.count() == 0 ) |
230 | { | 237 | { |
231 | // kdDebug(150) << "KLibrary: shutdown timer for " << name() << " started!" | 238 | // kdDebug(150) << "KLibrary: shutdown timer for " << name() << " started!" |
232 | // << endl; | 239 | // << endl; |
233 | 240 | ||
234 | if ( !m_timer ) | 241 | if ( !m_timer ) |
235 | { | 242 | { |
236 | m_timer = new QTimer( this, "klibrary_shutdown_timer" ); | 243 | m_timer = new QTimer( this, "klibrary_shutdown_timer" ); |
237 | connect( m_timer, SIGNAL( timeout() ), | 244 | connect( m_timer, SIGNAL( timeout() ), |
238 | this, SLOT( slotTimeout() ) ); | 245 | this, SLOT( slotTimeout() ) ); |
239 | } | 246 | } |
240 | 247 | ||
241 | // as long as it's not stable make the timeout short, for debugging | 248 | // as long as it's not stable make the timeout short, for debugging |
242 | // pleasure (matz) | 249 | // pleasure (matz) |
243 | //m_timer->start( 1000*60, true ); | 250 | //m_timer->start( 1000*60, true ); |
244 | m_timer->start( 1000*10, true ); | 251 | m_timer->start( 1000*10, true ); |
245 | } | 252 | } |
246 | } | 253 | } |
247 | 254 | ||
248 | void KLibrary::slotTimeout() | 255 | void KLibrary::slotTimeout() |
249 | { | 256 | { |
250 | if ( m_objs.count() != 0 ) | 257 | if ( m_objs.count() != 0 ) |
251 | return; | 258 | return; |
252 | 259 | ||
253 | /* Don't go through KLibLoader::unloadLibrary(), because that uses the | 260 | /* Don't go through KLibLoader::unloadLibrary(), because that uses the |
254 | ref counter, but this timeout means to unconditionally close this library | 261 | ref counter, but this timeout means to unconditionally close this library |
255 | The destroyed() signal will take care to remove us from all lists. | 262 | The destroyed() signal will take care to remove us from all lists. |
256 | */ | 263 | */ |
257 | delete this; | 264 | delete this; |
258 | } | 265 | } |
259 | 266 | ||
260 | // ------------------------------------------------- | 267 | // ------------------------------------------------- |
261 | 268 | ||
262 | /* This helper class is needed, because KLibraries can go away without | 269 | /* This helper class is needed, because KLibraries can go away without |
263 | being unloaded. So we need some info about KLibraries even after its | 270 | being unloaded. So we need some info about KLibraries even after its |
264 | death. */ | 271 | death. */ |
265 | class KLibWrapPrivate | 272 | class KLibWrapPrivate |
266 | { | 273 | { |
267 | public: | 274 | public: |
268 | //US KLibWrapPrivate(KLibrary *l, lt_dlhandle h); | 275 | //US KLibWrapPrivate(KLibrary *l, lt_dlhandle h); |
269 | KLibWrapPrivate(KLibrary *l, QLibrary* h); | 276 | KLibWrapPrivate(KLibrary *l, QLibrary* h); |
270 | 277 | ||
271 | KLibrary *lib; | 278 | KLibrary *lib; |
272 | enum {UNKNOWN, UNLOAD, DONT_UNLOAD} unload_mode; | 279 | enum {UNKNOWN, UNLOAD, DONT_UNLOAD} unload_mode; |
273 | int ref_count; | 280 | int ref_count; |
274 | //US lt_dlhandle handle; | 281 | //US lt_dlhandle handle; |
275 | QLibrary *handle; | 282 | QLibrary *handle; |
276 | QString name; | 283 | QString name; |
277 | QString filename; | 284 | QString filename; |
278 | }; | 285 | }; |
279 | 286 | ||
280 | //US KLibWrapPrivate::KLibWrapPrivate(KLibrary *l, lt_dlhandle h) | 287 | //US KLibWrapPrivate::KLibWrapPrivate(KLibrary *l, lt_dlhandle h) |
281 | KLibWrapPrivate::KLibWrapPrivate(KLibrary *l, QLibrary* h) | 288 | KLibWrapPrivate::KLibWrapPrivate(KLibrary *l, QLibrary* h) |
282 | : lib(l), ref_count(1), handle(h), name(l->name()), filename(l->fileName()) | 289 | : lib(l), ref_count(1), handle(h), name(l->name()), filename(l->fileName()) |
283 | { | 290 | { |
284 | unload_mode = UNKNOWN; | 291 | unload_mode = UNKNOWN; |
285 | /*US | 292 | /*US |
286 | if (lt_dlsym(handle, "__kde_do_not_unload") != 0) { | 293 | if (lt_dlsym(handle, "__kde_do_not_unload") != 0) { |
287 | // kdDebug(150) << "Will not unload " << name << endl; | 294 | // kdDebug(150) << "Will not unload " << name << endl; |
288 | unload_mode = DONT_UNLOAD; | 295 | unload_mode = DONT_UNLOAD; |
289 | } else if (lt_dlsym(handle, "__kde_do_unload") != 0) { | 296 | } else if (lt_dlsym(handle, "__kde_do_unload") != 0) { |
290 | unload_mode = UNLOAD; | 297 | unload_mode = UNLOAD; |
291 | } | 298 | } |
292 | */ | 299 | */ |
293 | //US use instead: | 300 | //US use instead: |
294 | if (h->resolve("__kde_do_not_unload") != 0) { | 301 | if (h->resolve("__kde_do_not_unload") != 0) { |
295 | // kdDebug(150) << "Will not unload " << name << endl; | 302 | // kdDebug(150) << "Will not unload " << name << endl; |
296 | unload_mode = DONT_UNLOAD; | 303 | unload_mode = DONT_UNLOAD; |
297 | } else if (h->resolve("__kde_do_unload") != 0) { | 304 | } else if (h->resolve("__kde_do_unload") != 0) { |
298 | unload_mode = UNLOAD; | 305 | unload_mode = UNLOAD; |
299 | } | 306 | } |
300 | } | 307 | } |
301 | 308 | ||
302 | class KLibLoaderPrivate | 309 | class KLibLoaderPrivate |
303 | { | 310 | { |
304 | public: | 311 | public: |
305 | QPtrList<KLibWrapPrivate> loaded_stack; | 312 | QPtrList<KLibWrapPrivate> loaded_stack; |
306 | QPtrList<KLibWrapPrivate> pending_close; | 313 | QPtrList<KLibWrapPrivate> pending_close; |
307 | enum {UNKNOWN, UNLOAD, DONT_UNLOAD} unload_mode; | 314 | enum {UNKNOWN, UNLOAD, DONT_UNLOAD} unload_mode; |
308 | 315 | ||
309 | QString errorMessage; | 316 | QString errorMessage; |
310 | }; | 317 | }; |
311 | 318 | ||
312 | KLibLoader* KLibLoader::s_self = 0; | 319 | KLibLoader* KLibLoader::s_self = 0; |
313 | 320 | ||
314 | KLibLoader* KLibLoader::self() | 321 | KLibLoader* KLibLoader::self() |
315 | { | 322 | { |
316 | if ( !s_self ) | 323 | if ( !s_self ) |
317 | s_self = new KLibLoader; | 324 | s_self = new KLibLoader; |
318 | return s_self; | 325 | return s_self; |
319 | } | 326 | } |
320 | 327 | ||
321 | void KLibLoader::cleanUp() | 328 | void KLibLoader::cleanUp() |
322 | { | 329 | { |
323 | if ( !s_self ) | 330 | if ( !s_self ) |
324 | return; | 331 | return; |
325 | 332 | ||
326 | delete s_self; | 333 | delete s_self; |
327 | s_self = 0; | 334 | s_self = 0; |
328 | } | 335 | } |
329 | 336 | ||
330 | KLibLoader::KLibLoader( QObject* parent, const char* name ) | 337 | KLibLoader::KLibLoader( QObject* parent, const char* name ) |
331 | : QObject( parent, name ) | 338 | : QObject( parent, name ) |
332 | { | 339 | { |
333 | s_self = this; | 340 | s_self = this; |
334 | d = new KLibLoaderPrivate; | 341 | d = new KLibLoaderPrivate; |
335 | //US lt_dlinit(); | 342 | //US lt_dlinit(); |
336 | d->unload_mode = KLibLoaderPrivate::UNKNOWN; | 343 | d->unload_mode = KLibLoaderPrivate::UNKNOWN; |
337 | if (getenv("KDE_NOUNLOAD") != 0) | 344 | if (getenv("KDE_NOUNLOAD") != 0) |
338 | d->unload_mode = KLibLoaderPrivate::DONT_UNLOAD; | 345 | d->unload_mode = KLibLoaderPrivate::DONT_UNLOAD; |
339 | else if (getenv("KDE_DOUNLOAD") != 0) | 346 | else if (getenv("KDE_DOUNLOAD") != 0) |
340 | d->unload_mode = KLibLoaderPrivate::UNLOAD; | 347 | d->unload_mode = KLibLoaderPrivate::UNLOAD; |
341 | d->loaded_stack.setAutoDelete( true ); | 348 | d->loaded_stack.setAutoDelete( true ); |
342 | } | 349 | } |
343 | 350 | ||
344 | KLibLoader::~KLibLoader() | 351 | KLibLoader::~KLibLoader() |
345 | { | 352 | { |
346 | // kdDebug(150) << "Deleting KLibLoader " << this << " " << name() << endl; | 353 | // kdDebug(150) << "Deleting KLibLoader " << this << " " << name() << endl; |
347 | 354 | ||
348 | QAsciiDictIterator<KLibWrapPrivate> it( m_libs ); | 355 | QAsciiDictIterator<KLibWrapPrivate> it( m_libs ); |
349 | for (; it.current(); ++it ) | 356 | for (; it.current(); ++it ) |
350 | { | 357 | { |
351 | kdDebug(150) << "The KLibLoader contains the library " << it.current()->name | 358 | kdDebug(150) << "The KLibLoader contains the library " << it.current()->name |
352 | << " (" << it.current()->lib << ")" << endl; | 359 | << " (" << it.current()->lib << ")" << endl; |
353 | d->pending_close.append(it.current()); | 360 | d->pending_close.append(it.current()); |
354 | } | 361 | } |
355 | 362 | ||
356 | close_pending(0); | 363 | close_pending(0); |
357 | 364 | ||
358 | delete d; | 365 | delete d; |
359 | } | 366 | } |
360 | 367 | ||
361 | //static | 368 | //static |
362 | QString KLibLoader::findLibrary( const char * name/*US , const KInstance * instance*/ ) | 369 | QString KLibLoader::findLibrary( const char * name/*US , const KInstance * instance*/ ) |
363 | { | 370 | { |
364 | QCString libname( name ); | 371 | QCString libname( name ); |
365 | 372 | ||
366 | // only append ".la" if there is no extension | 373 | // only append ".la" if there is no extension |
367 | // this allows to load non-libtool libraries as well | 374 | // this allows to load non-libtool libraries as well |
368 | // (mhk, 20000228) | 375 | // (mhk, 20000228) |
369 | int pos = libname.findRev('/'); | 376 | int pos = libname.findRev('/'); |
370 | if (pos < 0) | 377 | if (pos < 0) |
371 | pos = 0; | 378 | pos = 0; |
372 | /*US | 379 | /*US |
373 | if (libname.find('.', pos) < 0) { | 380 | if (libname.find('.', pos) < 0) { |
374 | libname += ".la"; | 381 | libname += ".la"; |
375 | } | 382 | } |
376 | */ | 383 | */ |
377 | //US in the microedition we work only with shared libraries. | 384 | //US in the microedition we work only with shared libraries. |
378 | if (libname.find('.', pos) < 0) { | 385 | if (libname.find('.', pos) < 0) { |
379 | libname += ".so"; | 386 | libname += ".so"; |
380 | } | 387 | } |
381 | 388 | ||
382 | // only look up the file if it is not an absolute filename | 389 | // only look up the file if it is not an absolute filename |
383 | // (mhk, 20000228) | 390 | // (mhk, 20000228) |
384 | QString libfile; | 391 | QString libfile; |
385 | if (libname[0] == '/') | 392 | if (libname[0] == '/') |
386 | libfile = libname; | 393 | libfile = libname; |
387 | else | 394 | else |
388 | { | 395 | { |
389 | //US at this point the libname must exist as real filesname. No expansions will be made later | 396 | //US at this point the libname must exist as real filesname. No expansions will be made later |
390 | // in findResources. Because of that we prepend the lib prefix here to the name | 397 | // in findResources. Because of that we prepend the lib prefix here to the name |
391 | //US I add also the "lib" prefix. I do not how could this could have worked before without it? | 398 | //US I add also the "lib" prefix. I do not how could this could have worked before without it? |
392 | libname.insert(pos, "lib"); | 399 | libname.insert(pos, "lib"); |
393 | 400 | ||
394 | 401 | ||
395 | //US libfile = instance->dirs()->findResource( "module", libname ); | 402 | //US libfile = instance->dirs()->findResource( "module", libname ); |
396 | libfile = KGlobal::dirs()->findResource( "module", libname ); | 403 | libfile = KGlobal::dirs()->findResource( "module", libname ); |
397 | if ( libfile.isEmpty() ) | 404 | if ( libfile.isEmpty() ) |
398 | { | 405 | { |
399 | //US libfile = instance->dirs()->findResource( "lib", libname ); | 406 | //US libfile = instance->dirs()->findResource( "lib", libname ); |
400 | libfile = KGlobal::dirs()->findResource( "lib", libname ); | 407 | libfile = KGlobal::dirs()->findResource( "lib", libname ); |
401 | #ifndef NDEBUG | 408 | #ifndef NDEBUG |
402 | if ( !libfile.isEmpty() && libname.left(3) == "lib" ) // don't warn for kdeinit modules | 409 | if ( !libfile.isEmpty() && libname.left(3) == "lib" ) // don't warn for kdeinit modules |
403 | kdDebug(150) << "library " << libname << " not found under 'module' but under 'lib'" << endl; | 410 | kdDebug(150) << "library " << libname << " not found under 'module' but under 'lib'" << endl; |
404 | #endif | 411 | #endif |
405 | } | 412 | } |
406 | if ( libfile.isEmpty() ) | 413 | if ( libfile.isEmpty() ) |
407 | { | 414 | { |
408 | #ifndef NDEBUG | 415 | #ifndef NDEBUG |
409 | kdDebug(150) << "library=" << libname << ": No file names " << libname.data() << " found in paths." << endl; | 416 | kdDebug(150) << "library=" << libname << ": No file names " << libname.data() << " found in paths." << endl; |
410 | #endif | 417 | self()->d->errorMessage = i18n("Library files for \"%1\" not found in paths").arg(libname); |
411 | self()->d->errorMessage = i18n("Library files for \"%1\" not found in paths").arg(libname); | ||
412 | 418 | ||
413 | qDebug("KLibLoader::library could not find library: %s", libname.data()); | 419 | qDebug("KLibLoader::library could not find library: %s", libname.data()); |
420 | #endif | ||
414 | 421 | ||
415 | } | 422 | } |
416 | else | 423 | else |
417 | self()->d->errorMessage = QString::null; | 424 | self()->d->errorMessage = QString::null; |
418 | } | 425 | } |
419 | return libfile; | 426 | return libfile; |
420 | } | 427 | } |
421 | 428 | ||
422 | 429 | ||
423 | KLibrary* KLibLoader::globalLibrary( const char *name ) | 430 | KLibrary* KLibLoader::globalLibrary( const char *name ) |
424 | { | 431 | { |
425 | KLibrary *tmp; | 432 | KLibrary *tmp; |
426 | /*US | 433 | /*US |
427 | int olt_dlopen_flag = lt_dlopen_flag; | 434 | int olt_dlopen_flag = lt_dlopen_flag; |
428 | 435 | ||
429 | lt_dlopen_flag |= LT_GLOBAL; | 436 | lt_dlopen_flag |= LT_GLOBAL; |
430 | kdDebug(150) << "Loading the next library global with flag " | 437 | kdDebug(150) << "Loading the next library global with flag " |
431 | << lt_dlopen_flag | 438 | << lt_dlopen_flag |
432 | << "." << endl; | 439 | << "." << endl; |
433 | */ | 440 | */ |
434 | tmp = library(name); | 441 | tmp = library(name); |
435 | /*US | 442 | /*US |
436 | lt_dlopen_flag = olt_dlopen_flag; | 443 | lt_dlopen_flag = olt_dlopen_flag; |
437 | */ | 444 | */ |
438 | return tmp; | 445 | return tmp; |
439 | } | 446 | } |
440 | 447 | ||
441 | 448 | ||
442 | KLibrary* KLibLoader::library( const char *name ) | 449 | KLibrary* KLibLoader::library( const char *name ) |
443 | { | 450 | { |
444 | if (!name) | 451 | if (!name) |
445 | return 0; | 452 | return 0; |
446 | 453 | ||
447 | KLibWrapPrivate* wrap = m_libs[name]; | 454 | KLibWrapPrivate* wrap = m_libs[name]; |
448 | if (wrap) { | 455 | if (wrap) { |
449 | /* Nothing to do to load the library. */ | 456 | /* Nothing to do to load the library. */ |
450 | wrap->ref_count++; | 457 | wrap->ref_count++; |
451 | return wrap->lib; | 458 | return wrap->lib; |
452 | } | 459 | } |
453 | 460 | ||
454 | /* Test if this library was loaded at some time, but got | 461 | /* Test if this library was loaded at some time, but got |
455 | unloaded meanwhile, whithout being dlclose()'ed. */ | 462 | unloaded meanwhile, whithout being dlclose()'ed. */ |
456 | QPtrListIterator<KLibWrapPrivate> it(d->loaded_stack); | 463 | QPtrListIterator<KLibWrapPrivate> it(d->loaded_stack); |
457 | for (; it.current(); ++it) { | 464 | for (; it.current(); ++it) { |
458 | if (it.current()->name == name) | 465 | if (it.current()->name == name) |
459 | wrap = it.current(); | 466 | wrap = it.current(); |
460 | } | 467 | } |
461 | 468 | ||
462 | if (wrap) { | 469 | if (wrap) { |
463 | d->pending_close.removeRef(wrap); | 470 | d->pending_close.removeRef(wrap); |
464 | if (!wrap->lib) { | 471 | if (!wrap->lib) { |
465 | /* This lib only was in loaded_stack, but not in m_libs. */ | 472 | /* This lib only was in loaded_stack, but not in m_libs. */ |
466 | wrap->lib = new KLibrary( name, wrap->filename, wrap->handle ); | 473 | wrap->lib = new KLibrary( name, wrap->filename, wrap->handle ); |
467 | } | 474 | } |
468 | wrap->ref_count++; | 475 | wrap->ref_count++; |
469 | } else { | 476 | } else { |
470 | QString libfile = findLibrary( name ); | 477 | QString libfile = findLibrary( name ); |
471 | if ( libfile.isEmpty() ) | 478 | if ( libfile.isEmpty() ) |
472 | return 0; | 479 | return 0; |
473 | 480 | ||
474 | QLibrary *qlib = new QLibrary( libfile.latin1(), QLibrary::Immediately ); | 481 | QLibrary *qlib = new QLibrary( libfile.latin1(), QLibrary::Immediately ); |
475 | 482 | ||
476 | //US lt_dlhandle handle = lt_dlopen( libfile.latin1() ); | 483 | //US lt_dlhandle handle = lt_dlopen( libfile.latin1() ); |
477 | //US if ( !handle ) | 484 | //US if ( !handle ) |
478 | if ( !qlib ) | 485 | if ( !qlib ) |
479 | { | 486 | { |
480 | //US const char* errmsg = lt_dlerror(); | 487 | //US const char* errmsg = lt_dlerror(); |
481 | char* errmsg; | 488 | char* errmsg; |
482 | sprintf(errmsg, "KLibLoader::library could not load library: %s", libfile.latin1()); | 489 | sprintf(errmsg, "KLibLoader::library could not load library: %s", libfile.latin1()); |
483 | qDebug(errmsg); | 490 | qDebug(errmsg); |
484 | 491 | ||
485 | if(errmsg) | 492 | if(errmsg) |
486 | d->errorMessage = QString::fromLatin1(errmsg); | 493 | d->errorMessage = QString::fromLatin1(errmsg); |
487 | else | 494 | else |
488 | d->errorMessage = QString::null; | 495 | d->errorMessage = QString::null; |
489 | kdWarning(150) << "library=" << name << ": file=" << libfile << ": " << d->errorMessage << endl; | 496 | kdWarning(150) << "library=" << name << ": file=" << libfile << ": " << d->errorMessage << endl; |
490 | return 0; | 497 | return 0; |
491 | } | 498 | } |
492 | else | 499 | else |
493 | d->errorMessage = QString::null; | 500 | d->errorMessage = QString::null; |
494 | 501 | ||
495 | KLibrary *lib = new KLibrary( name, libfile, qlib ); | 502 | KLibrary *lib = new KLibrary( name, libfile, qlib ); |
496 | wrap = new KLibWrapPrivate(lib, qlib); | 503 | wrap = new KLibWrapPrivate(lib, qlib); |
497 | d->loaded_stack.prepend(wrap); | 504 | d->loaded_stack.prepend(wrap); |
498 | } | 505 | } |
499 | m_libs.insert( name, wrap ); | 506 | m_libs.insert( name, wrap ); |
500 | 507 | ||
501 | connect( wrap->lib, SIGNAL( destroyed() ), | 508 | connect( wrap->lib, SIGNAL( destroyed() ), |
502 | this, SLOT( slotLibraryDestroyed() ) ); | 509 | this, SLOT( slotLibraryDestroyed() ) ); |
503 | 510 | ||
504 | return wrap->lib; | 511 | return wrap->lib; |
505 | } | 512 | } |
506 | 513 | ||
507 | QString KLibLoader::lastErrorMessage() const | 514 | QString KLibLoader::lastErrorMessage() const |
508 | { | 515 | { |
509 | return d->errorMessage; | 516 | return d->errorMessage; |
510 | } | 517 | } |
511 | 518 | ||
512 | void KLibLoader::unloadLibrary( const char *libname ) | 519 | void KLibLoader::unloadLibrary( const char *libname ) |
513 | { | 520 | { |
514 | KLibWrapPrivate *wrap = m_libs[ libname ]; | 521 | KLibWrapPrivate *wrap = m_libs[ libname ]; |
515 | if (!wrap) | 522 | if (!wrap) |
516 | return; | 523 | return; |
517 | if (--wrap->ref_count) | 524 | if (--wrap->ref_count) |
518 | return; | 525 | return; |
519 | 526 | ||
520 | // kdDebug(150) << "closing library " << libname << endl; | 527 | // kdDebug(150) << "closing library " << libname << endl; |
521 | 528 | ||
522 | m_libs.remove( libname ); | 529 | m_libs.remove( libname ); |
523 | 530 | ||
524 | disconnect( wrap->lib, SIGNAL( destroyed() ), | 531 | disconnect( wrap->lib, SIGNAL( destroyed() ), |
525 | this, SLOT( slotLibraryDestroyed() ) ); | 532 | this, SLOT( slotLibraryDestroyed() ) ); |
526 | close_pending( wrap ); | 533 | close_pending( wrap ); |
527 | } | 534 | } |
528 | 535 | ||
529 | KLibFactory* KLibLoader::factory( const char* name ) | 536 | KLibFactory* KLibLoader::factory( const char* name ) |
530 | { | 537 | { |
531 | KLibrary* lib = library( name ); | 538 | KLibrary* lib = library( name ); |
532 | if ( !lib ) | 539 | if ( !lib ) |
533 | return 0; | 540 | return 0; |
534 | 541 | ||
535 | return lib->factory(); | 542 | return lib->factory(); |
536 | } | 543 | } |
537 | 544 | ||
538 | void KLibLoader::slotLibraryDestroyed() | 545 | void KLibLoader::slotLibraryDestroyed() |
539 | { | 546 | { |
540 | const KLibrary *lib = static_cast<const KLibrary *>( sender() ); | 547 | const KLibrary *lib = static_cast<const KLibrary *>( sender() ); |
541 | 548 | ||
542 | QAsciiDictIterator<KLibWrapPrivate> it( m_libs ); | 549 | QAsciiDictIterator<KLibWrapPrivate> it( m_libs ); |
543 | for (; it.current(); ++it ) | 550 | for (; it.current(); ++it ) |
544 | if ( it.current()->lib == lib ) | 551 | if ( it.current()->lib == lib ) |
545 | { | 552 | { |
546 | KLibWrapPrivate *wrap = it.current(); | 553 | KLibWrapPrivate *wrap = it.current(); |
547 | wrap->lib = 0; /* the KLibrary object is already away */ | 554 | wrap->lib = 0; /* the KLibrary object is already away */ |
548 | m_libs.remove( it.currentKey() ); | 555 | m_libs.remove( it.currentKey() ); |
549 | close_pending( wrap ); | 556 | close_pending( wrap ); |
550 | return; | 557 | return; |
551 | } | 558 | } |
552 | } | 559 | } |
553 | 560 | ||
554 | void KLibLoader::close_pending(KLibWrapPrivate *wrap) | 561 | void KLibLoader::close_pending(KLibWrapPrivate *wrap) |
555 | { | 562 | { |
556 | if (wrap && !d->pending_close.containsRef( wrap )) | 563 | if (wrap && !d->pending_close.containsRef( wrap )) |
557 | d->pending_close.append( wrap ); | 564 | d->pending_close.append( wrap ); |
558 | 565 | ||
559 | /* First delete all KLibrary objects in pending_close, but _don't_ unload | 566 | /* First delete all KLibrary objects in pending_close, but _don't_ unload |
560 | the DSO behind it. */ | 567 | the DSO behind it. */ |
561 | QPtrListIterator<KLibWrapPrivate> it(d->pending_close); | 568 | QPtrListIterator<KLibWrapPrivate> it(d->pending_close); |
562 | for (; it.current(); ++it) { | 569 | for (; it.current(); ++it) { |
563 | wrap = it.current(); | 570 | wrap = it.current(); |
564 | if (wrap->lib) { | 571 | if (wrap->lib) { |
565 | disconnect( wrap->lib, SIGNAL( destroyed() ), | 572 | disconnect( wrap->lib, SIGNAL( destroyed() ), |
566 | this, SLOT( slotLibraryDestroyed() ) ); | 573 | this, SLOT( slotLibraryDestroyed() ) ); |
567 | delete wrap->lib; | 574 | delete wrap->lib; |
568 | wrap->lib = 0; | 575 | wrap->lib = 0; |
569 | } | 576 | } |
570 | } | 577 | } |
571 | 578 | ||
572 | if (d->unload_mode == KLibLoaderPrivate::DONT_UNLOAD) return; | 579 | if (d->unload_mode == KLibLoaderPrivate::DONT_UNLOAD) return; |
573 | 580 | ||
574 | bool deleted_one = false; | 581 | bool deleted_one = false; |
575 | while ((wrap = d->loaded_stack.first())) { | 582 | while ((wrap = d->loaded_stack.first())) { |
576 | /* Let's first see, if we want to try to unload this lib. | 583 | /* Let's first see, if we want to try to unload this lib. |
577 | If the env. var KDE_DOUNLOAD is set, we try to unload every lib. | 584 | If the env. var KDE_DOUNLOAD is set, we try to unload every lib. |
578 | If not, we look at the lib itself, and unload it only, if it exports | 585 | If not, we look at the lib itself, and unload it only, if it exports |
579 | the symbol __kde_do_unload. */ | 586 | the symbol __kde_do_unload. */ |
580 | if (d->unload_mode != KLibLoaderPrivate::UNLOAD | 587 | if (d->unload_mode != KLibLoaderPrivate::UNLOAD |
581 | && wrap->unload_mode != KLibWrapPrivate::UNLOAD) | 588 | && wrap->unload_mode != KLibWrapPrivate::UNLOAD) |
582 | break; | 589 | break; |
583 | 590 | ||
584 | /* Now ensure, that the libs are only unloaded in the reverse direction | 591 | /* Now ensure, that the libs are only unloaded in the reverse direction |
585 | they were loaded. */ | 592 | they were loaded. */ |
586 | if (!d->pending_close.containsRef( wrap )) { | 593 | if (!d->pending_close.containsRef( wrap )) { |
587 | if (!deleted_one) | 594 | if (!deleted_one) |
588 | /* Only diagnose, if we really haven't deleted anything. */ | 595 | /* Only diagnose, if we really haven't deleted anything. */ |
589 | // kdDebug(150) << "try to dlclose " << wrap->name << ": not yet" << endl; | 596 | // kdDebug(150) << "try to dlclose " << wrap->name << ": not yet" << endl; |
590 | break; | 597 | break; |
591 | } | 598 | } |
592 | 599 | ||
593 | // kdDebug(150) << "try to dlclose " << wrap->name << ": yes, done." << endl; | 600 | // kdDebug(150) << "try to dlclose " << wrap->name << ": yes, done." << endl; |
594 | 601 | ||
595 | #ifndef Q_WS_QWS | 602 | #ifndef Q_WS_QWS |
596 | if ( !deleted_one ) { | 603 | if ( !deleted_one ) { |
597 | /* Only do the hack once in this loop. | 604 | /* Only do the hack once in this loop. |
598 | WABA: *HACK* | 605 | WABA: *HACK* |
599 | We need to make sure to clear the clipboard before unloading a DSO | 606 | We need to make sure to clear the clipboard before unloading a DSO |
600 | because the DSO could have defined an object derived from QMimeSource | 607 | because the DSO could have defined an object derived from QMimeSource |
601 | and placed that on the clipboard. */ | 608 | and placed that on the clipboard. */ |
602 | /*kapp->clipboard()->clear();*/ | 609 | /*kapp->clipboard()->clear();*/ |
603 | 610 | ||
604 | /* Well.. let's do something more subtle... convert the clipboard context | 611 | /* Well.. let's do something more subtle... convert the clipboard context |
605 | to text. That should be safe as it only uses objects defined by Qt. */ | 612 | to text. That should be safe as it only uses objects defined by Qt. */ |