30# include <sys/filio.h> 
   33#include <sys/socket.h> 
   38#include <netinet/in.h> 
   44# ifdef HAVE_SYS_SELECT 
   45#  include <sys/select.h> 
   53#include <tqsocketnotifier.h> 
   56#include "tdesocketaddress.h" 
   57#include "tdesocketbase.h" 
   58#include "tdesocketdevice.h" 
   59#include "ksockssocketdevice.h" 
   63class KNetwork::TDESocketDevicePrivate
 
   66  mutable TQSocketNotifier *input, *output, *exception;
 
   70  inline TDESocketDevicePrivate()
 
   72    input = output = exception = 0L;
 
   79  : m_sockfd(-1), d(new TDESocketDevicePrivate)
 
   86TDESocketDevice::TDESocketDevice(
int fd)
 
   87  : m_sockfd(fd), d(new TDESocketDevicePrivate)
 
   90  setFlags(IO_Sequential | IO_Raw | IO_ReadWrite);
 
   96  : m_sockfd(-1), d(new TDESocketDevicePrivate)
 
  113  TQMutexLocker locker(
mutex());
 
  120      int fdflags = fcntl(
m_sockfd, F_GETFL, 0);
 
  123      setError(IO_UnspecifiedError, UnknownError);
 
  128    fdflags &= ~O_NONBLOCK;
 
  130    fdflags |= O_NONBLOCK;
 
  132      if (fcntl(
m_sockfd, F_SETFL, fdflags) == -1)
 
  134      setError(IO_UnspecifiedError, UnknownError);
 
  140      int on = opts & AddressReuseable ? 1 : 0;
 
  141      if (setsockopt(
m_sockfd, SOL_SOCKET, SO_REUSEADDR, (
char*)&on, 
sizeof(on)) == -1)
 
  143      setError(IO_UnspecifiedError, UnknownError);
 
  148#if defined(IPV6_V6ONLY) && defined(AF_INET6) 
  149  if (d->af == AF_INET6)
 
  153      int on = opts & IPv6Only ? 1 : 0;
 
  154      if (setsockopt(
m_sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (
char*)&on, 
sizeof(on)) == -1)
 
  156      setError(IO_UnspecifiedError, UnknownError);
 
  163     int on = opts & Broadcast ? 1 : 0;
 
  164     if (setsockopt(
m_sockfd, SOL_SOCKET, SO_BROADCAST, (
char*)&on, 
sizeof(on)) == -1)
 
  166     setError(IO_UnspecifiedError, UnknownError);
 
  189      d->input = d->output = d->exception = 0L;
 
  191      d->local.setFamily(AF_UNSPEC);
 
  192      d->peer.setFamily(AF_UNSPEC);
 
  208      setError(IO_SocketCreateError, AlreadyCreated);
 
  213  m_sockfd = kde_socket(family, type, protocol);
 
  217      setError(IO_SocketCreateError, NotSupported);
 
  242      if (errno == EADDRINUSE)
 
  243    setError(IO_BindError, AddressInUse);
 
  244      else if (errno == EINVAL)
 
  245    setError(IO_BindError, AlreadyBound);
 
  248    setError(IO_BindError, NotSupported);
 
  259      if (kde_listen(
m_sockfd, backlog) == -1)
 
  261      setError(IO_ListenError, NotSupported);
 
  266      setFlags(IO_Sequential | IO_Raw | IO_ReadWrite);
 
  272  setError(IO_ListenError, NotCreated);
 
  285      if (errno == EISCONN)
 
  287      else if (errno == EALREADY || errno == EINPROGRESS)
 
  289      setError(IO_ConnectError, InProgress);
 
  292      else if (errno == ECONNREFUSED)
 
  293    setError(IO_ConnectError, ConnectionRefused);
 
  294      else if (errno == ENETDOWN || errno == ENETUNREACH ||
 
  295           errno == ENETRESET || errno == ECONNABORTED ||
 
  296           errno == ECONNRESET || errno == EHOSTDOWN ||
 
  297           errno == EHOSTUNREACH)
 
  298    setError(IO_ConnectError, NetFailure);
 
  300    setError(IO_ConnectError, NotSupported);
 
  305  setFlags(IO_Sequential | IO_Raw | IO_ReadWrite);
 
  314      setError(IO_AcceptError, NotCreated);
 
  319  socklen_t len = 
sizeof(sa);
 
  320  int newfd = kde_accept(
m_sockfd, &sa, &len);
 
  323      if (errno == EAGAIN || errno == EWOULDBLOCK)
 
  324    setError(IO_AcceptError, WouldBlock);
 
  326    setError(IO_AcceptError, UnknownError);
 
  344      if (errno == EALREADY || errno == EINPROGRESS)
 
  346      setError(IO_ConnectError, InProgress);
 
  349      else if (errno == ECONNREFUSED)
 
  350    setError(IO_ConnectError, ConnectionRefused);
 
  351      else if (errno == ENETDOWN || errno == ENETUNREACH ||
 
  352           errno == ENETRESET || errno == ECONNABORTED ||
 
  353           errno == ECONNRESET || errno == EHOSTDOWN ||
 
  354           errno == EHOSTUNREACH)
 
  355    setError(IO_ConnectError, NetFailure);
 
  357    setError(IO_ConnectError, NotSupported);
 
  362  setFlags(IO_Sequential | IO_Raw | IO_ReadWrite);
 
  373  if (ioctl(
m_sockfd, FIONREAD, &nchars) == -1)
 
  385  if (!
poll(&input, 0, 0, msecs, timeout))
 
  391static int do_read_common(
int sockfd, 
char *data, TQ_ULONG maxlen, 
TDESocketAddress* from, ssize_t &retval, 
bool peek = 
false)
 
  397      retval = ::recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, from->
address(), &len);
 
  400    retval = ::recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, NULL, NULL);
 
  404      if (errno == EAGAIN || errno == EWOULDBLOCK)
 
  405    return TDESocketDevice::WouldBlock;
 
  407    return TDESocketDevice::UnknownError;
 
  410    return TDESocketDevice::RemotelyDisconnected;
 
  423  if (maxlen == 0 || data == 0L)
 
  427  int err = do_read_common(
m_sockfd, data, maxlen, 0L, retval);
 
  444  if (data == 0L || maxlen == 0)
 
  448  int err = do_read_common(
m_sockfd, data, maxlen, &from, retval);
 
  465  if (maxlen == 0 || data == 0L)
 
  469  int err = do_read_common(
m_sockfd, data, maxlen, 0L, retval, 
true);
 
  486  if (data == 0L || maxlen == 0)
 
  490  int err = do_read_common(
m_sockfd, data, maxlen, &from, retval, 
true);
 
  512  if (data == 0L || len == 0)
 
  518      if (errno == EAGAIN || errno == EWOULDBLOCK)
 
  519    setError(IO_WriteError, WouldBlock);
 
  521    setError(IO_WriteError, UnknownError);
 
  524  else if (retval == 0)
 
  525    setError(IO_WriteError, RemotelyDisconnected);
 
  535  if (d->local.family() != AF_UNSPEC)
 
  545#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 
  571  if (d->peer.family() != AF_UNSPEC)
 
  581#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 
  614  TQMutexLocker locker(
mutex());
 
  632  TQMutexLocker locker(
mutex());
 
  650  TQMutexLocker locker(
mutex());
 
  660  return d->exception = 
createNotifier(TQSocketNotifier::Exception);
 
  664             int timeout, 
bool* timedout)
 
  668      setError(IO_UnspecifiedError, NotCreated);
 
  680      fds.events |= POLLIN;
 
  685      fds.events |= POLLOUT;
 
  690      fds.events |= POLLPRI;
 
  694  int retval = 
::poll(&fds, 1, timeout);
 
  697      setError(IO_UnspecifiedError, UnknownError);
 
  708  if (input && fds.revents & POLLIN)
 
  710  if (output && fds.revents & POLLOUT)
 
  712  if (exception && fds.revents & POLLPRI)
 
  723  fd_set readfds, writefds, exceptfds;
 
  724  fd_set *preadfds = 0L, *pwritefds = 0L, *pexceptfds = 0L;
 
  735      pwritefds = &writefds;
 
  742      pexceptfds = &exceptfds;
 
  750    retval = select(
m_sockfd + 1, preadfds, pwritefds, pexceptfds, 0L);
 
  755      tv.tv_sec = timeout / 1000;
 
  756      tv.tv_usec = timeout % 1000 * 1000;
 
  758      retval = select(
m_sockfd + 1, preadfds, pwritefds, pexceptfds, &tv);
 
  763      setError(IO_UnspecifiedError, UnknownError);
 
  774  if (input && FD_ISSET(
m_sockfd, preadfds))
 
  776  if (output && FD_ISSET(
m_sockfd, pwritefds))
 
  778  if (exception && FD_ISSET(
m_sockfd, pexceptfds))
 
  787  bool input, output, exception;
 
  788  return poll(&input, &output, &exception, timeout, timedout);
 
  796  return new TQSocketNotifier(
m_sockfd, type);
 
  802  template<
class T> 
class ptr
 
  810    ptr(
const ptr<T>& other) : obj(other.obj)
 
  813    ptr(type* _obj) : obj(_obj)
 
  819    ptr<T>& operator=(
const ptr<T>& other)
 
  820    { obj = other.obj; 
return *
this; }
 
  822    ptr<T>& operator=(T* _obj)
 
  823    { obj = _obj; 
return  *
this; }
 
  825    type* operator->()
 const { 
return obj; }
 
  827    operator T*() 
const { 
return obj; }
 
  834static TDESocketDeviceFactoryBase* defaultImplFactory;
 
  835static TQMutex defaultImplFactoryMutex;
 
  836typedef TQMap<int, TDESocketDeviceFactoryBase* > factoryMap;
 
  837static factoryMap factories;
 
  845  KSocksSocketDevice::initSocks();
 
  847  if (defaultImplFactory)
 
  848    return defaultImplFactory->create(parent);
 
  860  TQMutexLocker locker(&defaultImplFactoryMutex);
 
  861  factoryMap::ConstIterator it = factories.constBegin();
 
  862  for ( ; it != factories.constEnd(); ++it)
 
  865      return it.data()->create(parent);
 
  870TDESocketDeviceFactoryBase*
 
  873  TQMutexLocker locker(&defaultImplFactoryMutex);
 
  874  TDESocketDeviceFactoryBase* old = defaultImplFactory;
 
  875  defaultImplFactory = factory;
 
  881  TQMutexLocker locker(&defaultImplFactoryMutex);
 
void setError(int status, SocketError error)
Sets the socket's error code and the I/O Device's status.
 
void resetError()
Resets the socket error code and the I/O Device's status.
 
int protocol() const
Retrieves the protocol associated with this entry.
 
TQ_UINT16 length() const
Retrieves the length of the socket address structure.
 
int socketType() const
Retrieves the socket type associated with this entry.
 
TDESocketAddress address() const
Retrieves the socket address associated with this entry.
 
int family() const
Retrieves the family associated with this socket address.
 
A generic socket address.
 
int family() const
Returns the family of this address.
 
virtual TDESocketAddress & setFamily(int family)
Sets the family of this object.
 
TDESocketAddress & setLength(TQ_UINT16 len)
Sets the length of this socket structure.
 
const sockaddr * address() const
Returns the socket address structure, to be passed down to low level functions.
 
TQ_UINT16 length() const
Returns the length of this socket address structure.
 
Basic socket functionality.
 
virtual void setSocketDevice(TDESocketDevice *device)
Sets the socket implementation to be used on this socket.
 
TQMutex * mutex() const
Returns the internal mutex for this class.
 
SocketError
Possible socket error codes.
 
virtual int socketOptions() const
Retrieves the socket options that have been set.
 
virtual bool setSocketOptions(int opts)
Set the given socket options.
 
Low-level socket functionality.
 
virtual int capabilities() const
Returns the set of capabilities this socket class implements.
 
virtual TQSocketNotifier * createNotifier(TQSocketNotifier::Type type) const
Creates a socket notifier of the given type.
 
virtual TDESocketAddress externalAddress() const
Returns this socket's externally visible local address.
 
virtual bool disconnect()
Disconnects this socket.
 
virtual TQ_LONG peekBlock(char *data, TQ_ULONG maxlen)
Peeks data in the socket.
 
static TDESocketDeviceFactoryBase * setDefaultImpl(TDESocketDeviceFactoryBase *factory)
Sets the default TDESocketDevice implementation to use and return the old factory.
 
virtual TQ_LONG writeBlock(const char *data, TQ_ULONG len)
Writes data to the socket.
 
virtual bool setSocketOptions(int opts)
This implementation sets the options on the socket.
 
virtual bool poll(bool *input, bool *output, bool *exception=0L, int timeout=-1, bool *timedout=0L)
Executes a poll in the socket, via select(2) or poll(2).
 
static TDESocketDevice * createDefault(TDESocketBase *parent)
Creates a new default TDESocketDevice object given the parent object.
 
virtual void close()
Closes the socket.
 
virtual TQ_LONG readBlock(char *data, TQ_ULONG maxlen)
Reads data from this socket.
 
virtual TQ_LONG waitForMore(int msecs, bool *timeout=0L)
Waits up to msecs for more data to be available on this socket.
 
int m_sockfd
The socket file descriptor.
 
virtual TDESocketDevice * accept()
Accepts a new incoming connection.
 
virtual TQ_LONG bytesAvailable() const
Returns the number of bytes available for reading without blocking.
 
virtual ~TDESocketDevice()
Destructor.
 
virtual bool connect(const KResolverEntry &address)
Connect to a remote host.
 
static void addNewImpl(TDESocketDeviceFactoryBase *factory, int capabilities)
Adds a factory of TDESocketDevice objects to the list, along with its capabilities flag.
 
virtual bool listen(int backlog=5)
Puts this socket into listening mode.
 
virtual bool create(int family, int type, int protocol)
Creates a socket but don't connect or bind anywhere.
 
virtual bool open(int mode)
Reimplementation from TQIODevice.
 
TQSocketNotifier * writeNotifier() const
Returns a socket notifier for output on this socket.
 
virtual TDESocketAddress localAddress() const
Returns this socket's local address.
 
virtual TDESocketAddress peerAddress() const
Returns this socket's peer address.
 
TQSocketNotifier * exceptionNotifier() const
Returns a socket notifier for exceptional events on this socket.
 
virtual bool bind(const KResolverEntry &address)
Binds this socket to the given address.
 
TQSocketNotifier * readNotifier() const
Returns a socket notifier for input on this socket.
 
A namespace to store all networking-related (socket) classes.