• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdecore
 

tdecore

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 <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 <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 

tdecore

Skip menu "tdecore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

tdecore

Skip menu "tdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdecore by doxygen 1.7.1
This website is maintained by Timothy Pearson.