tdesocketdevice.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 <tqmap.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 <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 <tqmutex.h> 00053 #include <tqsocketnotifier.h> 00054 00055 #include "kresolver.h" 00056 #include "tdesocketaddress.h" 00057 #include "tdesocketbase.h" 00058 #include "tdesocketdevice.h" 00059 #include "ksockssocketdevice.h" 00060 00061 using namespace KNetwork; 00062 00063 class KNetwork::TDESocketDevicePrivate 00064 { 00065 public: 00066 mutable TQSocketNotifier *input, *output, *exception; 00067 TDESocketAddress local, peer; 00068 int af; 00069 00070 inline TDESocketDevicePrivate() 00071 { 00072 input = output = exception = 0L; 00073 af = 0; 00074 } 00075 }; 00076 00077 00078 TDESocketDevice::TDESocketDevice(const TDESocketBase* parent) 00079 : m_sockfd(-1), d(new TDESocketDevicePrivate) 00080 { 00081 setSocketDevice(this); 00082 if (parent) 00083 setSocketOptions(parent->socketOptions()); 00084 } 00085 00086 TDESocketDevice::TDESocketDevice(int fd) 00087 : m_sockfd(fd), d(new TDESocketDevicePrivate) 00088 { 00089 setState(IO_Open); 00090 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite); 00091 setSocketDevice(this); 00092 d->af = localAddress().family(); 00093 } 00094 00095 TDESocketDevice::TDESocketDevice(bool, const TDESocketBase* parent) 00096 : m_sockfd(-1), d(new TDESocketDevicePrivate) 00097 { 00098 // do not set parent 00099 if (parent) 00100 setSocketOptions(parent->socketOptions()); 00101 } 00102 00103 TDESocketDevice::~TDESocketDevice() 00104 { 00105 close(); // deletes the notifiers 00106 unsetSocketDevice(); // prevent double deletion 00107 delete d; 00108 } 00109 00110 bool TDESocketDevice::setSocketOptions(int opts) 00111 { 00112 // must call parent 00113 TQMutexLocker locker(mutex()); 00114 TDESocketBase::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 TDESocketDevice::open(TQ_OpenMode) 00175 { 00176 resetError(); 00177 return false; 00178 } 00179 00180 void TDESocketDevice::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 TDESocketDevice::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 TDESocketDevice::create(const KResolverEntry& address) 00228 { 00229 return create(address.family(), address.socketType(), address.protocol()); 00230 } 00231 00232 bool TDESocketDevice::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 TDESocketDevice::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 TDESocketDevice::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 TDESocketDevice* TDESocketDevice::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 TDESocketDevice(newfd); 00331 } 00332 00333 bool TDESocketDevice::disconnect() 00334 { 00335 resetError(); 00336 00337 if (m_sockfd == -1) 00338 return false; // can't create 00339 00340 TDESocketAddress 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 #ifdef USE_QT3 00368 TQ_LONG TDESocketDevice::bytesAvailable() const 00369 #endif 00370 #ifdef USE_QT4 00371 qint64 TDESocketDevice::bytesAvailable() const 00372 #endif 00373 { 00374 if (m_sockfd == -1) 00375 return -1; // there's nothing to read in a closed socket 00376 00377 int nchars; 00378 if (ioctl(m_sockfd, FIONREAD, &nchars) == -1) 00379 return -1; // error! 00380 00381 return nchars; 00382 } 00383 00384 TQ_LONG TDESocketDevice::waitForMore(int msecs, bool *timeout) 00385 { 00386 if (m_sockfd == -1) 00387 return -1; // there won't ever be anything to read... 00388 00389 bool input; 00390 if (!poll(&input, 0, 0, msecs, timeout)) 00391 return -1; // failed polling 00392 00393 return bytesAvailable(); 00394 } 00395 00396 static int do_read_common(int sockfd, char *data, TQ_ULONG maxlen, TDESocketAddress* from, ssize_t &retval, bool peek = false) 00397 { 00398 socklen_t len; 00399 if (from) 00400 { 00401 from->setLength(len = 128); // arbitrary length 00402 retval = ::recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, from->address(), &len); 00403 } 00404 else 00405 retval = ::recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, NULL, NULL); 00406 00407 if (retval == -1) 00408 { 00409 if (errno == EAGAIN || errno == EWOULDBLOCK) 00410 return TDESocketDevice::WouldBlock; 00411 else 00412 return TDESocketDevice::UnknownError; 00413 } 00414 if (retval == 0) 00415 return TDESocketDevice::RemotelyDisconnected; 00416 00417 if (from) 00418 from->setLength(len); 00419 return 0; 00420 } 00421 00422 TQT_TQIO_LONG TDESocketDevice::tqreadBlock(char *data, TQT_TQIO_ULONG maxlen) 00423 { 00424 resetError(); 00425 if (m_sockfd == -1) 00426 return -1; 00427 00428 if (maxlen == 0 || data == 0L) 00429 return 0; // can't read 00430 00431 ssize_t retval; 00432 int err = do_read_common(m_sockfd, data, maxlen, 0L, retval); 00433 00434 if (err) 00435 { 00436 setError(IO_ReadError, static_cast<SocketError>(err)); 00437 return -1; 00438 } 00439 00440 return retval; 00441 } 00442 00443 TQT_TQIO_LONG TDESocketDevice::tqreadBlock(char *data, TQT_TQIO_ULONG maxlen, TDESocketAddress &from) 00444 { 00445 resetError(); 00446 if (m_sockfd == -1) 00447 return -1; // nothing to do here 00448 00449 if (data == 0L || maxlen == 0) 00450 return 0; // user doesn't want to read 00451 00452 ssize_t retval; 00453 int err = do_read_common(m_sockfd, data, maxlen, &from, retval); 00454 00455 if (err) 00456 { 00457 setError(IO_ReadError, static_cast<SocketError>(err)); 00458 return -1; 00459 } 00460 00461 return retval; 00462 } 00463 00464 TQ_LONG TDESocketDevice::peekBlock(char *data, TQ_ULONG maxlen) 00465 { 00466 resetError(); 00467 if (m_sockfd == -1) 00468 return -1; 00469 00470 if (maxlen == 0 || data == 0L) 00471 return 0; // can't read 00472 00473 ssize_t retval; 00474 int err = do_read_common(m_sockfd, data, maxlen, 0L, retval, true); 00475 00476 if (err) 00477 { 00478 setError(IO_ReadError, static_cast<SocketError>(err)); 00479 return -1; 00480 } 00481 00482 return retval; 00483 } 00484 00485 TQ_LONG TDESocketDevice::peekBlock(char *data, TQ_ULONG maxlen, TDESocketAddress& from) 00486 { 00487 resetError(); 00488 if (m_sockfd == -1) 00489 return -1; // nothing to do here 00490 00491 if (data == 0L || maxlen == 0) 00492 return 0; // user doesn't want to read 00493 00494 ssize_t retval; 00495 int err = do_read_common(m_sockfd, data, maxlen, &from, retval, true); 00496 00497 if (err) 00498 { 00499 setError(IO_ReadError, static_cast<SocketError>(err)); 00500 return -1; 00501 } 00502 00503 return retval; 00504 } 00505 00506 TQT_TQIO_LONG TDESocketDevice::tqwriteBlock(const char *data, TQT_TQIO_ULONG len) 00507 { 00508 return tqwriteBlock(data, len, TDESocketAddress()); 00509 } 00510 00511 TQT_TQIO_LONG TDESocketDevice::tqwriteBlock(const char *data, TQT_TQIO_ULONG len, const TDESocketAddress& to) 00512 { 00513 resetError(); 00514 if (m_sockfd == -1) 00515 return -1; // can't write to unopen socket 00516 00517 if (data == 0L || len == 0) 00518 return 0; // nothing to be written 00519 00520 ssize_t retval = ::sendto(m_sockfd, data, len, 0, to.address(), to.length()); 00521 if (retval == -1) 00522 { 00523 if (errno == EAGAIN || errno == EWOULDBLOCK) 00524 setError(IO_WriteError, WouldBlock); 00525 else 00526 setError(IO_WriteError, UnknownError); 00527 return -1; // nothing written 00528 } 00529 else if (retval == 0) 00530 setError(IO_WriteError, RemotelyDisconnected); 00531 00532 return retval; 00533 } 00534 00535 TDESocketAddress TDESocketDevice::localAddress() const 00536 { 00537 if (m_sockfd == -1) 00538 return TDESocketAddress(); // not open, empty value 00539 00540 if (d->local.family() != AF_UNSPEC) 00541 return d->local; 00542 00543 socklen_t len; 00544 TDESocketAddress localAddress; 00545 localAddress.setLength(len = 32); // arbitrary value 00546 if (kde_getsockname(m_sockfd, localAddress.address(), &len) == -1) 00547 // error! 00548 return d->local = TDESocketAddress(); 00549 00550 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 00551 len = localAddress.address()->sa_len; 00552 #endif 00553 00554 if (len <= localAddress.length()) 00555 { 00556 // it has fit already 00557 localAddress.setLength(len); 00558 return d->local = localAddress; 00559 } 00560 00561 // no, the socket address is actually larger than we had anticipated 00562 // call again 00563 localAddress.setLength(len); 00564 if (kde_getsockname(m_sockfd, localAddress.address(), &len) == -1) 00565 // error! 00566 return d->local = TDESocketAddress(); 00567 00568 return d->local = localAddress; 00569 } 00570 00571 TDESocketAddress TDESocketDevice::peerAddress() const 00572 { 00573 if (m_sockfd == -1) 00574 return TDESocketAddress(); // not open, empty value 00575 00576 if (d->peer.family() != AF_UNSPEC) 00577 return d->peer; 00578 00579 socklen_t len; 00580 TDESocketAddress peerAddress; 00581 peerAddress.setLength(len = 32); // arbitrary value 00582 if (kde_getpeername(m_sockfd, peerAddress.address(), &len) == -1) 00583 // error! 00584 return d->peer = TDESocketAddress(); 00585 00586 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 00587 len = peerAddress.address()->sa_len; 00588 #endif 00589 00590 if (len <= peerAddress.length()) 00591 { 00592 // it has fit already 00593 peerAddress.setLength(len); 00594 return d->peer = peerAddress; 00595 } 00596 00597 // no, the socket address is actually larger than we had anticipated 00598 // call again 00599 peerAddress.setLength(len); 00600 if (kde_getpeername(m_sockfd, peerAddress.address(), &len) == -1) 00601 // error! 00602 return d->peer = TDESocketAddress(); 00603 00604 return d->peer = peerAddress; 00605 } 00606 00607 TDESocketAddress TDESocketDevice::externalAddress() const 00608 { 00609 // for normal sockets, the externally visible address is the same 00610 // as the local address 00611 return localAddress(); 00612 } 00613 00614 TQSocketNotifier* TDESocketDevice::readNotifier() const 00615 { 00616 if (d->input) 00617 return d->input; 00618 00619 TQMutexLocker locker(mutex()); 00620 if (d->input) 00621 return d->input; 00622 00623 if (m_sockfd == -1) 00624 { 00625 // socket doesn't exist; can't create notifier 00626 return 0L; 00627 } 00628 00629 return d->input = createNotifier(TQSocketNotifier::Read); 00630 } 00631 00632 TQSocketNotifier* TDESocketDevice::writeNotifier() const 00633 { 00634 if (d->output) 00635 return d->output; 00636 00637 TQMutexLocker locker(mutex()); 00638 if (d->output) 00639 return d->output; 00640 00641 if (m_sockfd == -1) 00642 { 00643 // socket doesn't exist; can't create notifier 00644 return 0L; 00645 } 00646 00647 return d->output = createNotifier(TQSocketNotifier::Write); 00648 } 00649 00650 TQSocketNotifier* TDESocketDevice::exceptionNotifier() const 00651 { 00652 if (d->exception) 00653 return d->exception; 00654 00655 TQMutexLocker locker(mutex()); 00656 if (d->exception) 00657 return d->exception; 00658 00659 if (m_sockfd == -1) 00660 { 00661 // socket doesn't exist; can't create notifier 00662 return 0L; 00663 } 00664 00665 return d->exception = createNotifier(TQSocketNotifier::Exception); 00666 } 00667 00668 bool TDESocketDevice::poll(bool *input, bool *output, bool *exception, 00669 int timeout, bool* timedout) 00670 { 00671 if (m_sockfd == -1) 00672 { 00673 setError(IO_UnspecifiedError, NotCreated); 00674 return false; 00675 } 00676 00677 resetError(); 00678 #ifdef HAVE_POLL 00679 struct pollfd fds; 00680 fds.fd = m_sockfd; 00681 fds.events = 0; 00682 00683 if (input) 00684 { 00685 fds.events |= POLLIN; 00686 *input = false; 00687 } 00688 if (output) 00689 { 00690 fds.events |= POLLOUT; 00691 *output = false; 00692 } 00693 if (exception) 00694 { 00695 fds.events |= POLLPRI; 00696 *exception = false; 00697 } 00698 00699 int retval = ::poll(&fds, 1, timeout); 00700 if (retval == -1) 00701 { 00702 setError(IO_UnspecifiedError, UnknownError); 00703 return false; 00704 } 00705 if (retval == 0) 00706 { 00707 // timeout 00708 if (timedout) 00709 *timedout = true; 00710 return true; 00711 } 00712 00713 if (input && fds.revents & POLLIN) 00714 *input = true; 00715 if (output && fds.revents & POLLOUT) 00716 *output = true; 00717 if (exception && fds.revents & POLLPRI) 00718 *exception = true; 00719 if (timedout) 00720 *timedout = false; 00721 00722 return true; 00723 #else 00724 /* 00725 * We don't have poll(2). We'll have to make do with select(2). 00726 */ 00727 00728 fd_set readfds, writefds, exceptfds; 00729 fd_set *preadfds = 0L, *pwritefds = 0L, *pexceptfds = 0L; 00730 00731 if (input) 00732 { 00733 preadfds = &readfds; 00734 FD_ZERO(preadfds); 00735 FD_SET(m_sockfd, preadfds); 00736 *input = false; 00737 } 00738 if (output) 00739 { 00740 pwritefds = &writefds; 00741 FD_ZERO(pwritefds); 00742 FD_SET(m_sockfd, pwritefds); 00743 *output = false; 00744 } 00745 if (exception) 00746 { 00747 pexceptfds = &exceptfds; 00748 FD_ZERO(pexceptfds); 00749 FD_SET(m_sockfd, pexceptfds); 00750 *exception = false; 00751 } 00752 00753 int retval; 00754 if (timeout < 0) 00755 retval = select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, 0L); 00756 else 00757 { 00758 // convert the milliseconds to timeval 00759 struct timeval tv; 00760 tv.tv_sec = timeout / 1000; 00761 tv.tv_usec = timeout % 1000 * 1000; 00762 00763 retval = select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, &tv); 00764 } 00765 00766 if (retval == -1) 00767 { 00768 setError(IO_UnspecifiedError, UnknownError); 00769 return false; 00770 } 00771 if (retval == 0) 00772 { 00773 // timeout 00774 if (timedout) 00775 *timedout = true; 00776 return true; 00777 } 00778 00779 if (input && FD_ISSET(m_sockfd, preadfds)) 00780 *input = true; 00781 if (output && FD_ISSET(m_sockfd, pwritefds)) 00782 *output = true; 00783 if (exception && FD_ISSET(m_sockfd, pexceptfds)) 00784 *exception = true; 00785 00786 return true; 00787 #endif 00788 } 00789 00790 bool TDESocketDevice::poll(int timeout, bool *timedout) 00791 { 00792 bool input, output, exception; 00793 return poll(&input, &output, &exception, timeout, timedout); 00794 } 00795 00796 TQSocketNotifier* TDESocketDevice::createNotifier(TQSocketNotifier::Type type) const 00797 { 00798 if (m_sockfd == -1) 00799 return 0L; 00800 00801 return new TQSocketNotifier(m_sockfd, type); 00802 } 00803 00804 namespace 00805 { 00806 // simple class to avoid pointer stuff 00807 template<class T> class ptr 00808 { 00809 typedef T type; 00810 type* obj; 00811 public: 00812 ptr() : obj(0) 00813 { } 00814 00815 ptr(const ptr<T>& other) : obj(other.obj) 00816 { } 00817 00818 ptr(type* _obj) : obj(_obj) 00819 { } 00820 00821 ~ptr() 00822 { } 00823 00824 ptr<T>& operator=(const ptr<T>& other) 00825 { obj = other.obj; return *this; } 00826 00827 ptr<T>& operator=(T* _obj) 00828 { obj = _obj; return *this; } 00829 00830 type* operator->() const { return obj; } 00831 00832 operator T*() const { return obj; } 00833 00834 bool isNull() const 00835 { return obj == 0; } 00836 }; 00837 } 00838 00839 static TDESocketDeviceFactoryBase* defaultImplFactory; 00840 static TQMutex defaultImplFactoryMutex; 00841 typedef TQMap<int, TDESocketDeviceFactoryBase* > factoryMap; 00842 static factoryMap factories; 00843 00844 TDESocketDevice* TDESocketDevice::createDefault(TDESocketBase* parent) 00845 { 00846 TDESocketDevice* device = dynamic_cast<TDESocketDevice*>(parent); 00847 if (device != 0L) 00848 return device; 00849 00850 KSocksSocketDevice::initSocks(); 00851 00852 if (defaultImplFactory) 00853 return defaultImplFactory->create(parent); 00854 00855 // the really default 00856 return new TDESocketDevice(parent); 00857 } 00858 00859 TDESocketDevice* TDESocketDevice::createDefault(TDESocketBase* parent, int capabilities) 00860 { 00861 TDESocketDevice* device = dynamic_cast<TDESocketDevice*>(parent); 00862 if (device != 0L) 00863 return device; 00864 00865 TQMutexLocker locker(&defaultImplFactoryMutex); 00866 factoryMap::ConstIterator it = factories.constBegin(); 00867 for ( ; it != factories.constEnd(); ++it) 00868 if ((it.key() & capabilities) == capabilities) 00869 // found a match 00870 return it.data()->create(parent); 00871 00872 return 0L; // no default 00873 } 00874 00875 TDESocketDeviceFactoryBase* 00876 TDESocketDevice::setDefaultImpl(TDESocketDeviceFactoryBase* factory) 00877 { 00878 TQMutexLocker locker(&defaultImplFactoryMutex); 00879 TDESocketDeviceFactoryBase* old = defaultImplFactory; 00880 defaultImplFactory = factory; 00881 return old; 00882 } 00883 00884 void TDESocketDevice::addNewImpl(TDESocketDeviceFactoryBase* factory, int capabilities) 00885 { 00886 TQMutexLocker locker(&defaultImplFactoryMutex); 00887 if (factories.contains(capabilities)) 00888 delete factories[capabilities]; 00889 factories.insert(capabilities, factory); 00890 } 00891