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"
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)
86 TDESocketDevice::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))
391 static 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; }
834 static TDESocketDeviceFactoryBase* defaultImplFactory;
835 static TQMutex defaultImplFactoryMutex;
836 typedef TQMap<int, TDESocketDeviceFactoryBase* > factoryMap;
837 static 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);
870 TDESocketDeviceFactoryBase*
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.