summaryrefslogtreecommitdiffabout
authorulf69 <ulf69>2004-06-30 21:52:47 (UTC)
committer ulf69 <ulf69>2004-06-30 21:52:47 (UTC)
commitb8957d8d6437880355312cb008addceac66e9eb2 (patch) (unidiff)
treeb0b65cc826e57e2466f7240ca53f703b3cf6b333
parent294b21a5360fdffec72c73bd2513837f14271a01 (diff)
downloadkdepimpi-b8957d8d6437880355312cb008addceac66e9eb2.zip
kdepimpi-b8957d8d6437880355312cb008addceac66e9eb2.tar.gz
kdepimpi-b8957d8d6437880355312cb008addceac66e9eb2.tar.bz2
added debug information in case of errors
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--microkde/kdecore/klibloader.cpp17
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,640 +1,647 @@
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*/
47template class QAsciiDict<KLibrary>; 51template 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
69extern "C" { 73extern "C" {
70extern int lt_dlopen_flag; 74extern int lt_dlopen_flag;
71} 75}
72*/ 76*/
73 77
74KLibFactory::KLibFactory( QObject* parent, const char* name ) 78KLibFactory::KLibFactory( QObject* parent, const char* name )
75 : QObject( parent, name ) 79 : QObject( parent, name )
76{ 80{
77} 81}
78 82
79KLibFactory::~KLibFactory() 83KLibFactory::~KLibFactory()
80{ 84{
81// kdDebug(150) << "Deleting KLibFactory " << this << endl; 85// kdDebug(150) << "Deleting KLibFactory " << this << endl;
82} 86}
83 87
84QObject* KLibFactory::create( QObject* parent, const char* name, const char* classname, const QStringList &args ) 88QObject* 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
93QObject* KLibFactory::createObject( QObject*, const char*, const char*, const QStringList &) 97QObject* 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 )
102KLibrary::KLibrary( const QString& libname, const QString& filename, QLibrary* handle ) 106KLibrary::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
113KLibrary::~KLibrary() 117KLibrary::~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
139QString KLibrary::name() const 143QString KLibrary::name() const
140{ 144{
141 return m_libname; 145 return m_libname;
142} 146}
143 147
144QString KLibrary::fileName() const 148QString KLibrary::fileName() const
145{ 149{
146 return m_filename; 150 return m_filename;
147} 151}
148 152
149KLibFactory* KLibrary::factory() 153KLibFactory* 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
181void* KLibrary::symbol( const char* symname ) const 188void* 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
195bool KLibrary::hasSymbol( const char* symname ) const 202bool 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
202void KLibrary::unload() const 209void 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
208void KLibrary::slotObjectCreated( QObject *obj ) 215void 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
225void KLibrary::slotObjectDestroyed() 232void 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
248void KLibrary::slotTimeout() 255void 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. */
265class KLibWrapPrivate 272class KLibWrapPrivate
266{ 273{
267public: 274public:
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)
281KLibWrapPrivate::KLibWrapPrivate(KLibrary *l, QLibrary* h) 288KLibWrapPrivate::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
302class KLibLoaderPrivate 309class KLibLoaderPrivate
303{ 310{
304public: 311public:
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
312KLibLoader* KLibLoader::s_self = 0; 319KLibLoader* KLibLoader::s_self = 0;
313 320
314KLibLoader* KLibLoader::self() 321KLibLoader* 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
321void KLibLoader::cleanUp() 328void 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
330KLibLoader::KLibLoader( QObject* parent, const char* name ) 337KLibLoader::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
344KLibLoader::~KLibLoader() 351KLibLoader::~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
362QString KLibLoader::findLibrary( const char * name/*US , const KInstance * instance*/ ) 369QString 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
423KLibrary* KLibLoader::globalLibrary( const char *name ) 430KLibrary* KLibLoader::globalLibrary( const char *name )
424{ 431{
425KLibrary *tmp; 432KLibrary *tmp;
426/*US 433/*US
427int olt_dlopen_flag = lt_dlopen_flag; 434int 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*/
438return tmp; 445return tmp;
439} 446}
440 447
441 448
442KLibrary* KLibLoader::library( const char *name ) 449KLibrary* 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
507QString KLibLoader::lastErrorMessage() const 514QString KLibLoader::lastErrorMessage() const
508{ 515{
509 return d->errorMessage; 516 return d->errorMessage;
510} 517}
511 518
512void KLibLoader::unloadLibrary( const char *libname ) 519void 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
529KLibFactory* KLibLoader::factory( const char* name ) 536KLibFactory* 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
538void KLibLoader::slotLibraryDestroyed() 545void 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
554void KLibLoader::close_pending(KLibWrapPrivate *wrap) 561void 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. */
606 613
607 QWidgetList *widgetlist = QApplication::topLevelWidgets(); 614 QWidgetList *widgetlist = QApplication::topLevelWidgets();
608 QWidget *co = widgetlist->first(); 615 QWidget *co = widgetlist->first();
609 while (co) { 616 while (co) {
610 if (qstrcmp(co->name(), "internal clipboard owner") == 0) { 617 if (qstrcmp(co->name(), "internal clipboard owner") == 0) {
611 if (XGetSelectionOwner(co->x11Display(), XA_PRIMARY) == co->winId()) 618 if (XGetSelectionOwner(co->x11Display(), XA_PRIMARY) == co->winId())
612 kapp->clipboard()->setText(kapp->clipboard()->text()); 619 kapp->clipboard()->setText(kapp->clipboard()->text());
613 620
614 break; 621 break;
615 } 622 }
616 co = widgetlist->next(); 623 co = widgetlist->next();
617 } 624 }
618 delete widgetlist; 625 delete widgetlist;
619 } 626 }
620#else 627#else
621 // FIXME(E): Implement in Qt Embedded 628 // FIXME(E): Implement in Qt Embedded
622#endif 629#endif
623 630
624 deleted_one = true; 631 deleted_one = true;
625//US lt_dlclose(wrap->handle); 632//US lt_dlclose(wrap->handle);
626 wrap->handle->unload(); 633 wrap->handle->unload();
627 634
628 d->pending_close.removeRef(wrap); 635 d->pending_close.removeRef(wrap);
629 /* loaded_stack is AutoDelete, so wrap is freed */ 636 /* loaded_stack is AutoDelete, so wrap is freed */
630 d->loaded_stack.remove(); 637 d->loaded_stack.remove();
631 } 638 }
632} 639}
633 640
634void KLibLoader::virtual_hook( int, void* ) 641void KLibLoader::virtual_hook( int, void* )
635{ /*BASE::virtual_hook( id, data );*/ } 642{ /*BASE::virtual_hook( id, data );*/ }
636 643
637void KLibFactory::virtual_hook( int, void* ) 644void KLibFactory::virtual_hook( int, void* )
638{ /*BASE::virtual_hook( id, data );*/ } 645{ /*BASE::virtual_hook( id, data );*/ }
639 646
640//US #include "klibloader.moc" 647//US #include "klibloader.moc"