ksocketdevice.cpp
00001 /* -*- C++ -*- 00002 * Copyright (C) 2003,2005 Thiago Macieira <thiago.macieira@kdemail.net> 00003 * 00004 * 00005 * Permission is hereby granted, free of charge, to any person obtaining 00006 * a copy of this software and associated documentation files (the 00007 * "Software"), to deal in the Software without restriction, including 00008 * without limitation the rights to use, copy, modify, merge, publish, 00009 * distribute, sublicense, and/or sell copies of the Software, and to 00010 * permit persons to whom the Software is furnished to do so, subject to 00011 * the following conditions: 00012 * 00013 * The above copyright notice and this permission notice shall be included 00014 * in all copies or substantial portions of the Software. 00015 * 00016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00017 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00018 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00019 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 00020 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 00021 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 00022 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 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 // Include syssocket before our local includes 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 // do not set parent 00099 if (parent) 00100 setSocketOptions(parent->socketOptions()); 00101 } 00102 00103 KSocketDevice::~KSocketDevice() 00104 { 00105 close(); // deletes the notifiers 00106 unsetSocketDevice(); // prevent double deletion 00107 delete d; 00108 } 00109 00110 bool KSocketDevice::setSocketOptions(int opts) 00111 { 00112 // must call parent 00113 QMutexLocker locker(mutex()); 00114 KSocketBase::setSocketOptions(opts); 00115 00116 if (m_sockfd == -1) 00117 return true; // flags are stored 00118 00119 { 00120 int fdflags = fcntl(m_sockfd, F_GETFL, 0); 00121 if (fdflags == -1) 00122 { 00123 setError(IO_UnspecifiedError, UnknownError); 00124 return false; // error 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; // error 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; // error 00145 } 00146 } 00147 00148 #if defined(IPV6_V6ONLY) && defined(AF_INET6) 00149 if (d->af == AF_INET6) 00150 { 00151 // don't try this on non-IPv6 sockets, or we'll get an error 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; // error 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; // error 00168 } 00169 } 00170 00171 return true; // all went well 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 // it's already created! 00208 setError(IO_SocketCreateError, AlreadyCreated); 00209 return false; 00210 } 00211 00212 // no socket yet; we have to create it 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; // successfully created 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; // failed creating 00238 00239 // we have a socket, so try and bind 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 // assume the address is the cause 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 // we don't have a socket 00271 // can't listen 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; // failed creating! 00282 00283 if (kde_connect(m_sockfd, address.address(), address.length()) == -1) 00284 { 00285 if (errno == EISCONN) 00286 return true; // we're already connected 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; // all is well 00307 } 00308 00309 KSocketDevice* KSocketDevice::accept() 00310 { 00311 if (m_sockfd == -1) 00312 { 00313 // can't accept without a socket 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; // can't create 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; // all is well 00365 } 00366 00367 Q_LONG KSocketDevice::bytesAvailable() const 00368 { 00369 if (m_sockfd == -1) 00370 return -1; // there's nothing to read in a closed socket 00371 00372 int nchars; 00373 if (ioctl(m_sockfd, FIONREAD, &nchars) == -1) 00374 return -1; // error! 00375 00376 return nchars; 00377 } 00378 00379 Q_LONG KSocketDevice::waitForMore(int msecs, bool *timeout) 00380 { 00381 if (m_sockfd == -1) 00382 return -1; // there won't ever be anything to read... 00383 00384 bool input; 00385 if (!poll(&input, 0, 0, msecs, timeout)) 00386 return -1; // failed polling 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); // arbitrary length 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; // can't read 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; // nothing to do here 00443 00444 if (data == 0L || maxlen == 0) 00445 return 0; // user doesn't want to read 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; // can't read 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; // nothing to do here 00485 00486 if (data == 0L || maxlen == 0) 00487 return 0; // user doesn't want to read 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; // can't write to unopen socket 00511 00512 if (data == 0L || len == 0) 00513 return 0; // nothing to be written 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; // nothing written 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(); // not open, empty value 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); // arbitrary value 00541 if (kde_getsockname(m_sockfd, localAddress.address(), &len) == -1) 00542 // error! 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 // it has fit already 00552 localAddress.setLength(len); 00553 return d->local = localAddress; 00554 } 00555 00556 // no, the socket address is actually larger than we had anticipated 00557 // call again 00558 localAddress.setLength(len); 00559 if (kde_getsockname(m_sockfd, localAddress.address(), &len) == -1) 00560 // error! 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(); // not open, empty value 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); // arbitrary value 00577 if (kde_getpeername(m_sockfd, peerAddress.address(), &len) == -1) 00578 // error! 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 // it has fit already 00588 peerAddress.setLength(len); 00589 return d->peer = peerAddress; 00590 } 00591 00592 // no, the socket address is actually larger than we had anticipated 00593 // call again 00594 peerAddress.setLength(len); 00595 if (kde_getpeername(m_sockfd, peerAddress.address(), &len) == -1) 00596 // error! 00597 return d->peer = KSocketAddress(); 00598 00599 return d->peer = peerAddress; 00600 } 00601 00602 KSocketAddress KSocketDevice::externalAddress() const 00603 { 00604 // for normal sockets, the externally visible address is the same 00605 // as the local address 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 // socket doesn't exist; can't create notifier 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 // socket doesn't exist; can't create notifier 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 // socket doesn't exist; can't create notifier 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 // timeout 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 * We don't have poll(2). We'll have to make do with select(2). 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 // convert the milliseconds to timeval 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 // timeout 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 // simple class to avoid pointer stuff 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 // the really default 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 // found a match 00865 return it.data()->create(parent); 00866 00867 return 0L; // no default 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