KDECore
k3socketdevice.cpp
Go to the documentation of this file.
00001 /* -*- C++ -*- 00002 * Copyright (C) 2003,2005 Thiago Macieira <thiago@kde.org> 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 // syssocket.h needs to come before any header that includes k3socketbase.h 00026 #include "syssocket.h" 00027 00028 #include "k3socketdevice.h" //krazy:exclude=includes (KDE3 compat: not worth fixing) 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> // WARNING: verify if this is portable 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 // do not set parent 00116 if (parent) 00117 setSocketOptions(parent->socketOptions()); 00118 } 00119 00120 KSocketDevice::~KSocketDevice() 00121 { 00122 close(); // deletes the notifiers 00123 unsetSocketDevice(); // prevent double deletion 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 // must call parent 00140 QMutexLocker locker(mutex()); 00141 KSocketBase::setSocketOptions(opts); 00142 00143 if (m_sockfd == -1) 00144 return true; // flags are stored 00145 00146 #ifdef Q_WS_WIN 00147 u_long iMode = ((opts & Blocking) == Blocking) ? 0 : 1; 00148 // disable non blocking 00149 if (ioctlsocket(m_sockfd, FIONBIO, &iMode) == SOCKET_ERROR) 00150 { 00151 // socket can't made blocking because WSAAsyncSelect/WSAEventSelect (==QSocketNotifier) 00152 // is activated for them 00153 if(WSAGetLastError() == WSAEINVAL) 00154 return true; 00155 qDebug("socket set %s failed %d", iMode ? "nonblocking" : "blocking", GetLastError()); 00156 setError(UnknownError); 00157 return false; // error 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; // error 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; // error 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; // error 00188 } 00189 } 00190 00191 #if defined(IPV6_V6ONLY) && defined(AF_INET6) 00192 if (d->af == AF_INET6) 00193 { 00194 // don't try this on non-IPv6 sockets, or we'll get an error 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; // error 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; // error 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; // error 00226 } 00227 } 00228 00229 return true; // all went well 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); // closed 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 // it's already created! 00268 setError(AlreadyCreated); 00269 return false; 00270 } 00271 00272 // no socket yet; we have to create it 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); // there's no "Open" flag 00285 return true; // successfully created 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; // failed creating 00299 00300 // we have a socket, so try and bind 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 // assume the address is the cause 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 // we don't have a socket 00340 // can't listen 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; // failed creating! 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; // we're already connected 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; // all is well 00380 } 00381 00382 KSocketDevice* KSocketDevice::accept() 00383 { 00384 if (m_sockfd == -1) 00385 { 00386 // can't accept without a socket 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; // can't create 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; // all is well 00437 } 00438 00439 qint64 KSocketDevice::bytesAvailable() const 00440 { 00441 if (m_sockfd == -1) 00442 return -1; // there's nothing to read in a closed socket 00443 00444 int nchars; 00445 if (kde_ioctl(m_sockfd, FIONREAD, &nchars) == -1) 00446 return -1; // error! 00447 00448 return nchars; 00449 } 00450 00451 qint64 KSocketDevice::waitForMore(int msecs, bool *timeout) 00452 { 00453 if (m_sockfd == -1) 00454 return -1; // there won't ever be anything to read... 00455 00456 bool input; 00457 if (!poll(&input, 0, 0, msecs, timeout)) 00458 return -1; // failed polling 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); // arbitrary length 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; // nothing to do here 00499 00500 if (data == 0L || maxlen == 0) 00501 return 0; // user doesn't want to read 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; // nothing to do here 00520 00521 if (data == 0L || maxlen == 0) 00522 return 0; // user doesn't want to read 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; // can't write to unopen socket 00541 00542 if (data == 0L || len == 0) 00543 return 0; // nothing to be written 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; // nothing written 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(); // not open, empty value 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); // arbitrary value 00579 if (kde_getsockname(m_sockfd, localAddress.address(), &len) == -1) 00580 // error! 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 // it has fit already 00590 localAddress.setLength(len); 00591 return d->local = localAddress; 00592 } 00593 00594 // no, the socket address is actually larger than we had anticipated 00595 // call again 00596 localAddress.setLength(len); 00597 if (kde_getsockname(m_sockfd, localAddress.address(), &len) == -1) 00598 // error! 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(); // not open, empty value 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); // arbitrary value 00615 if (kde_getpeername(m_sockfd, peerAddress.address(), &len) == -1) 00616 // error! 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 // it has fit already 00626 peerAddress.setLength(len); 00627 return d->peer = peerAddress; 00628 } 00629 00630 // no, the socket address is actually larger than we had anticipated 00631 // call again 00632 peerAddress.setLength(len); 00633 if (kde_getpeername(m_sockfd, peerAddress.address(), &len) == -1) 00634 // error! 00635 return d->peer = KSocketAddress(); 00636 00637 return d->peer = peerAddress; 00638 } 00639 00640 KSocketAddress KSocketDevice::externalAddress() const 00641 { 00642 // for normal sockets, the externally visible address is the same 00643 // as the local address 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 // socket doesn't exist; can't create notifier 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 // socket doesn't exist; can't create notifier 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 // socket doesn't exist; can't create notifier 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 // timeout 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 * We don't have poll(2). We'll have to make do with select(2). 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 // convert the milliseconds to timeval 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 // timeout 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 // simple class to avoid pointer stuff 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 // the really default 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 // found a match 00901 return it.value()->create(parent); 00902 00903 return 0L; // no default 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
KDE 4.6 API Reference