00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <config.h>
00026
00027 #include <qmap.h>
00028
00029 #ifdef USE_SOLARIS
00030 # include <sys/filio.h>
00031 #endif
00032 #include <sys/types.h>
00033 #include <sys/socket.h>
00034 #include <sys/time.h>
00035 #include <sys/ioctl.h>
00036 #include <errno.h>
00037 #include <fcntl.h>
00038 #include <netinet/in.h>
00039 #include <unistd.h>
00040
00041 #ifdef HAVE_POLL
00042 # include <sys/poll.h>
00043 #else
00044 # ifdef HAVE_SYS_SELECT
00045 # include <sys/select.h>
00046 # endif
00047 #endif
00048
00049
00050 #include "syssocket.h"
00051
00052 #include <qmutex.h>
00053 #include <qsocketnotifier.h>
00054
00055 #include "kresolver.h"
00056 #include "ksocketaddress.h"
00057 #include "ksocketbase.h"
00058 #include "ksocketdevice.h"
00059 #include "ksockssocketdevice.h"
00060
00061 using namespace KNetwork;
00062
00063 class KNetwork::KSocketDevicePrivate
00064 {
00065 public:
00066 mutable QSocketNotifier *input, *output, *exception;
00067 KSocketAddress local, peer;
00068 int af;
00069
00070 inline KSocketDevicePrivate()
00071 {
00072 input = output = exception = 0L;
00073 af = 0;
00074 }
00075 };
00076
00077
00078 KSocketDevice::KSocketDevice(const KSocketBase* parent)
00079 : m_sockfd(-1), d(new KSocketDevicePrivate)
00080 {
00081 setSocketDevice(this);
00082 if (parent)
00083 setSocketOptions(parent->socketOptions());
00084 }
00085
00086 KSocketDevice::KSocketDevice(int fd)
00087 : m_sockfd(fd), d(new KSocketDevicePrivate)
00088 {
00089 setState(IO_Open);
00090 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite);
00091 setSocketDevice(this);
00092 d->af = localAddress().family();
00093 }
00094
00095 KSocketDevice::KSocketDevice(bool, const KSocketBase* parent)
00096 : m_sockfd(-1), d(new KSocketDevicePrivate)
00097 {
00098
00099 if (parent)
00100 setSocketOptions(parent->socketOptions());
00101 }
00102
00103 KSocketDevice::~KSocketDevice()
00104 {
00105 close();
00106 unsetSocketDevice();
00107 delete d;
00108 }
00109
00110 bool KSocketDevice::setSocketOptions(int opts)
00111 {
00112
00113 QMutexLocker locker(mutex());
00114 KSocketBase::setSocketOptions(opts);
00115
00116 if (m_sockfd == -1)
00117 return true;
00118
00119 {
00120 int fdflags = fcntl(m_sockfd, F_GETFL, 0);
00121 if (fdflags == -1)
00122 {
00123 setError(IO_UnspecifiedError, UnknownError);
00124 return false;
00125 }
00126
00127 if (opts & Blocking)
00128 fdflags &= ~O_NONBLOCK;
00129 else
00130 fdflags |= O_NONBLOCK;
00131
00132 if (fcntl(m_sockfd, F_SETFL, fdflags) == -1)
00133 {
00134 setError(IO_UnspecifiedError, UnknownError);
00135 return false;
00136 }
00137 }
00138
00139 {
00140 int on = opts & AddressReuseable ? 1 : 0;
00141 if (setsockopt(m_sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)) == -1)
00142 {
00143 setError(IO_UnspecifiedError, UnknownError);
00144 return false;
00145 }
00146 }
00147
00148 #if defined(IPV6_V6ONLY) && defined(AF_INET6)
00149 if (d->af == AF_INET6)
00150 {
00151
00152
00153 int on = opts & IPv6Only ? 1 : 0;
00154 if (setsockopt(m_sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&on, sizeof(on)) == -1)
00155 {
00156 setError(IO_UnspecifiedError, UnknownError);
00157 return false;
00158 }
00159 }
00160 #endif
00161
00162 {
00163 int on = opts & Broadcast ? 1 : 0;
00164 if (setsockopt(m_sockfd, SOL_SOCKET, SO_BROADCAST, (char*)&on, sizeof(on)) == -1)
00165 {
00166 setError(IO_UnspecifiedError, UnknownError);
00167 return false;
00168 }
00169 }
00170
00171 return true;
00172 }
00173
00174 bool KSocketDevice::open(int)
00175 {
00176 resetError();
00177 return false;
00178 }
00179
00180 void KSocketDevice::close()
00181 {
00182 resetError();
00183 if (m_sockfd != -1)
00184 {
00185 delete d->input;
00186 delete d->output;
00187 delete d->exception;
00188
00189 d->input = d->output = d->exception = 0L;
00190
00191 d->local.setFamily(AF_UNSPEC);
00192 d->peer.setFamily(AF_UNSPEC);
00193
00194 ::close(m_sockfd);
00195 }
00196 setState(0);
00197
00198 m_sockfd = -1;
00199 }
00200
00201 bool KSocketDevice::create(int family, int type, int protocol)
00202 {
00203 resetError();
00204
00205 if (m_sockfd != -1)
00206 {
00207
00208 setError(IO_SocketCreateError, AlreadyCreated);
00209 return false;
00210 }
00211
00212
00213 m_sockfd = kde_socket(family, type, protocol);
00214
00215 if (m_sockfd == -1)
00216 {
00217 setError(IO_SocketCreateError, NotSupported);
00218 return false;
00219 }
00220
00221 d->af = family;
00222 setSocketOptions(socketOptions());
00223 setState(IO_Open);
00224 return true;
00225 }
00226
00227 bool KSocketDevice::create(const KResolverEntry& address)
00228 {
00229 return create(address.family(), address.socketType(), address.protocol());
00230 }
00231
00232 bool KSocketDevice::bind(const KResolverEntry& address)
00233 {
00234 resetError();
00235
00236 if (m_sockfd == -1 && !create(address))
00237 return false;
00238
00239
00240 if (kde_bind(m_sockfd, address.address(), address.length()) == -1)
00241 {
00242 if (errno == EADDRINUSE)
00243 setError(IO_BindError, AddressInUse);
00244 else if (errno == EINVAL)
00245 setError(IO_BindError, AlreadyBound);
00246 else
00247
00248 setError(IO_BindError, NotSupported);
00249 return false;
00250 }
00251
00252 return true;
00253 }
00254
00255 bool KSocketDevice::listen(int backlog)
00256 {
00257 if (m_sockfd != -1)
00258 {
00259 if (kde_listen(m_sockfd, backlog) == -1)
00260 {
00261 setError(IO_ListenError, NotSupported);
00262 return false;
00263 }
00264
00265 resetError();
00266 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite);
00267 return true;
00268 }
00269
00270
00271
00272 setError(IO_ListenError, NotCreated);
00273 return false;
00274 }
00275
00276 bool KSocketDevice::connect(const KResolverEntry& address)
00277 {
00278 resetError();
00279
00280 if (m_sockfd == -1 && !create(address))
00281 return false;
00282
00283 if (kde_connect(m_sockfd, address.address(), address.length()) == -1)
00284 {
00285 if (errno == EISCONN)
00286 return true;
00287 else if (errno == EALREADY || errno == EINPROGRESS)
00288 {
00289 setError(IO_ConnectError, InProgress);
00290 return true;
00291 }
00292 else if (errno == ECONNREFUSED)
00293 setError(IO_ConnectError, ConnectionRefused);
00294 else if (errno == ENETDOWN || errno == ENETUNREACH ||
00295 errno == ENETRESET || errno == ECONNABORTED ||
00296 errno == ECONNRESET || errno == EHOSTDOWN ||
00297 errno == EHOSTUNREACH)
00298 setError(IO_ConnectError, NetFailure);
00299 else
00300 setError(IO_ConnectError, NotSupported);
00301
00302 return false;
00303 }
00304
00305 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite);
00306 return true;
00307 }
00308
00309 KSocketDevice* KSocketDevice::accept()
00310 {
00311 if (m_sockfd == -1)
00312 {
00313
00314 setError(IO_AcceptError, NotCreated);
00315 return 0L;
00316 }
00317
00318 struct sockaddr sa;
00319 socklen_t len = sizeof(sa);
00320 int newfd = kde_accept(m_sockfd, &sa, &len);
00321 if (newfd == -1)
00322 {
00323 if (errno == EAGAIN || errno == EWOULDBLOCK)
00324 setError(IO_AcceptError, WouldBlock);
00325 else
00326 setError(IO_AcceptError, UnknownError);
00327 return NULL;
00328 }
00329
00330 return new KSocketDevice(newfd);
00331 }
00332
00333 bool KSocketDevice::disconnect()
00334 {
00335 resetError();
00336
00337 if (m_sockfd == -1)
00338 return false;
00339
00340 KSocketAddress address;
00341 address.setFamily(AF_UNSPEC);
00342 if (kde_connect(m_sockfd, address.address(), address.length()) == -1)
00343 {
00344 if (errno == EALREADY || errno == EINPROGRESS)
00345 {
00346 setError(IO_ConnectError, InProgress);
00347 return false;
00348 }
00349 else if (errno == ECONNREFUSED)
00350 setError(IO_ConnectError, ConnectionRefused);
00351 else if (errno == ENETDOWN || errno == ENETUNREACH ||
00352 errno == ENETRESET || errno == ECONNABORTED ||
00353 errno == ECONNRESET || errno == EHOSTDOWN ||
00354 errno == EHOSTUNREACH)
00355 setError(IO_ConnectError, NetFailure);
00356 else
00357 setError(IO_ConnectError, NotSupported);
00358
00359 return false;
00360 }
00361
00362 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite);
00363 setState(IO_Open);
00364 return true;
00365 }
00366
00367 Q_LONG KSocketDevice::bytesAvailable() const
00368 {
00369 if (m_sockfd == -1)
00370 return -1;
00371
00372 int nchars;
00373 if (ioctl(m_sockfd, FIONREAD, &nchars) == -1)
00374 return -1;
00375
00376 return nchars;
00377 }
00378
00379 Q_LONG KSocketDevice::waitForMore(int msecs, bool *timeout)
00380 {
00381 if (m_sockfd == -1)
00382 return -1;
00383
00384 bool input;
00385 if (!poll(&input, 0, 0, msecs, timeout))
00386 return -1;
00387
00388 return bytesAvailable();
00389 }
00390
00391 static int do_read_common(int sockfd, char *data, Q_ULONG maxlen, KSocketAddress* from, ssize_t &retval, bool peek = false)
00392 {
00393 socklen_t len;
00394 if (from)
00395 {
00396 from->setLength(len = 128);
00397 retval = ::recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, from->address(), &len);
00398 }
00399 else
00400 retval = ::recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, NULL, NULL);
00401
00402 if (retval == -1)
00403 {
00404 if (errno == EAGAIN || errno == EWOULDBLOCK)
00405 return KSocketDevice::WouldBlock;
00406 else
00407 return KSocketDevice::UnknownError;
00408 }
00409 if (retval == 0)
00410 return KSocketDevice::RemotelyDisconnected;
00411
00412 if (from)
00413 from->setLength(len);
00414 return 0;
00415 }
00416
00417 Q_LONG KSocketDevice::readBlock(char *data, Q_ULONG maxlen)
00418 {
00419 resetError();
00420 if (m_sockfd == -1)
00421 return -1;
00422
00423 if (maxlen == 0 || data == 0L)
00424 return 0;
00425
00426 ssize_t retval;
00427 int err = do_read_common(m_sockfd, data, maxlen, 0L, retval);
00428
00429 if (err)
00430 {
00431 setError(IO_ReadError, static_cast<SocketError>(err));
00432 return -1;
00433 }
00434
00435 return retval;
00436 }
00437
00438 Q_LONG KSocketDevice::readBlock(char *data, Q_ULONG maxlen, KSocketAddress &from)
00439 {
00440 resetError();
00441 if (m_sockfd == -1)
00442 return -1;
00443
00444 if (data == 0L || maxlen == 0)
00445 return 0;
00446
00447 ssize_t retval;
00448 int err = do_read_common(m_sockfd, data, maxlen, &from, retval);
00449
00450 if (err)
00451 {
00452 setError(IO_ReadError, static_cast<SocketError>(err));
00453 return -1;
00454 }
00455
00456 return retval;
00457 }
00458
00459 Q_LONG KSocketDevice::peekBlock(char *data, Q_ULONG maxlen)
00460 {
00461 resetError();
00462 if (m_sockfd == -1)
00463 return -1;
00464
00465 if (maxlen == 0 || data == 0L)
00466 return 0;
00467
00468 ssize_t retval;
00469 int err = do_read_common(m_sockfd, data, maxlen, 0L, retval, true);
00470
00471 if (err)
00472 {
00473 setError(IO_ReadError, static_cast<SocketError>(err));
00474 return -1;
00475 }
00476
00477 return retval;
00478 }
00479
00480 Q_LONG KSocketDevice::peekBlock(char *data, Q_ULONG maxlen, KSocketAddress& from)
00481 {
00482 resetError();
00483 if (m_sockfd == -1)
00484 return -1;
00485
00486 if (data == 0L || maxlen == 0)
00487 return 0;
00488
00489 ssize_t retval;
00490 int err = do_read_common(m_sockfd, data, maxlen, &from, retval, true);
00491
00492 if (err)
00493 {
00494 setError(IO_ReadError, static_cast<SocketError>(err));
00495 return -1;
00496 }
00497
00498 return retval;
00499 }
00500
00501 Q_LONG KSocketDevice::writeBlock(const char *data, Q_ULONG len)
00502 {
00503 return writeBlock(data, len, KSocketAddress());
00504 }
00505
00506 Q_LONG KSocketDevice::writeBlock(const char *data, Q_ULONG len, const KSocketAddress& to)
00507 {
00508 resetError();
00509 if (m_sockfd == -1)
00510 return -1;
00511
00512 if (data == 0L || len == 0)
00513 return 0;
00514
00515 ssize_t retval = ::sendto(m_sockfd, data, len, 0, to.address(), to.length());
00516 if (retval == -1)
00517 {
00518 if (errno == EAGAIN || errno == EWOULDBLOCK)
00519 setError(IO_WriteError, WouldBlock);
00520 else
00521 setError(IO_WriteError, UnknownError);
00522 return -1;
00523 }
00524 else if (retval == 0)
00525 setError(IO_WriteError, RemotelyDisconnected);
00526
00527 return retval;
00528 }
00529
00530 KSocketAddress KSocketDevice::localAddress() const
00531 {
00532 if (m_sockfd == -1)
00533 return KSocketAddress();
00534
00535 if (d->local.family() != AF_UNSPEC)
00536 return d->local;
00537
00538 socklen_t len;
00539 KSocketAddress localAddress;
00540 localAddress.setLength(len = 32);
00541 if (kde_getsockname(m_sockfd, localAddress.address(), &len) == -1)
00542
00543 return d->local = KSocketAddress();
00544
00545 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
00546 len = localAddress.address()->sa_len;
00547 #endif
00548
00549 if (len <= localAddress.length())
00550 {
00551
00552 localAddress.setLength(len);
00553 return d->local = localAddress;
00554 }
00555
00556
00557
00558 localAddress.setLength(len);
00559 if (kde_getsockname(m_sockfd, localAddress.address(), &len) == -1)
00560
00561 return d->local = KSocketAddress();
00562
00563 return d->local = localAddress;
00564 }
00565
00566 KSocketAddress KSocketDevice::peerAddress() const
00567 {
00568 if (m_sockfd == -1)
00569 return KSocketAddress();
00570
00571 if (d->peer.family() != AF_UNSPEC)
00572 return d->peer;
00573
00574 socklen_t len;
00575 KSocketAddress peerAddress;
00576 peerAddress.setLength(len = 32);
00577 if (kde_getpeername(m_sockfd, peerAddress.address(), &len) == -1)
00578
00579 return d->peer = KSocketAddress();
00580
00581 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
00582 len = peerAddress.address()->sa_len;
00583 #endif
00584
00585 if (len <= peerAddress.length())
00586 {
00587
00588 peerAddress.setLength(len);
00589 return d->peer = peerAddress;
00590 }
00591
00592
00593
00594 peerAddress.setLength(len);
00595 if (kde_getpeername(m_sockfd, peerAddress.address(), &len) == -1)
00596
00597 return d->peer = KSocketAddress();
00598
00599 return d->peer = peerAddress;
00600 }
00601
00602 KSocketAddress KSocketDevice::externalAddress() const
00603 {
00604
00605
00606 return localAddress();
00607 }
00608
00609 QSocketNotifier* KSocketDevice::readNotifier() const
00610 {
00611 if (d->input)
00612 return d->input;
00613
00614 QMutexLocker locker(mutex());
00615 if (d->input)
00616 return d->input;
00617
00618 if (m_sockfd == -1)
00619 {
00620
00621 return 0L;
00622 }
00623
00624 return d->input = createNotifier(QSocketNotifier::Read);
00625 }
00626
00627 QSocketNotifier* KSocketDevice::writeNotifier() const
00628 {
00629 if (d->output)
00630 return d->output;
00631
00632 QMutexLocker locker(mutex());
00633 if (d->output)
00634 return d->output;
00635
00636 if (m_sockfd == -1)
00637 {
00638
00639 return 0L;
00640 }
00641
00642 return d->output = createNotifier(QSocketNotifier::Write);
00643 }
00644
00645 QSocketNotifier* KSocketDevice::exceptionNotifier() const
00646 {
00647 if (d->exception)
00648 return d->exception;
00649
00650 QMutexLocker locker(mutex());
00651 if (d->exception)
00652 return d->exception;
00653
00654 if (m_sockfd == -1)
00655 {
00656
00657 return 0L;
00658 }
00659
00660 return d->exception = createNotifier(QSocketNotifier::Exception);
00661 }
00662
00663 bool KSocketDevice::poll(bool *input, bool *output, bool *exception,
00664 int timeout, bool* timedout)
00665 {
00666 if (m_sockfd == -1)
00667 {
00668 setError(IO_UnspecifiedError, NotCreated);
00669 return false;
00670 }
00671
00672 resetError();
00673 #ifdef HAVE_POLL
00674 struct pollfd fds;
00675 fds.fd = m_sockfd;
00676 fds.events = 0;
00677
00678 if (input)
00679 {
00680 fds.events |= POLLIN;
00681 *input = false;
00682 }
00683 if (output)
00684 {
00685 fds.events |= POLLOUT;
00686 *output = false;
00687 }
00688 if (exception)
00689 {
00690 fds.events |= POLLPRI;
00691 *exception = false;
00692 }
00693
00694 int retval = ::poll(&fds, 1, timeout);
00695 if (retval == -1)
00696 {
00697 setError(IO_UnspecifiedError, UnknownError);
00698 return false;
00699 }
00700 if (retval == 0)
00701 {
00702
00703 if (timedout)
00704 *timedout = true;
00705 return true;
00706 }
00707
00708 if (input && fds.revents & POLLIN)
00709 *input = true;
00710 if (output && fds.revents & POLLOUT)
00711 *output = true;
00712 if (exception && fds.revents & POLLPRI)
00713 *exception = true;
00714 if (timedout)
00715 *timedout = false;
00716
00717 return true;
00718 #else
00719
00720
00721
00722
00723 fd_set readfds, writefds, exceptfds;
00724 fd_set *preadfds = 0L, *pwritefds = 0L, *pexceptfds = 0L;
00725
00726 if (input)
00727 {
00728 preadfds = &readfds;
00729 FD_ZERO(preadfds);
00730 FD_SET(m_sockfd, preadfds);
00731 *input = false;
00732 }
00733 if (output)
00734 {
00735 pwritefds = &writefds;
00736 FD_ZERO(pwritefds);
00737 FD_SET(m_sockfd, pwritefds);
00738 *output = false;
00739 }
00740 if (exception)
00741 {
00742 pexceptfds = &exceptfds;
00743 FD_ZERO(pexceptfds);
00744 FD_SET(m_sockfd, pexceptfds);
00745 *exception = false;
00746 }
00747
00748 int retval;
00749 if (timeout < 0)
00750 retval = select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, 0L);
00751 else
00752 {
00753
00754 struct timeval tv;
00755 tv.tv_sec = timeout / 1000;
00756 tv.tv_usec = timeout % 1000 * 1000;
00757
00758 retval = select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, &tv);
00759 }
00760
00761 if (retval == -1)
00762 {
00763 setError(IO_UnspecifiedError, UnknownError);
00764 return false;
00765 }
00766 if (retval == 0)
00767 {
00768
00769 if (timedout)
00770 *timedout = true;
00771 return true;
00772 }
00773
00774 if (input && FD_ISSET(m_sockfd, preadfds))
00775 *input = true;
00776 if (output && FD_ISSET(m_sockfd, pwritefds))
00777 *output = true;
00778 if (exception && FD_ISSET(m_sockfd, pexceptfds))
00779 *exception = true;
00780
00781 return true;
00782 #endif
00783 }
00784
00785 bool KSocketDevice::poll(int timeout, bool *timedout)
00786 {
00787 bool input, output, exception;
00788 return poll(&input, &output, &exception, timeout, timedout);
00789 }
00790
00791 QSocketNotifier* KSocketDevice::createNotifier(QSocketNotifier::Type type) const
00792 {
00793 if (m_sockfd == -1)
00794 return 0L;
00795
00796 return new QSocketNotifier(m_sockfd, type);
00797 }
00798
00799 namespace
00800 {
00801
00802 template<class T> class ptr
00803 {
00804 typedef T type;
00805 type* obj;
00806 public:
00807 ptr() : obj(0)
00808 { }
00809
00810 ptr(const ptr<T>& other) : obj(other.obj)
00811 { }
00812
00813 ptr(type* _obj) : obj(_obj)
00814 { }
00815
00816 ~ptr()
00817 { }
00818
00819 ptr<T>& operator=(const ptr<T>& other)
00820 { obj = other.obj; return *this; }
00821
00822 ptr<T>& operator=(T* _obj)
00823 { obj = _obj; return *this; }
00824
00825 type* operator->() const { return obj; }
00826
00827 operator T*() const { return obj; }
00828
00829 bool isNull() const
00830 { return obj == 0; }
00831 };
00832 }
00833
00834 static KSocketDeviceFactoryBase* defaultImplFactory;
00835 static QMutex defaultImplFactoryMutex;
00836 typedef QMap<int, KSocketDeviceFactoryBase* > factoryMap;
00837 static factoryMap factories;
00838
00839 KSocketDevice* KSocketDevice::createDefault(KSocketBase* parent)
00840 {
00841 KSocketDevice* device = dynamic_cast<KSocketDevice*>(parent);
00842 if (device != 0L)
00843 return device;
00844
00845 KSocksSocketDevice::initSocks();
00846
00847 if (defaultImplFactory)
00848 return defaultImplFactory->create(parent);
00849
00850
00851 return new KSocketDevice(parent);
00852 }
00853
00854 KSocketDevice* KSocketDevice::createDefault(KSocketBase* parent, int capabilities)
00855 {
00856 KSocketDevice* device = dynamic_cast<KSocketDevice*>(parent);
00857 if (device != 0L)
00858 return device;
00859
00860 QMutexLocker locker(&defaultImplFactoryMutex);
00861 factoryMap::ConstIterator it = factories.constBegin();
00862 for ( ; it != factories.constEnd(); ++it)
00863 if ((it.key() & capabilities) == capabilities)
00864
00865 return it.data()->create(parent);
00866
00867 return 0L;
00868 }
00869
00870 KSocketDeviceFactoryBase*
00871 KSocketDevice::setDefaultImpl(KSocketDeviceFactoryBase* factory)
00872 {
00873 QMutexLocker locker(&defaultImplFactoryMutex);
00874 KSocketDeviceFactoryBase* old = defaultImplFactory;
00875 defaultImplFactory = factory;
00876 return old;
00877 }
00878
00879 void KSocketDevice::addNewImpl(KSocketDeviceFactoryBase* factory, int capabilities)
00880 {
00881 QMutexLocker locker(&defaultImplFactoryMutex);
00882 if (factories.contains(capabilities))
00883 delete factories[capabilities];
00884 factories.insert(capabilities, factory);
00885 }
00886