File indexing completed on 2023-09-24 04:04:41
0001 /* -*- C++ -*- 0002 * Copyright (C) 2003,2005 Thiago Macieira <thiago@kde.org> 0003 * 0004 * 0005 * Permission is hereby granted, free of charge, to any person obtaining 0006 * a copy of this software and associated documentation files (the 0007 * "Software"), to deal in the Software without restriction, including 0008 * without limitation the rights to use, copy, modify, merge, publish, 0009 * distribute, sublicense, and/or sell copies of the Software, and to 0010 * permit persons to whom the Software is furnished to do so, subject to 0011 * the following conditions: 0012 * 0013 * The above copyright notice and this permission notice shall be included 0014 * in all copies or substantial portions of the Software. 0015 * 0016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 0017 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 0018 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 0019 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 0020 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 0021 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 0022 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 0023 */ 0024 0025 // syssocket.h needs to come before any header that includes k3socketbase.h 0026 #include "syssocket.h" 0027 0028 #include "k3socketdevice.h" //krazy:exclude=includes (KDE3 compat: not worth fixing) 0029 0030 #include <config-network.h> 0031 #include <config-kdelibs4support.h> 0032 0033 #include <QMap> 0034 0035 #if HAVE_SYS_FILIO_H 0036 # include <sys/filio.h> 0037 #endif 0038 #include <sys/types.h> 0039 #include <sys/socket.h> 0040 #include <sys/time.h> 0041 #include <sys/ioctl.h> 0042 #include <errno.h> 0043 #include <fcntl.h> 0044 #include <netinet/in.h> 0045 #include <netinet/tcp.h> // WARNING: verify if this is portable 0046 #include <unistd.h> 0047 0048 #if HAVE_POLL 0049 # include <sys/poll.h> 0050 #else 0051 # if HAVE_SYS_SELECT_H 0052 # include <sys/select.h> 0053 # endif 0054 #endif 0055 0056 #ifdef Q_OS_WIN 0057 #include <windows.h> 0058 #endif 0059 0060 #include <QMutex> 0061 0062 #include "k3resolver.h" 0063 #include "k3socketaddress.h" 0064 using namespace KNetwork; 0065 0066 class KNetwork::KSocketDevicePrivate 0067 { 0068 public: 0069 mutable QSocketNotifier *input, *output, *exception; 0070 KSocketAddress local, peer; 0071 int af; 0072 int proto; 0073 0074 inline KSocketDevicePrivate() 0075 { 0076 input = output = exception = nullptr; 0077 af = proto = 0; 0078 } 0079 }; 0080 0081 KSocketDevice::KSocketDevice(const KSocketBase *parent, QObject *objparent) 0082 : KActiveSocketBase(objparent), m_sockfd(-1), 0083 d(new KSocketDevicePrivate) 0084 { 0085 setSocketDevice(this); 0086 if (parent) { 0087 setSocketOptions(parent->socketOptions()); 0088 } 0089 } 0090 0091 KSocketDevice::KSocketDevice(int fd, OpenMode mode) 0092 : KActiveSocketBase(nullptr), m_sockfd(fd), d(new KSocketDevicePrivate) 0093 { 0094 if (mode) { 0095 mode |= Unbuffered; 0096 } 0097 KActiveSocketBase::open(mode); 0098 setSocketDevice(this); 0099 d->af = localAddress().family(); 0100 } 0101 0102 KSocketDevice::KSocketDevice(QObject *parent) 0103 : KActiveSocketBase(parent), m_sockfd(-1), d(new KSocketDevicePrivate) 0104 { 0105 setSocketDevice(this); 0106 } 0107 0108 KSocketDevice::KSocketDevice(bool, const KSocketBase *parent) 0109 : KActiveSocketBase(nullptr), m_sockfd(-1), d(new KSocketDevicePrivate) 0110 { 0111 // do not set parent 0112 if (parent) { 0113 setSocketOptions(parent->socketOptions()); 0114 } 0115 } 0116 0117 KSocketDevice::~KSocketDevice() 0118 { 0119 close(); // deletes the notifiers 0120 unsetSocketDevice(); // prevent double deletion 0121 delete d; 0122 } 0123 0124 int KSocketDevice::socket() const 0125 { 0126 return m_sockfd; 0127 } 0128 0129 int KSocketDevice::capabilities() const 0130 { 0131 return 0; 0132 } 0133 0134 bool KSocketDevice::setSocketOptions(int opts) 0135 { 0136 // must call parent 0137 QMutexLocker locker(mutex()); 0138 KSocketBase::setSocketOptions(opts); 0139 0140 if (m_sockfd == -1) { 0141 return true; // flags are stored 0142 } 0143 0144 #ifdef Q_OS_WIN 0145 u_long iMode = ((opts & Blocking) == Blocking) ? 0 : 1; 0146 // disable non blocking 0147 if (ioctlsocket(m_sockfd, FIONBIO, &iMode) == SOCKET_ERROR) { 0148 // socket can't made blocking because WSAAsyncSelect/WSAEventSelect (==QSocketNotifier) 0149 // is activated for them 0150 if (WSAGetLastError() == WSAEINVAL) { 0151 return true; 0152 } 0153 qDebug("socket set %s failed %d", iMode ? "nonblocking" : "blocking", GetLastError()); 0154 setError(UnknownError); 0155 return false; // error 0156 } 0157 0158 #else 0159 { 0160 int fdflags = fcntl(m_sockfd, F_GETFL, 0); 0161 if (fdflags == -1) { 0162 setError(UnknownError); 0163 return false; // error 0164 } 0165 0166 if (opts & Blocking) { 0167 fdflags &= ~O_NONBLOCK; 0168 } else { 0169 fdflags |= O_NONBLOCK; 0170 } 0171 0172 if (fcntl(m_sockfd, F_SETFL, fdflags) == -1) { 0173 setError(UnknownError); 0174 return false; // error 0175 } 0176 } 0177 #endif 0178 0179 { 0180 int on = opts & AddressReuseable ? 1 : 0; 0181 if (setsockopt(m_sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) == -1) { 0182 setError(UnknownError); 0183 return false; // error 0184 } 0185 } 0186 0187 #if defined(IPV6_V6ONLY) && defined(AF_INET6) 0188 if (d->af == AF_INET6) { 0189 // don't try this on non-IPv6 sockets, or we'll get an error 0190 0191 int on = opts & IPv6Only ? 1 : 0; 0192 if (setsockopt(m_sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&on, sizeof(on)) == -1) { 0193 setError(UnknownError); 0194 return false; // error 0195 } 0196 } 0197 #endif 0198 0199 { 0200 int on = opts & Broadcast ? 1 : 0; 0201 if (setsockopt(m_sockfd, SOL_SOCKET, SO_BROADCAST, (char *)&on, sizeof(on)) == -1) { 0202 setError(UnknownError); 0203 return false; // error 0204 } 0205 } 0206 0207 if ((d->proto == IPPROTO_TCP || d->proto == 0) && 0208 (d->af == AF_INET 0209 #if defined(AF_INET6) 0210 || d->af == AF_INET6 0211 #endif 0212 )) { 0213 int on = opts & NoDelay ? 1 : 0; 0214 if (setsockopt(m_sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&on, sizeof(on)) == -1) { 0215 setError(UnknownError); 0216 return false; // error 0217 } 0218 } 0219 0220 return true; // all went well 0221 } 0222 0223 void KSocketDevice::close() 0224 { 0225 resetError(); 0226 if (m_sockfd != -1) { 0227 delete d->input; 0228 delete d->output; 0229 delete d->exception; 0230 0231 d->input = d->output = d->exception = nullptr; 0232 #ifdef Q_OS_WIN 0233 ::closesocket(m_sockfd); 0234 #else 0235 d->local.setFamily(AF_UNSPEC); 0236 d->peer.setFamily(AF_UNSPEC); 0237 0238 ::close(m_sockfd); 0239 #endif 0240 } 0241 setOpenMode(NotOpen); // closed 0242 0243 m_sockfd = -1; 0244 } 0245 0246 bool KSocketDevice::flush() 0247 { 0248 return false; 0249 } 0250 0251 bool KSocketDevice::create(int family, int type, int protocol) 0252 { 0253 resetError(); 0254 0255 if (m_sockfd != -1) { 0256 // it's already created! 0257 setError(AlreadyCreated); 0258 return false; 0259 } 0260 0261 // no socket yet; we have to create it 0262 m_sockfd = kde_socket(family, type, protocol); 0263 0264 if (m_sockfd == -1) { 0265 setError(NotSupported); 0266 return false; 0267 } 0268 0269 d->af = family; 0270 d->proto = protocol; 0271 setSocketOptions(socketOptions()); 0272 setOpenMode(Unbuffered); // there's no "Open" flag 0273 return true; // successfully created 0274 } 0275 0276 bool KSocketDevice::create(const KResolverEntry &address) 0277 { 0278 return create(address.family(), address.socketType(), address.protocol()); 0279 } 0280 0281 bool KSocketDevice::bind(const KResolverEntry &address) 0282 { 0283 resetError(); 0284 0285 if (m_sockfd == -1 && !create(address)) { 0286 return false; // failed creating 0287 } 0288 0289 // we have a socket, so try and bind 0290 if (kde_bind(m_sockfd, address.address(), address.length()) == -1) { 0291 if (errno == EADDRINUSE) { 0292 setError(AddressInUse); 0293 return false; 0294 } else if (errno == EINVAL) { 0295 setError(AlreadyBound); 0296 } else { 0297 #ifdef Q_OS_WIN 0298 qDebug(" bind failed: %s ", address.address().toString().toLatin1().constData()); 0299 #endif 0300 // assume the address is the cause 0301 setError(NotSupported); 0302 return false; 0303 } 0304 } 0305 0306 return true; 0307 } 0308 0309 bool KSocketDevice::listen(int backlog) 0310 { 0311 if (m_sockfd != -1) { 0312 if (kde_listen(m_sockfd, backlog) == -1) { 0313 setError(NotSupported); 0314 return false; 0315 } 0316 0317 resetError(); 0318 setOpenMode(QIODevice::Unbuffered | QIODevice::ReadWrite); 0319 return true; 0320 } 0321 0322 // we don't have a socket 0323 // can't listen 0324 setError(NotCreated); 0325 return false; 0326 } 0327 0328 bool KSocketDevice::connect(const KResolverEntry &address, OpenMode mode) 0329 { 0330 resetError(); 0331 0332 if (m_sockfd == -1 && !create(address)) { 0333 return false; // failed creating! 0334 } 0335 0336 if (kde_connect(m_sockfd, address.address(), address.length()) == -1) { 0337 if (errno == EISCONN) { 0338 KActiveSocketBase::open(Unbuffered | mode); 0339 return true; // we're already connected 0340 } else if (errno == EALREADY || errno == EINPROGRESS) { 0341 KActiveSocketBase::open(Unbuffered | mode); 0342 setError(InProgress); 0343 return true; 0344 } else if (errno == ECONNREFUSED) { 0345 setError(ConnectionRefused); 0346 } else if (errno == ENETDOWN || errno == ENETUNREACH || 0347 errno == ENETRESET || errno == ECONNABORTED || 0348 errno == ECONNRESET || errno == EHOSTDOWN || 0349 errno == EHOSTUNREACH) { 0350 setError(NetFailure); 0351 } else { 0352 setError(NotSupported); 0353 } 0354 0355 return false; 0356 } 0357 0358 KActiveSocketBase::open(Unbuffered | mode); 0359 return true; // all is well 0360 } 0361 0362 KSocketDevice *KSocketDevice::accept() 0363 { 0364 if (m_sockfd == -1) { 0365 // can't accept without a socket 0366 setError(NotCreated); 0367 return nullptr; 0368 } 0369 0370 struct sockaddr sa; 0371 socklen_t len = sizeof(sa); 0372 int newfd = kde_accept(m_sockfd, &sa, &len); 0373 if (newfd == -1) { 0374 if (errno == EAGAIN || errno == EWOULDBLOCK) { 0375 setError(WouldBlock); 0376 } else { 0377 setError(UnknownError); 0378 } 0379 return nullptr; 0380 } 0381 0382 return new KSocketDevice(newfd); 0383 } 0384 0385 bool KSocketDevice::disconnect() 0386 { 0387 resetError(); 0388 0389 if (m_sockfd == -1) { 0390 return false; // can't create 0391 } 0392 0393 KSocketAddress address; 0394 address.setFamily(AF_UNSPEC); 0395 if (kde_connect(m_sockfd, address.address(), address.length()) == -1) { 0396 if (errno == EALREADY || errno == EINPROGRESS) { 0397 setError(InProgress); 0398 return false; 0399 } else if (errno == ECONNREFUSED) { 0400 setError(ConnectionRefused); 0401 } else if (errno == ENETDOWN || errno == ENETUNREACH || 0402 errno == ENETRESET || errno == ECONNABORTED || 0403 errno == ECONNRESET || errno == EHOSTDOWN || 0404 errno == EHOSTUNREACH) { 0405 setError(NetFailure); 0406 } else { 0407 setError(NotSupported); 0408 } 0409 0410 return false; 0411 } 0412 0413 setOpenMode(QIODevice::Unbuffered | QIODevice::ReadWrite); 0414 return true; // all is well 0415 } 0416 0417 qint64 KSocketDevice::bytesAvailable() const 0418 { 0419 if (m_sockfd == -1) { 0420 return -1; // there's nothing to read in a closed socket 0421 } 0422 0423 int nchars; 0424 if (kde_ioctl(m_sockfd, FIONREAD, &nchars) == -1) { 0425 return -1; // error! 0426 } 0427 0428 return nchars; 0429 } 0430 0431 qint64 KSocketDevice::waitForMore(int msecs, bool *timeout) 0432 { 0433 if (m_sockfd == -1) { 0434 return -1; // there won't ever be anything to read... 0435 } 0436 0437 bool input; 0438 if (!poll(&input, nullptr, nullptr, msecs, timeout)) { 0439 return -1; // failed polling 0440 } 0441 0442 return bytesAvailable(); 0443 } 0444 0445 static int do_read_common(int sockfd, char *data, qint64 maxlen, KSocketAddress *from, ssize_t &retval, bool peek = false) 0446 { 0447 socklen_t len; 0448 if (from) { 0449 from->setLength(len = 128); // arbitrary length 0450 retval = ::recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, from->address(), &len); 0451 } else { 0452 retval = ::recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, nullptr, nullptr); 0453 } 0454 0455 if (retval == -1) { 0456 #ifdef Q_OS_WIN 0457 if (WSAGetLastError() == WSAEWOULDBLOCK) { 0458 return KSocketDevice::WouldBlock; 0459 } else 0460 #endif 0461 if (errno == EAGAIN || errno == EWOULDBLOCK) { 0462 return KSocketDevice::WouldBlock; 0463 } else { 0464 return KSocketDevice::UnknownError; 0465 } 0466 } 0467 if (retval == 0) { 0468 return KSocketDevice::RemotelyDisconnected; 0469 } 0470 0471 if (from) { 0472 from->setLength(len); 0473 } 0474 return 0; 0475 } 0476 0477 qint64 KSocketDevice::readData(char *data, qint64 maxlen, KSocketAddress *from) 0478 { 0479 resetError(); 0480 if (m_sockfd == -1) { 0481 return -1; // nothing to do here 0482 } 0483 0484 if (data == nullptr || maxlen == 0) { 0485 return 0; // user doesn't want to read 0486 } 0487 0488 ssize_t retval; 0489 int err = do_read_common(m_sockfd, data, maxlen, from, retval); 0490 0491 if (err) { 0492 setError(static_cast<SocketError>(err)); 0493 return -1; 0494 } 0495 0496 return retval; 0497 } 0498 0499 qint64 KSocketDevice::peekData(char *data, qint64 maxlen, KSocketAddress *from) 0500 { 0501 resetError(); 0502 if (m_sockfd == -1) { 0503 return -1; // nothing to do here 0504 } 0505 0506 if (data == nullptr || maxlen == 0) { 0507 return 0; // user doesn't want to read 0508 } 0509 0510 ssize_t retval; 0511 int err = do_read_common(m_sockfd, data, maxlen, from, retval, true); 0512 0513 if (err) { 0514 setError(static_cast<SocketError>(err)); 0515 return -1; 0516 } 0517 0518 return retval; 0519 } 0520 0521 qint64 KSocketDevice::writeData(const char *data, qint64 len, const KSocketAddress *to) 0522 { 0523 resetError(); 0524 if (m_sockfd == -1) { 0525 return -1; // can't write to unopen socket 0526 } 0527 0528 if (data == nullptr || len == 0) { 0529 return 0; // nothing to be written 0530 } 0531 0532 ssize_t retval; 0533 if (to != nullptr) { 0534 retval = ::sendto(m_sockfd, data, len, 0, to->address(), to->length()); 0535 } else 0536 #ifdef Q_OS_WIN 0537 retval = ::send(m_sockfd, data, len, 0); 0538 #else 0539 retval = ::write(m_sockfd, data, len); 0540 #endif 0541 if (retval == -1) { 0542 if (errno == EAGAIN || errno == EWOULDBLOCK) { 0543 setError(WouldBlock); 0544 } else { 0545 setError(UnknownError); 0546 } 0547 return -1; // nothing written 0548 } else if (retval == 0) { 0549 setError(RemotelyDisconnected); 0550 } 0551 0552 return retval; 0553 } 0554 0555 KSocketAddress KSocketDevice::localAddress() const 0556 { 0557 if (m_sockfd == -1) { 0558 return KSocketAddress(); // not open, empty value 0559 } 0560 0561 if (d->local.family() != AF_UNSPEC) { 0562 return d->local; 0563 } 0564 0565 socklen_t len; 0566 KSocketAddress localAddress; 0567 localAddress.setLength(len = 32); // arbitrary value 0568 if (kde_getsockname(m_sockfd, localAddress.address(), &len) == -1) 0569 // error! 0570 { 0571 return d->local = KSocketAddress(); 0572 } 0573 0574 #if HAVE_STRUCT_SOCKADDR_SA_LEN 0575 len = localAddress.address()->sa_len; 0576 #endif 0577 0578 if (len <= localAddress.length()) { 0579 // it has fit already 0580 localAddress.setLength(len); 0581 return d->local = localAddress; 0582 } 0583 0584 // no, the socket address is actually larger than we had anticipated 0585 // call again 0586 localAddress.setLength(len); 0587 if (kde_getsockname(m_sockfd, localAddress.address(), &len) == -1) 0588 // error! 0589 { 0590 return d->local = KSocketAddress(); 0591 } 0592 0593 return d->local = localAddress; 0594 } 0595 0596 KSocketAddress KSocketDevice::peerAddress() const 0597 { 0598 if (m_sockfd == -1) { 0599 return KSocketAddress(); // not open, empty value 0600 } 0601 0602 if (d->peer.family() != AF_UNSPEC) { 0603 return d->peer; 0604 } 0605 0606 socklen_t len; 0607 KSocketAddress peerAddress; 0608 peerAddress.setLength(len = 32); // arbitrary value 0609 if (kde_getpeername(m_sockfd, peerAddress.address(), &len) == -1) 0610 // error! 0611 { 0612 return d->peer = KSocketAddress(); 0613 } 0614 0615 #if HAVE_STRUCT_SOCKADDR_SA_LEN 0616 len = peerAddress.address()->sa_len; 0617 #endif 0618 0619 if (len <= peerAddress.length()) { 0620 // it has fit already 0621 peerAddress.setLength(len); 0622 return d->peer = peerAddress; 0623 } 0624 0625 // no, the socket address is actually larger than we had anticipated 0626 // call again 0627 peerAddress.setLength(len); 0628 if (kde_getpeername(m_sockfd, peerAddress.address(), &len) == -1) 0629 // error! 0630 { 0631 return d->peer = KSocketAddress(); 0632 } 0633 0634 return d->peer = peerAddress; 0635 } 0636 0637 KSocketAddress KSocketDevice::externalAddress() const 0638 { 0639 // for normal sockets, the externally visible address is the same 0640 // as the local address 0641 return localAddress(); 0642 } 0643 0644 QSocketNotifier *KSocketDevice::readNotifier() const 0645 { 0646 if (d->input) { 0647 return d->input; 0648 } 0649 0650 QMutexLocker locker(mutex()); 0651 if (d->input) { 0652 return d->input; 0653 } 0654 0655 if (m_sockfd == -1) { 0656 // socket doesn't exist; can't create notifier 0657 return nullptr; 0658 } 0659 0660 return d->input = createNotifier(QSocketNotifier::Read); 0661 } 0662 0663 QSocketNotifier *KSocketDevice::writeNotifier() const 0664 { 0665 if (d->output) { 0666 return d->output; 0667 } 0668 0669 QMutexLocker locker(mutex()); 0670 if (d->output) { 0671 return d->output; 0672 } 0673 0674 if (m_sockfd == -1) { 0675 // socket doesn't exist; can't create notifier 0676 return nullptr; 0677 } 0678 0679 return d->output = createNotifier(QSocketNotifier::Write); 0680 } 0681 0682 QSocketNotifier *KSocketDevice::exceptionNotifier() const 0683 { 0684 if (d->exception) { 0685 return d->exception; 0686 } 0687 0688 QMutexLocker locker(mutex()); 0689 if (d->exception) { 0690 return d->exception; 0691 } 0692 0693 if (m_sockfd == -1) { 0694 // socket doesn't exist; can't create notifier 0695 return nullptr; 0696 } 0697 0698 return d->exception = createNotifier(QSocketNotifier::Exception); 0699 } 0700 0701 bool KSocketDevice::poll(bool *input, bool *output, bool *exception, 0702 int timeout, bool *timedout) 0703 { 0704 if (m_sockfd == -1) { 0705 setError(NotCreated); 0706 return false; 0707 } 0708 0709 resetError(); 0710 #if HAVE_POLL 0711 struct pollfd fds; 0712 fds.fd = m_sockfd; 0713 fds.events = 0; 0714 0715 if (input) { 0716 fds.events |= POLLIN; 0717 *input = false; 0718 } 0719 if (output) { 0720 fds.events |= POLLOUT; 0721 *output = false; 0722 } 0723 if (exception) { 0724 fds.events |= POLLPRI; 0725 *exception = false; 0726 } 0727 0728 int retval = ::poll(&fds, 1, timeout); 0729 if (retval == -1) { 0730 setError(UnknownError); 0731 return false; 0732 } 0733 if (retval == 0) { 0734 // timeout 0735 if (timedout) { 0736 *timedout = true; 0737 } 0738 return true; 0739 } 0740 0741 if (input && fds.revents & POLLIN) { 0742 *input = true; 0743 } 0744 if (output && fds.revents & POLLOUT) { 0745 *output = true; 0746 } 0747 if (exception && fds.revents & POLLPRI) { 0748 *exception = true; 0749 } 0750 if (timedout) { 0751 *timedout = false; 0752 } 0753 0754 return true; 0755 #else 0756 /* 0757 * We don't have poll(2). We'll have to make do with select(2). 0758 */ 0759 0760 fd_set readfds, writefds, exceptfds; 0761 fd_set *preadfds = 0L, *pwritefds = 0L, *pexceptfds = 0L; 0762 0763 if (input) { 0764 preadfds = &readfds; 0765 FD_ZERO(preadfds); 0766 FD_SET(m_sockfd, preadfds); 0767 *input = false; 0768 } 0769 if (output) { 0770 pwritefds = &writefds; 0771 FD_ZERO(pwritefds); 0772 FD_SET(m_sockfd, pwritefds); 0773 *output = false; 0774 } 0775 if (exception) { 0776 pexceptfds = &exceptfds; 0777 FD_ZERO(pexceptfds); 0778 FD_SET(m_sockfd, pexceptfds); 0779 *exception = false; 0780 } 0781 0782 int retval; 0783 if (timeout < 0) { 0784 retval = select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, 0L); 0785 } else { 0786 // convert the milliseconds to timeval 0787 struct timeval tv; 0788 tv.tv_sec = timeout / 1000; 0789 tv.tv_usec = timeout % 1000 * 1000; 0790 0791 retval = select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, &tv); 0792 } 0793 0794 if (retval == -1) { 0795 setError(UnknownError); 0796 return false; 0797 } 0798 if (retval == 0) { 0799 // timeout 0800 if (timedout) { 0801 *timedout = true; 0802 } 0803 return true; 0804 } 0805 0806 if (input && FD_ISSET(m_sockfd, preadfds)) { 0807 *input = true; 0808 } 0809 if (output && FD_ISSET(m_sockfd, pwritefds)) { 0810 *output = true; 0811 } 0812 if (exception && FD_ISSET(m_sockfd, pexceptfds)) { 0813 *exception = true; 0814 } 0815 0816 return true; 0817 #endif 0818 } 0819 0820 bool KSocketDevice::poll(int timeout, bool *timedout) 0821 { 0822 bool input, output, exception; 0823 return poll(&input, &output, &exception, timeout, timedout); 0824 } 0825 0826 QSocketNotifier *KSocketDevice::createNotifier(QSocketNotifier::Type type) const 0827 { 0828 if (m_sockfd == -1) { 0829 return nullptr; 0830 } 0831 0832 return new QSocketNotifier(m_sockfd, type); 0833 } 0834 0835 namespace 0836 { 0837 // simple class to avoid pointer stuff 0838 template<class T> class ptr 0839 { 0840 typedef T type; 0841 type *obj; 0842 public: 0843 ptr() : obj(0) 0844 { } 0845 0846 ptr(const ptr<T> &other) : obj(other.obj) 0847 { } 0848 0849 ptr(type *_obj) : obj(_obj) 0850 { } 0851 0852 ~ptr() 0853 { } 0854 0855 ptr<T> &operator=(const ptr<T> &other) 0856 { 0857 obj = other.obj; 0858 return *this; 0859 } 0860 0861 ptr<T> &operator=(T *_obj) 0862 { 0863 obj = _obj; 0864 return *this; 0865 } 0866 0867 type *operator->() const 0868 { 0869 return obj; 0870 } 0871 0872 operator T *() const 0873 { 0874 return obj; 0875 } 0876 0877 bool isNull() const 0878 { 0879 return obj == 0; 0880 } 0881 }; 0882 } 0883 0884 static KSocketDeviceFactoryBase *defaultImplFactory; 0885 static QMutex defaultImplFactoryMutex; 0886 typedef QMap<int, KSocketDeviceFactoryBase * > factoryMap; 0887 static factoryMap factories; 0888 0889 KSocketDevice *KSocketDevice::createDefault(KSocketBase *parent) 0890 { 0891 KSocketDevice *device = dynamic_cast<KSocketDevice *>(parent); 0892 if (device != nullptr) { 0893 return device; 0894 } 0895 0896 if (defaultImplFactory) { 0897 return defaultImplFactory->create(parent); 0898 } 0899 0900 // the really default 0901 return new KSocketDevice(parent); 0902 } 0903 0904 KSocketDevice *KSocketDevice::createDefault(KSocketBase *parent, int capabilities) 0905 { 0906 KSocketDevice *device = dynamic_cast<KSocketDevice *>(parent); 0907 if (device != nullptr) { 0908 return device; 0909 } 0910 0911 QMutexLocker locker(&defaultImplFactoryMutex); 0912 factoryMap::ConstIterator it = factories.constBegin(); 0913 for (; it != factories.constEnd(); ++it) 0914 if ((it.key() & capabilities) == capabilities) 0915 // found a match 0916 { 0917 return it.value()->create(parent); 0918 } 0919 0920 return nullptr; // no default 0921 } 0922 0923 KSocketDeviceFactoryBase * 0924 KSocketDevice::setDefaultImpl(KSocketDeviceFactoryBase *factory) 0925 { 0926 QMutexLocker locker(&defaultImplFactoryMutex); 0927 KSocketDeviceFactoryBase *old = defaultImplFactory; 0928 defaultImplFactory = factory; 0929 return old; 0930 } 0931 0932 void KSocketDevice::addNewImpl(KSocketDeviceFactoryBase *factory, int capabilities) 0933 { 0934 QMutexLocker locker(&defaultImplFactoryMutex); 0935 if (factories.contains(capabilities)) { 0936 delete factories[capabilities]; 0937 } 0938 factories.insert(capabilities, factory); 0939 } 0940