30 # include <sys/filio.h>
32 #include <sys/types.h>
33 #include <sys/socket.h>
35 #include <sys/ioctl.h>
38 #include <netinet/in.h>
44 # ifdef HAVE_SYS_SELECT
45 # include <sys/select.h>
50 #include "syssocket.h"
53 #include <tqsocketnotifier.h>
55 #include "kresolver.h"
56 #include "tdesocketaddress.h"
57 #include "tdesocketbase.h"
58 #include "tdesocketdevice.h"
59 #include "ksockssocketdevice.h"
61 using namespace KNetwork;
63 class KNetwork::TDESocketDevicePrivate
66 mutable TQSocketNotifier *input, *output, *exception;
70 inline TDESocketDevicePrivate()
72 input = output = exception = 0L;
79 : m_sockfd(-1), d(new TDESocketDevicePrivate)
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);
368 TQ_LONG TDESocketDevice::bytesAvailable() const
371 qint64 TDESocketDevice::bytesAvailable() const
378 if (ioctl(m_sockfd, FIONREAD, &nchars) == -1)
390 if (!
poll(&input, 0, 0, msecs, timeout))
393 return bytesAvailable();
396 static int do_read_common(
int sockfd,
char *data, TQ_ULONG maxlen,
TDESocketAddress* from, ssize_t &retval,
bool peek =
false)
402 retval = ::recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, from->
address(), &len);
405 retval = ::recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, NULL, NULL);
409 if (errno == EAGAIN || errno == EWOULDBLOCK)
410 return TDESocketDevice::WouldBlock;
412 return TDESocketDevice::UnknownError;
415 return TDESocketDevice::RemotelyDisconnected;
428 if (maxlen == 0 || data == 0L)
432 int err = do_read_common(
m_sockfd, data, maxlen, 0L, retval);
436 setError(IO_ReadError, static_cast<SocketError>(err));
449 if (data == 0L || maxlen == 0)
453 int err = do_read_common(
m_sockfd, data, maxlen, &from, retval);
457 setError(IO_ReadError, static_cast<SocketError>(err));
470 if (maxlen == 0 || data == 0L)
474 int err = do_read_common(
m_sockfd, data, maxlen, 0L, retval,
true);
478 setError(IO_ReadError, static_cast<SocketError>(err));
491 if (data == 0L || maxlen == 0)
495 int err = do_read_common(
m_sockfd, data, maxlen, &from, retval,
true);
499 setError(IO_ReadError, static_cast<SocketError>(err));
517 if (data == 0L || len == 0)
523 if (errno == EAGAIN || errno == EWOULDBLOCK)
524 setError(IO_WriteError, WouldBlock);
526 setError(IO_WriteError, UnknownError);
529 else if (retval == 0)
530 setError(IO_WriteError, RemotelyDisconnected);
540 if (d->local.family() != AF_UNSPEC)
550 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
576 if (d->peer.family() != AF_UNSPEC)
586 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
619 TQMutexLocker locker(
mutex());
637 TQMutexLocker locker(
mutex());
655 TQMutexLocker locker(
mutex());
665 return d->exception =
createNotifier(TQSocketNotifier::Exception);
669 int timeout,
bool* timedout)
673 setError(IO_UnspecifiedError, NotCreated);
685 fds.events |= POLLIN;
690 fds.events |= POLLOUT;
695 fds.events |= POLLPRI;
699 int retval =
::poll(&fds, 1, timeout);
702 setError(IO_UnspecifiedError, UnknownError);
713 if (input && fds.revents & POLLIN)
715 if (output && fds.revents & POLLOUT)
717 if (exception && fds.revents & POLLPRI)
728 fd_set readfds, writefds, exceptfds;
729 fd_set *preadfds = 0L, *pwritefds = 0L, *pexceptfds = 0L;
740 pwritefds = &writefds;
747 pexceptfds = &exceptfds;
755 retval = select(
m_sockfd + 1, preadfds, pwritefds, pexceptfds, 0L);
760 tv.tv_sec = timeout / 1000;
761 tv.tv_usec = timeout % 1000 * 1000;
763 retval = select(
m_sockfd + 1, preadfds, pwritefds, pexceptfds, &tv);
768 setError(IO_UnspecifiedError, UnknownError);
779 if (input && FD_ISSET(
m_sockfd, preadfds))
781 if (output && FD_ISSET(
m_sockfd, pwritefds))
783 if (exception && FD_ISSET(
m_sockfd, pexceptfds))
792 bool input, output, exception;
793 return poll(&input, &output, &exception, timeout, timedout);
801 return new TQSocketNotifier(
m_sockfd, type);
807 template<
class T>
class ptr
815 ptr(
const ptr<T>& other) : obj(other.obj)
818 ptr(type* _obj) : obj(_obj)
824 ptr<T>& operator=(
const ptr<T>& other)
825 { obj = other.obj;
return *
this; }
827 ptr<T>& operator=(T* _obj)
828 { obj = _obj;
return *
this; }
830 type* operator->()
const {
return obj; }
832 operator T*()
const {
return obj; }
839 static TDESocketDeviceFactoryBase* defaultImplFactory;
840 static TQMutex defaultImplFactoryMutex;
841 typedef TQMap<int, TDESocketDeviceFactoryBase* > factoryMap;
842 static factoryMap factories;
850 KSocksSocketDevice::initSocks();
852 if (defaultImplFactory)
853 return defaultImplFactory->create(parent);
865 TQMutexLocker locker(&defaultImplFactoryMutex);
866 factoryMap::ConstIterator it = factories.constBegin();
867 for ( ; it != factories.constEnd(); ++it)
870 return it.data()->create(parent);
875 TDESocketDeviceFactoryBase*
878 TQMutexLocker locker(&defaultImplFactoryMutex);
879 TDESocketDeviceFactoryBase* old = defaultImplFactory;
880 defaultImplFactory = factory;
886 TQMutexLocker locker(&defaultImplFactoryMutex);
887 if (factories.contains(capabilities))
888 delete factories[capabilities];
889 factories.insert(capabilities, factory);
TQSocketNotifier * readNotifier() const
Returns a socket notifier for input on this socket.
A generic socket address.
virtual void setSocketDevice(TDESocketDevice *device)
Sets the socket implementation to be used on this socket.
virtual bool disconnect()
Disconnects this socket.
virtual TDESocketAddress externalAddress() const
Returns this socket's externally visible local address.
static void addNewImpl(TDESocketDeviceFactoryBase *factory, int capabilities)
Adds a factory of TDESocketDevice objects to the list, along with its capabilities flag...
virtual TQSocketNotifier * createNotifier(TQSocketNotifier::Type type) const
Creates a socket notifier of the given type.
TQSocketNotifier * exceptionNotifier() const
Returns a socket notifier for exceptional events on this socket.
virtual TDESocketDevice * accept()
Accepts a new incoming connection.
virtual TQ_LONG waitForMore(int msecs, bool *timeout=0L)
Returns the number of bytes available for reading without blocking.
TQMutex * mutex() const
Returns the internal mutex for this class.
void resetError()
Resets the socket error code and the I/O Device's status.
virtual bool create(int family, int type, int protocol)
Creates a socket but don't connect or bind anywhere.
TQSocketNotifier * writeNotifier() const
Returns a socket notifier for output on this socket.
Low-level socket functionality.
virtual TQT_TQIO_LONG tqwriteBlock(const char *data, TQT_TQIO_ULONG len)
Writes data to the socket.
int protocol() const
Retrieves the protocol associated with this entry.
TDESocketAddress address() const
Retrieves the socket address associated with this entry.
TDESocketAddress & setLength(TQ_UINT16 len)
Sets the length of this socket structure.
void setError(int status, SocketError error)
Sets the socket's error code and the I/O Device's status.
static TDESocketDeviceFactoryBase * setDefaultImpl(TDESocketDeviceFactoryBase *factory)
Sets the default TDESocketDevice implementation to use and return the old factory.
TQ_UINT16 length() const
Retrieves the length of the socket address structure.
int m_sockfd
The socket file descriptor.
static TDESocketDevice * createDefault(TDESocketBase *parent)
Creates a new default TDESocketDevice object given the parent object.
const sockaddr * address() const
Returns the socket address structure, to be passed down to low level functions.
virtual bool connect(const KResolverEntry &address)
Connect to a remote host.
virtual TQT_TQIO_LONG tqreadBlock(char *data, TQT_TQIO_ULONG maxlen)
Reads data from this socket.
virtual bool open(TQ_OpenMode mode)
Reimplementation from TQIODevice.
virtual int socketOptions() const
Retrieves the socket options that have been set.
int socketType() const
Retrieves the socket type associated with this entry.
virtual bool setSocketOptions(int opts)
This implementation sets the options on the socket.
virtual bool bind(const KResolverEntry &address)
Binds this socket to the given address.
virtual int capabilities() const
Returns the set of capabilities this socket class implements.
int family() const
Retrieves the family associated with this socket address.
virtual ~TDESocketDevice()
Destructor.
Basic socket functionality.
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).
int family() const
Returns the family of this address.
virtual TQ_LONG peekBlock(char *data, TQ_ULONG maxlen)
Peeks data in the socket.
virtual bool setSocketOptions(int opts)
Set the given socket options.
virtual void close()
Closes the socket.
TDESocketDevice(const TDESocketBase *=0L)
Default constructor.
virtual bool listen(int backlog=5)
Puts this socket into listening mode.
TQ_UINT16 length() const
Returns the length of this socket address structure.
virtual TDESocketAddress & setFamily(int family)
Sets the family of this object.
virtual TDESocketAddress peerAddress() const
Returns this socket's peer address.
virtual TDESocketAddress localAddress() const
Returns this socket's local address.