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