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_H
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 {
00356 KActiveSocketBase::open(Unbuffered | mode);
00357 return true;
00358 }
00359 else if (errno == EALREADY || errno == EINPROGRESS)
00360 {
00361 KActiveSocketBase::open(Unbuffered | mode);
00362 setError(InProgress);
00363 return true;
00364 }
00365 else if (errno == ECONNREFUSED)
00366 setError(ConnectionRefused);
00367 else if (errno == ENETDOWN || errno == ENETUNREACH ||
00368 errno == ENETRESET || errno == ECONNABORTED ||
00369 errno == ECONNRESET || errno == EHOSTDOWN ||
00370 errno == EHOSTUNREACH)
00371 setError(NetFailure);
00372 else
00373 setError(NotSupported);
00374
00375 return false;
00376 }
00377
00378 KActiveSocketBase::open(Unbuffered | mode);
00379 return true;
00380 }
00381
00382 KSocketDevice* KSocketDevice::accept()
00383 {
00384 if (m_sockfd == -1)
00385 {
00386
00387 setError(NotCreated);
00388 return 0L;
00389 }
00390
00391 struct sockaddr sa;
00392 socklen_t len = sizeof(sa);
00393 int newfd = kde_accept(m_sockfd, &sa, &len);
00394 if (newfd == -1)
00395 {
00396 if (errno == EAGAIN || errno == EWOULDBLOCK)
00397 setError(WouldBlock);
00398 else
00399 setError(UnknownError);
00400 return NULL;
00401 }
00402
00403 return new KSocketDevice(newfd);
00404 }
00405
00406 bool KSocketDevice::disconnect()
00407 {
00408 resetError();
00409
00410 if (m_sockfd == -1)
00411 return false;
00412
00413 KSocketAddress address;
00414 address.setFamily(AF_UNSPEC);
00415 if (kde_connect(m_sockfd, address.address(), address.length()) == -1)
00416 {
00417 if (errno == EALREADY || errno == EINPROGRESS)
00418 {
00419 setError(InProgress);
00420 return false;
00421 }
00422 else if (errno == ECONNREFUSED)
00423 setError(ConnectionRefused);
00424 else if (errno == ENETDOWN || errno == ENETUNREACH ||
00425 errno == ENETRESET || errno == ECONNABORTED ||
00426 errno == ECONNRESET || errno == EHOSTDOWN ||
00427 errno == EHOSTUNREACH)
00428 setError(NetFailure);
00429 else
00430 setError(NotSupported);
00431
00432 return false;
00433 }
00434
00435 setOpenMode(QIODevice::Unbuffered | QIODevice::ReadWrite);
00436 return true;
00437 }
00438
00439 qint64 KSocketDevice::bytesAvailable() const
00440 {
00441 if (m_sockfd == -1)
00442 return -1;
00443
00444 int nchars;
00445 if (kde_ioctl(m_sockfd, FIONREAD, &nchars) == -1)
00446 return -1;
00447
00448 return nchars;
00449 }
00450
00451 qint64 KSocketDevice::waitForMore(int msecs, bool *timeout)
00452 {
00453 if (m_sockfd == -1)
00454 return -1;
00455
00456 bool input;
00457 if (!poll(&input, 0, 0, msecs, timeout))
00458 return -1;
00459
00460 return bytesAvailable();
00461 }
00462
00463 static int do_read_common(int sockfd, char *data, qint64 maxlen, KSocketAddress* from, ssize_t &retval, bool peek = false)
00464 {
00465 socklen_t len;
00466 if (from)
00467 {
00468 from->setLength(len = 128);
00469 retval = ::recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, from->address(), &len);
00470 }
00471 else
00472 retval = ::recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, NULL, NULL);
00473
00474 if (retval == -1)
00475 {
00476 #ifdef Q_WS_WIN
00477 if (WSAGetLastError() == WSAEWOULDBLOCK )
00478 return KSocketDevice::WouldBlock;
00479 else
00480 #endif
00481 if (errno == EAGAIN || errno == EWOULDBLOCK )
00482 return KSocketDevice::WouldBlock;
00483 else
00484 return KSocketDevice::UnknownError;
00485 }
00486 if (retval == 0)
00487 return KSocketDevice::RemotelyDisconnected;
00488
00489 if (from)
00490 from->setLength(len);
00491 return 0;
00492 }
00493
00494 qint64 KSocketDevice::readData(char *data, qint64 maxlen, KSocketAddress *from)
00495 {
00496 resetError();
00497 if (m_sockfd == -1)
00498 return -1;
00499
00500 if (data == 0L || maxlen == 0)
00501 return 0;
00502
00503 ssize_t retval;
00504 int err = do_read_common(m_sockfd, data, maxlen, from, retval);
00505
00506 if (err)
00507 {
00508 setError(static_cast<SocketError>(err));
00509 return -1;
00510 }
00511
00512 return retval;
00513 }
00514
00515 qint64 KSocketDevice::peekData(char *data, qint64 maxlen, KSocketAddress* from)
00516 {
00517 resetError();
00518 if (m_sockfd == -1)
00519 return -1;
00520
00521 if (data == 0L || maxlen == 0)
00522 return 0;
00523
00524 ssize_t retval;
00525 int err = do_read_common(m_sockfd, data, maxlen, from, retval, true);
00526
00527 if (err)
00528 {
00529 setError(static_cast<SocketError>(err));
00530 return -1;
00531 }
00532
00533 return retval;
00534 }
00535
00536 qint64 KSocketDevice::writeData(const char *data, qint64 len, const KSocketAddress* to)
00537 {
00538 resetError();
00539 if (m_sockfd == -1)
00540 return -1;
00541
00542 if (data == 0L || len == 0)
00543 return 0;
00544
00545 ssize_t retval;
00546 if (to != 0L)
00547 retval = ::sendto(m_sockfd, data, len, 0, to->address(), to->length());
00548 else
00549 #ifdef Q_WS_WIN
00550 retval = ::send(m_sockfd, data, len, 0);
00551 #else
00552 retval = ::write(m_sockfd, data, len);
00553 #endif
00554 if (retval == -1)
00555 {
00556 if (errno == EAGAIN || errno == EWOULDBLOCK)
00557 setError(WouldBlock);
00558 else
00559 setError(UnknownError);
00560 return -1;
00561 }
00562 else if (retval == 0)
00563 setError(RemotelyDisconnected);
00564
00565 return retval;
00566 }
00567
00568 KSocketAddress KSocketDevice::localAddress() const
00569 {
00570 if (m_sockfd == -1)
00571 return KSocketAddress();
00572
00573 if (d->local.family() != AF_UNSPEC)
00574 return d->local;
00575
00576 socklen_t len;
00577 KSocketAddress localAddress;
00578 localAddress.setLength(len = 32);
00579 if (kde_getsockname(m_sockfd, localAddress.address(), &len) == -1)
00580
00581 return d->local = KSocketAddress();
00582
00583 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
00584 len = localAddress.address()->sa_len;
00585 #endif
00586
00587 if (len <= localAddress.length())
00588 {
00589
00590 localAddress.setLength(len);
00591 return d->local = localAddress;
00592 }
00593
00594
00595
00596 localAddress.setLength(len);
00597 if (kde_getsockname(m_sockfd, localAddress.address(), &len) == -1)
00598
00599 return d->local = KSocketAddress();
00600
00601 return d->local = localAddress;
00602 }
00603
00604 KSocketAddress KSocketDevice::peerAddress() const
00605 {
00606 if (m_sockfd == -1)
00607 return KSocketAddress();
00608
00609 if (d->peer.family() != AF_UNSPEC)
00610 return d->peer;
00611
00612 socklen_t len;
00613 KSocketAddress peerAddress;
00614 peerAddress.setLength(len = 32);
00615 if (kde_getpeername(m_sockfd, peerAddress.address(), &len) == -1)
00616
00617 return d->peer = KSocketAddress();
00618
00619 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
00620 len = peerAddress.address()->sa_len;
00621 #endif
00622
00623 if (len <= peerAddress.length())
00624 {
00625
00626 peerAddress.setLength(len);
00627 return d->peer = peerAddress;
00628 }
00629
00630
00631
00632 peerAddress.setLength(len);
00633 if (kde_getpeername(m_sockfd, peerAddress.address(), &len) == -1)
00634
00635 return d->peer = KSocketAddress();
00636
00637 return d->peer = peerAddress;
00638 }
00639
00640 KSocketAddress KSocketDevice::externalAddress() const
00641 {
00642
00643
00644 return localAddress();
00645 }
00646
00647 QSocketNotifier* KSocketDevice::readNotifier() const
00648 {
00649 if (d->input)
00650 return d->input;
00651
00652 QMutexLocker locker(mutex());
00653 if (d->input)
00654 return d->input;
00655
00656 if (m_sockfd == -1)
00657 {
00658
00659 return 0L;
00660 }
00661
00662 return d->input = createNotifier(QSocketNotifier::Read);
00663 }
00664
00665 QSocketNotifier* KSocketDevice::writeNotifier() const
00666 {
00667 if (d->output)
00668 return d->output;
00669
00670 QMutexLocker locker(mutex());
00671 if (d->output)
00672 return d->output;
00673
00674 if (m_sockfd == -1)
00675 {
00676
00677 return 0L;
00678 }
00679
00680 return d->output = createNotifier(QSocketNotifier::Write);
00681 }
00682
00683 QSocketNotifier* KSocketDevice::exceptionNotifier() const
00684 {
00685 if (d->exception)
00686 return d->exception;
00687
00688 QMutexLocker locker(mutex());
00689 if (d->exception)
00690 return d->exception;
00691
00692 if (m_sockfd == -1)
00693 {
00694
00695 return 0L;
00696 }
00697
00698 return d->exception = createNotifier(QSocketNotifier::Exception);
00699 }
00700
00701 bool KSocketDevice::poll(bool *input, bool *output, bool *exception,
00702 int timeout, bool* timedout)
00703 {
00704 if (m_sockfd == -1)
00705 {
00706 setError(NotCreated);
00707 return false;
00708 }
00709
00710 resetError();
00711 #ifdef HAVE_POLL
00712 struct pollfd fds;
00713 fds.fd = m_sockfd;
00714 fds.events = 0;
00715
00716 if (input)
00717 {
00718 fds.events |= POLLIN;
00719 *input = false;
00720 }
00721 if (output)
00722 {
00723 fds.events |= POLLOUT;
00724 *output = false;
00725 }
00726 if (exception)
00727 {
00728 fds.events |= POLLPRI;
00729 *exception = false;
00730 }
00731
00732 int retval = ::poll(&fds, 1, timeout);
00733 if (retval == -1)
00734 {
00735 setError(UnknownError);
00736 return false;
00737 }
00738 if (retval == 0)
00739 {
00740
00741 if (timedout)
00742 *timedout = true;
00743 return true;
00744 }
00745
00746 if (input && fds.revents & POLLIN)
00747 *input = true;
00748 if (output && fds.revents & POLLOUT)
00749 *output = true;
00750 if (exception && fds.revents & POLLPRI)
00751 *exception = true;
00752 if (timedout)
00753 *timedout = false;
00754
00755 return true;
00756 #else
00757
00758
00759
00760
00761 fd_set readfds, writefds, exceptfds;
00762 fd_set *preadfds = 0L, *pwritefds = 0L, *pexceptfds = 0L;
00763
00764 if (input)
00765 {
00766 preadfds = &readfds;
00767 FD_ZERO(preadfds);
00768 FD_SET(m_sockfd, preadfds);
00769 *input = false;
00770 }
00771 if (output)
00772 {
00773 pwritefds = &writefds;
00774 FD_ZERO(pwritefds);
00775 FD_SET(m_sockfd, pwritefds);
00776 *output = false;
00777 }
00778 if (exception)
00779 {
00780 pexceptfds = &exceptfds;
00781 FD_ZERO(pexceptfds);
00782 FD_SET(m_sockfd, pexceptfds);
00783 *exception = false;
00784 }
00785
00786 int retval;
00787 if (timeout < 0)
00788 retval = select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, 0L);
00789 else
00790 {
00791
00792 struct timeval tv;
00793 tv.tv_sec = timeout / 1000;
00794 tv.tv_usec = timeout % 1000 * 1000;
00795
00796 retval = select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, &tv);
00797 }
00798
00799 if (retval == -1)
00800 {
00801 setError(UnknownError);
00802 return false;
00803 }
00804 if (retval == 0)
00805 {
00806
00807 if (timedout)
00808 *timedout = true;
00809 return true;
00810 }
00811
00812 if (input && FD_ISSET(m_sockfd, preadfds))
00813 *input = true;
00814 if (output && FD_ISSET(m_sockfd, pwritefds))
00815 *output = true;
00816 if (exception && FD_ISSET(m_sockfd, pexceptfds))
00817 *exception = true;
00818
00819 return true;
00820 #endif
00821 }
00822
00823 bool KSocketDevice::poll(int timeout, bool *timedout)
00824 {
00825 bool input, output, exception;
00826 return poll(&input, &output, &exception, timeout, timedout);
00827 }
00828
00829 QSocketNotifier* KSocketDevice::createNotifier(QSocketNotifier::Type type) const
00830 {
00831 if (m_sockfd == -1)
00832 return 0L;
00833
00834 return new QSocketNotifier(m_sockfd, type);
00835 }
00836
00837 namespace
00838 {
00839
00840 template<class T> class ptr
00841 {
00842 typedef T type;
00843 type* obj;
00844 public:
00845 ptr() : obj(0)
00846 { }
00847
00848 ptr(const ptr<T>& other) : obj(other.obj)
00849 { }
00850
00851 ptr(type* _obj) : obj(_obj)
00852 { }
00853
00854 ~ptr()
00855 { }
00856
00857 ptr<T>& operator=(const ptr<T>& other)
00858 { obj = other.obj; return *this; }
00859
00860 ptr<T>& operator=(T* _obj)
00861 { obj = _obj; return *this; }
00862
00863 type* operator->() const { return obj; }
00864
00865 operator T*() const { return obj; }
00866
00867 bool isNull() const
00868 { return obj == 0; }
00869 };
00870 }
00871
00872 static KSocketDeviceFactoryBase* defaultImplFactory;
00873 static QMutex defaultImplFactoryMutex;
00874 typedef QMap<int, KSocketDeviceFactoryBase* > factoryMap;
00875 static factoryMap factories;
00876
00877 KSocketDevice* KSocketDevice::createDefault(KSocketBase* parent)
00878 {
00879 KSocketDevice* device = dynamic_cast<KSocketDevice*>(parent);
00880 if (device != 0L)
00881 return device;
00882
00883 if (defaultImplFactory)
00884 return defaultImplFactory->create(parent);
00885
00886
00887 return new KSocketDevice(parent);
00888 }
00889
00890 KSocketDevice* KSocketDevice::createDefault(KSocketBase* parent, int capabilities)
00891 {
00892 KSocketDevice* device = dynamic_cast<KSocketDevice*>(parent);
00893 if (device != 0L)
00894 return device;
00895
00896 QMutexLocker locker(&defaultImplFactoryMutex);
00897 factoryMap::ConstIterator it = factories.constBegin();
00898 for ( ; it != factories.constEnd(); ++it)
00899 if ((it.key() & capabilities) == capabilities)
00900
00901 return it.value()->create(parent);
00902
00903 return 0L;
00904 }
00905
00906 KSocketDeviceFactoryBase*
00907 KSocketDevice::setDefaultImpl(KSocketDeviceFactoryBase* factory)
00908 {
00909 QMutexLocker locker(&defaultImplFactoryMutex);
00910 KSocketDeviceFactoryBase* old = defaultImplFactory;
00911 defaultImplFactory = factory;
00912 return old;
00913 }
00914
00915 void KSocketDevice::addNewImpl(KSocketDeviceFactoryBase* factory, int capabilities)
00916 {
00917 QMutexLocker locker(&defaultImplFactoryMutex);
00918 if (factories.contains(capabilities))
00919 delete factories[capabilities];
00920 factories.insert(capabilities, factory);
00921 }
00922