summaryrefslogtreecommitdiffstats
path: root/kdecore/kextsock.h
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commitce4a32fe52ef09d8f5ff1dd22c001110902b60a2 (patch)
tree5ac38a06f3dde268dc7927dc155896926aaf7012 /kdecore/kextsock.h
downloadtdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.tar.gz
tdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdelibs@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kdecore/kextsock.h')
-rw-r--r--kdecore/kextsock.h1110
1 files changed, 1110 insertions, 0 deletions
diff --git a/kdecore/kextsock.h b/kdecore/kextsock.h
new file mode 100644
index 000000000..f3d1f5923
--- /dev/null
+++ b/kdecore/kextsock.h
@@ -0,0 +1,1110 @@
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2000-2004 Thiago Macieira <thiago.macieira@kdemail.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef KEXTSOCK_H
+#define KEXTSOCK_H
+
+#include "kdelibs_export.h"
+
+#ifdef Q_OS_UNIX
+
+#include <sys/time.h>
+
+#include <qstring.h>
+#include <qptrlist.h>
+#include <qiodevice.h>
+
+#include "kbufferedio.h"
+#include "ksockaddr.h"
+
+/* External reference to netdb.h */
+struct addrinfo;
+struct kde_addrinfo;
+class KAddressInfo; /* our abstraction of it */
+class QSocketNotifier;
+
+/*
+ * This is extending QIODevice's error codes
+ *
+ * According to qiodevice.h, the last error is IO_UnspecifiedError
+ * These errors will never occur in functions declared in QIODevice
+ * (except open, but you shouldn't call open)
+ */
+#define IO_ListenError (IO_UnspecifiedError+1)
+#define IO_AcceptError (IO_UnspecifiedError+2)
+#define IO_LookupError (IO_UnspecifiedError+3)
+
+class KExtendedSocketPrivate;
+/**
+ * The extended socket class.
+ *
+ * This class should be used instead of KSocket whenever the user needs
+ * fine-grained control over the socket being created. Unlike KSocket, which
+ * does everything at once, without much intervention, KExtendedSocket allows
+ * intervention at every step of the process and the setting of parameters.
+ *
+ * This class allows for the creation of both server and client sockets. The
+ * only difference is that the passiveSocket flag must be passed either to
+ * the constructor or to setSocketFlags(). If passiveSocket is used, the class will
+ * enable functions listen() and accept() and related signals, and will
+ * also disable readBlock() and writeBlock().
+ *
+ * To create a Unix socket, one would pass flag unixSocket to the constructor
+ * or setSocketFlags(). The hostname and service/port can be set to whatever is
+ * necessary. If no hostname is given, but a service/port is, the socket created
+ * will be implementation dependant (usually in /tmp). In any other case, the
+ * fields will be concatenated.
+ *
+ * To create an Internet socket, inetSocket flag can be used. If, on the other
+ * hand a specific IP protocol is desired, ipv4Socket and/or ipv6Socket can be
+ * used.
+ *
+ * Note that the socket type selection flags are cumulative. One could select
+ * Unix and Internet sockets by using unixSocket | inetSocket. Or, for instance,
+ * to make sure only IPv4 and IPv6 sockets are selected, even if future implementations
+ * support newer IP protocols, ipv4Socket | ipv6Socket is your guy.
+ *
+ * @deprecated
+ * This class is now deprecated. Please use the classes in KNetwork for
+ * new programs. In particular, this class is replaced by KNetwork::KStreamSocket
+ * and @ref KNetwork::KServerSocket.
+ *
+ * @author Thiago Macieira <thiago.macieira@kdemail.net>
+ * @short an extended socket
+ */
+class KDECORE_EXPORT KExtendedSocket: public KBufferedIO // public QObject, public QIODevice
+{
+ Q_OBJECT
+
+public:
+ /**
+ * flags that can be passed down to the member functions
+ */
+ enum Flags
+ {
+ /* socket address families */
+ /*
+ * NOTE: if you change this, you have to change function valid_socket() as well
+ * These values are hard coded!
+ */
+ anySocket = 0x00,
+ knownSocket = 0x01,
+ unixSocket = knownSocket | 0x02,
+ inetSocket = knownSocket | 0x04,
+ ipv4Socket = inetSocket | 0x100,
+ ipv6Socket = inetSocket | 0x200,
+
+ passiveSocket = 0x1000, /* passive socket (i.e., one that accepts connections) */
+ canonName = 0x2000, /* request that the canon name be found */
+ noResolve = 0x4000, /* do not attempt to resolve, treat as numeric host */
+
+ streamSocket = 0x8000, /* request a streaming socket (e.g., TCP) */
+ datagramSocket = 0x10000, /* request a datagram socket (e.g., UDP) */
+ rawSocket = 0x20000, /* request a raw socket. This probably requires privileges */
+
+ inputBufferedSocket = 0x200000, /* buffer input in this socket */
+ outputBufferedSocket = 0x400000, /* buffer output in this socket */
+ bufferedSocket = 0x600000 /* make this a fully buffered socket */
+ };
+
+ /**
+ * status of the class
+ * The status are sequential. If a change to one status is requested,
+ * all the prior status will be passed and their actions, performed
+ */
+ enum SockStatus
+ {
+ // the numbers are scattered so that we leave room for future expansion
+ error = -1, // invalid status!
+
+ nothing = 0, // no status, the class has just been created
+
+ lookupInProgress = 50, // lookup is in progress. Signals will be sent
+ lookupDone = 70, // lookup has been done. Flags cannot be changed
+ // from this point on
+
+ created = 100, // ::socket() has been called, a socket exists
+ bound = 140, // socket has been bound
+
+ connecting = 200, // socket is connecting (not passiveSocket)
+ connected = 220, // socket has connected (not passiveSocket)
+
+ listening = 200, // socket is listening (passiveSocket)
+ accepting = 220, // socket is accepting (passiveSocket)
+
+ closing = 350, // socket is closing (delayed close)
+
+ done = 400 // socket has been closed
+ };
+
+public:
+ /**
+ * Creates an empty KExtendedSocket.
+ */
+ KExtendedSocket();
+
+ /**
+ * Creates a socket with the given hostname and port.
+ *
+ * If this is a connecting (active) socket, the hostname and port specify
+ * the remote address to which we will connect.
+ *
+ * If this is a listening (passive) socket, the hostname and port specify
+ * the address to listen on. In order to listen on every interface
+ * available on this node, set @p host to QString::null. To let the operating
+ * system select a port, set it to 0.
+ *
+ * @sa setAddress
+ * @param host the hostname
+ * @param port the port number
+ * @param flags flags
+ */
+ KExtendedSocket(const QString& host, int port, int flags = 0);
+
+ /**
+ * Creates a socket with the given hostname and service.
+ *
+ * If this is a connecting (active) socket, the hostname and service specify
+ * the remote address to which we will connect.
+ *
+ * If this is a listening (passive) socket, the hostname and service specify
+ * the address to listen on. In order to listen on every interface
+ * available on this node, set @p host to QString::null. To let the operating
+ * system select a port, set the service to "0".
+ *
+ * @sa setAddress
+ * @param host the hostname
+ * @param service the service
+ * @param flags flags
+ */
+ KExtendedSocket(const QString& host, const QString& service, int flags = 0);
+
+ /**
+ * Destroys the socket, disconnecting if still connected and
+ * freeing any related resources still being kept.
+ */
+ virtual ~KExtendedSocket();
+
+ /**
+ * Resets the socket, disconnecting if still connected and
+ * freeing any related resources still being kept.
+ * @since 3.1
+ */
+ void reset();
+
+ /*
+ * --- status, flags and internal variables --- *
+ */
+
+ /**
+ * Returns the class status.
+ * @return the class status
+ * @see ::SockStatus
+ */
+ int socketStatus() const;
+
+ /**
+ * Returns the related system error code
+ * Except for IO_LookupError errors, these are codes found in
+ * errno
+ * @return the system error code
+ */
+ int systemError() const;
+
+ /**
+ * Sets the given flags.
+ * @param flags the flags to be set
+ * @return the new flags status, or -1 if flags can no longer be set
+ */
+ int setSocketFlags(int flags);
+
+ /**
+ * Returns the current flags
+ * @return the current flags
+ * @see ::Flags
+ */
+ int socketFlags() const;
+
+ /**
+ * Sets the hostname to the given value.
+ *
+ * If this is a listening (passive) socket, the hostname is the host to which the socket
+ * will bind in order to listen. If you want to listen in every interface, set it
+ * to "*" or QString::null.
+ *
+ * If this is a connecting (active) socket, the hostname is the host to which we will try
+ * to connect.
+ *
+ * @param host the hostname
+ * @return true on success, false on error
+ */
+ bool setHost(const QString& host);
+
+ /**
+ * Returns the hostname.
+ * @return the hostname or QString::null if no host has been set
+ */
+ QString host() const;
+
+ /**
+ * Sets the port/service.
+ * @param port the port
+ */
+ bool setPort(int port);
+
+ /**
+ * Sets the port/service.
+ *
+ * In the case of Unix-domain sockets, the port is the filename for the socket.
+ * If the name is not an absolute path, "/tmp/" will be prepended.
+ *
+ * @param port the port
+ * @return true if successful, false on error (e.g. connection already established)
+ */
+ bool setPort(const QString& port);
+
+ /**
+ * Returns the port/service. If it is a port, the string contains a number.
+ * @return the port or QString::null if it has not been set.
+ */
+ QString port() const;
+
+ /**
+ * Sets the address where we will connect to.
+ *
+ * See @ref setHost and @ref setPort for information on the parameters.
+ *
+ * @param host the hostname
+ * @param port port number
+ * @return true if successful, false on error (e.g. connection already established)
+ */
+ bool setAddress(const QString& host, int port);
+
+ /**
+ * Sets the address where we will connect to.
+ *
+ * See @ref setHost and @ref setPort for information on the parameters.
+ *
+ * @param host the hostname
+ * @param serv the service
+ * @return true if successful, false on error (e.g. connection already established)
+ */
+ bool setAddress(const QString& host, const QString& serv);
+
+ /**
+ * Sets the hostname to which we will bind locally before connecting.
+ * @param host the hostname
+ * @return false if this is a passiveSocket, otherwise true.
+ */
+ bool setBindHost(const QString& host);
+
+ /**
+ * Unsets the bind hostname. That is, don't request a binding host.
+ * @return true if successful, false on error (e.g. connection already established)
+ */
+ bool unsetBindHost();
+
+ /**
+ * Returns the hostname to which the socket will be/is bound.
+ * @return the host or QString::null if it has not been set.
+ */
+ QString bindHost() const;
+
+ /**
+ * Sets the port/service to which we will bind before connecting
+ * @param port the port number
+ * @return true if successful, false on error (e.g. connection already established)
+ */
+ bool setBindPort(int port);
+
+ /**
+ * Sets the port/service to which we will bind before connecting.
+ * @param service the port number or service name
+ * @return true if successful, false on error (e.g. connection already established)
+ */
+ bool setBindPort(const QString& service);
+
+ /**
+ * Unsets the bind port/service.
+ * @return true if successful, false on error (e.g. connection already established)
+ */
+ bool unsetBindPort();
+
+ /**
+ * Returns the service to which the socket will be/is bound.
+ * @return the host or QString::null if it has not been set.
+ */
+ QString bindPort() const;
+
+ /**
+ * Sets both host and port to which we will bind the socket. Will return
+ * false if this is a passiveSocket.
+ * @param host the hostname
+ * @param port the port number
+ * @return true if successful, false on error (e.g. connection already established)
+ */
+ bool setBindAddress(const QString& host, int port);
+
+ /**
+ * Sets both host and service to which we will bind the socket. Will return
+ * false if this is a passiveSocket.
+ * @param host the hostname
+ * @param service the service
+ * @return true if successful, false on error (e.g. connection already established)
+ */
+ bool setBindAddress(const QString& host, const QString& service);
+
+ /**
+ * Unsets the bind address for the socket. That means that we won't
+ * attempt to bind to an address before connecting.
+ * @return true if successful, false on error (e.g. connection already established)
+ */
+ bool unsetBindAddress();
+
+ /**
+ * Sets the timeout value for the connection (if this is not passiveSocket) or
+ * acception (if it is). In the event the given function
+ * (connect or accept) returns due to time out, it's possible to call it again.
+ *
+ * Setting the timeout to 0 disables the timeout feature.
+ *
+ * @param secs the timeout length, in seconds
+ * @param usecs the timeout complement, in microseconds
+ * @return false if setting timeout makes no sense in the context.
+ */
+ bool setTimeout(int secs, int usecs = 0);
+
+ /**
+ * Returns the timeout value for the connection.
+ * @return the timeout value. 0 if there is no timeout.
+ */
+ timeval timeout() const;
+
+ /**
+ * Sets/unsets blocking mode for the socket. When non-blocking mode is enabled,
+ * I/O operations might return error and set errno to EWOULDBLOCK. Also,
+ * it's not recommended to use this when using the class signals.
+ *
+ * @param enable if true, set blocking mode. False, non-blocking mode.
+ * @return false on error.
+ */
+ bool setBlockingMode(bool enable);
+
+ /**
+ * Returns the current blocking mode for this socket.
+ * @return true if in blocking mode
+ */
+ bool blockingMode();
+
+ /**
+ * Sets/unsets address reusing flag for this socket.
+ *
+ * This function returns true if the value was set correctly. That is NOT
+ * the result of the set.
+ * @param enable if true, set address reusable
+ * @return true on success, false on failure. If the socket was not yet created,
+ * the value is only remembered. In this case the return value is always true.
+ */
+ bool setAddressReusable(bool enable);
+
+ /**
+ * Returns whether this socket's address can be reused
+ * @return true if the address can be reused
+ */
+ bool addressReusable();
+
+ /**
+ * Sets/unsets the v6-only flag for IPv6 sockets.
+ *
+ * When an IPv6 socket is in use, communication with IPv4 sockets is
+ * guaranteed by translating those IPv4 addresses into IPv6 ones
+ * (specifically, the v4-mapped addresses). This flag allows that
+ * behavior to be turned on and off.
+ *
+ * Note that this does not have any effect on sockets that are not
+ * IPv6 and the function will always return false in those cases.
+ * Also note that this flag defaults to off in order to accommodate
+ * existing applications.
+ *
+ * @param enable if true, no IPv4 translation will be performed;
+ * this socket will be restricted to IPv6 communication
+ * @returns true on success, false on failure.
+ * @see localAddress to find out if this is an IPv6 socket
+ */
+ bool setIPv6Only(bool enable);
+
+ /**
+ * Returns the status of the v6-only flag for IPv6 sockets.
+ * @returns true if the flag is set to on; false if it is not. If this
+ * socket is not an IPv6 one, the return value is false.
+ * @see setIPv6Only
+ */
+ bool isIPv6Only();
+
+ /**
+ * Sets the buffer sizes for this socket.
+ *
+ * This implementation allows any size for both parameters. The value given
+ * will be interpreted as the maximum size allowed for the buffers, after
+ * which the I/O functions will stop buffering. The value of -1 will be
+ * interpreted as "unlimited" size. The value of -2 means "no change".
+ *
+ * Note: changing the buffer size to 0 for any buffer will cause the given
+ * buffer's to be discarded. Likewise, setting the size to a value less than
+ * the current size will cause the buffer to be shrunk to the wanted value,
+ * as if the data had been read.
+ * @param rsize read buffer size
+ * @param wsize write buffer size
+ * @return true on success, false if this is not possible in this state (e.g. connection
+ * not established yet)
+ */
+ virtual bool setBufferSize(int rsize, int wsize = -2);
+
+ /**
+ * Returns the local socket address
+ * @return the local socket address, can be 0 if the connection has not been established
+ * yet
+ */
+ const ::KSocketAddress *localAddress();
+
+ /**
+ * Returns the peer socket address. Use KExtendedSocket::resolve() to
+ * resolve this to a human-readable hostname/service or port.
+ * @return the peer address, can be 0 if the connection has not been established yet
+ * or the socket is passive
+ */
+ const ::KSocketAddress *peerAddress();
+
+ /**
+ * Returns the file descriptor
+ * @return the file descriptor. -1 if there is no fd yet.
+ */
+ inline int fd() const
+ { return sockfd; }
+
+ /*
+ * -- socket creation -- *
+ */
+
+ /**
+ * Performs lookup on the addresses we were given before.
+ *
+ * This will perform lookups on the bind addresses if they were given.
+ * @return 0 or an error. Do not rely on the values returned by lookup
+ * as of now. They are not specified.
+ */
+ virtual int lookup();
+
+ /**
+ * Starts an asynchronous lookup for the addresses given.
+ *
+ * When the lookup is done, the lookupReady signal will be emitted.
+ *
+ * Note that, depending on the parameters for the lookup, this function might
+ * know the results without the need for blocking or queuing an
+ * asynchronous lookup. That means that the lookupReady signal might be
+ * emitted by this function, so your code should be prepared for that.
+ *
+ * One such case is when noResolve flag is set.
+ * If this function is able to determine the results without queuing
+ * and the lookup failed, this function will return -1.
+ *
+ * @return 0 on success or -1 on error. Note that
+ * returning 0 means that either we are in the process of doing
+ * lookup or that it has finished already.
+ */
+ virtual int startAsyncLookup();
+
+ /**
+ * Cancels any on-going asynchronous lookups
+ */
+ virtual void cancelAsyncLookup();
+
+ /**
+ * Place the socket in listen mode. The parameters are the same as for
+ * the system listen() call.
+ * @param N the queue length for pending connections
+ * @return 0 on success, -1 on system error (errno
+ * available) and -2 if this is not a passiveSocket.
+ */
+ virtual int listen(int N = 5); // 5 is arbitrary
+
+ /**
+ * Accepts an incoming connection from the socket. If this socket is in
+ * blocking mode, this function will block until a connection is received.
+ * Otherwise, it might return with error. The sock parameter will be
+ * initialised with the newly created socket.
+ *
+ * Upon successful acception (i.e., this function returns 0), the newly
+ * created socket will be already connected. The socket will be unbuffered
+ * and readyRead() and readyWrite() signals will be disabled.
+ *
+ * @param sock a pointer to an KExtendedSocket variable
+ * @return 0 on success, -1 on system error (errno set) and -2 if this is
+ * not a passiveSocket and -3 if this took too long (time out)
+ */
+ virtual int accept(KExtendedSocket *&sock);
+
+ /**
+ * Attempts to connect to the remote host.
+ * After successful connection (return value 0), the socket will be ready
+ * for I/O operations. Note, however, that not all signals may be enabled
+ * for emission by this socket:
+ * @li readyRead and readyWrite signals will be enabled only if
+ * enableRead or enableWrite were called. You can still enable
+ * them by calling those functions, of course.
+ * @li #closed() will only be sent if we are indeed reading from the input
+ * stream. That is, if this socket is buffering the input. See setBufferSize
+ *
+ * Note that, in general, functions inherited/overridden from KBufferedIO will only
+ * work on buffered sockets, like bytesAvailable and bytesToWrite.
+ * @return The return values are:
+ * @li 0: success
+ * @li -1: system error, errno was set accordingly
+ * @li -2: this socket cannot connect(); this is a passiveSocket. It can also
+ * mean that the function was unable to make a connection with the given
+ * bind address or that an asynchronous connection attempt is already
+ * in progress.
+ * @li -3: connection timed out
+ *
+ */
+ virtual int connect();
+
+ /**
+ * Starts an asynchronous connect. This works exactly the same as #connect,
+ * except that the connection result won't be returned.
+ *
+ * Note that those signals might be emitted before this function returns, so your
+ * code should be prepared for that condition.
+ *
+ * You must call cancelAsyncConnect() before you delete the socket if you
+ * call this. Otherwise you will have crashes.
+ *
+ * @return 0 on successful queuing of the connect or -1 on error.
+ * If this function returns 0, then the connectionSuccess() or the
+ * connectionFailed() signals will be emitted.
+ */
+ virtual int startAsyncConnect();
+
+ /**
+ * Cancels any on-going asynchronous connection attempt.
+ */
+ virtual void cancelAsyncConnect();
+
+ /**
+ * Implementation of QIODevice::open() pure virtual function.
+ * This depends on the target host address already being there.
+ * If this is a passiveSocket, this is identical to call listen(); else, if
+ * this is not a passiveSocket and no connection attempt is in progress, this
+ * is like connect(). If one is in progress, this function will fail.
+ * @param mode the open mode. Must be IO_Raw | IO_ReadWrite
+ * @return true if successful, false when an error occurred or the most was
+ * not correct
+ */
+ virtual bool open(int mode = IO_Raw | IO_ReadWrite);
+
+ /**
+ * Closes the socket. If we have data still in the write buffer yet to be
+ * sent, the socket won't be closed right now. It'll be closed after we managed
+ * to send everything out.
+ * If you want to close the socket now, you may want to call flush() first,
+ * and then closeNow().
+ */
+ virtual void close();
+
+ /**
+ * Closes the socket now, discarding the contents of the write buffer, if any.
+ * The read buffer's contents are kept until they are emptied by read operations
+ * or the class is destroyed.
+ */
+ virtual void closeNow();
+
+ /**
+ * Releases the socket and anything we have holding on it. The class cannot
+ * be used anymore. In other words, this is just like closeNow(), but it does
+ * not actually close the socket.
+ *
+ * This is useful if you just want to connect and don't need the rest of the
+ * class.
+ *
+ * Note that the buffers' contents will be discarded.
+ *
+ * Use of this method is discouraged, because the socket created might be such that
+ * normal library routines can't handle (read, write, close, etc.)
+ */
+ virtual void release();
+
+ /*
+ * -- I/O --
+ */
+
+ /**
+ * Flushes the socket buffer. You need not call this method during normal
+ * operation as we will try and send everything as soon as possible.
+ * However, if you want to make sure that data in the buffer is being sent
+ * at this moment, you can call this function. It will try to send as much
+ * data as possible, but it will stop as soon as the kernel cannot receive
+ * any more data, and would possibly block.
+ *
+ * By repeatedly calling this function, the behavior will be like that of
+ * a blocking socket. Indeed, if this function is called with the kernel not
+ * ready to receive data, it will block, unless this is a non-blocking socket.
+ *
+ * This function does not touch the read buffer. You can empty it by calling
+ * readBlock() with a null destination buffer.
+ */
+ virtual void flush();
+
+ /**
+ * Returns length of this socket. This call is not supported on sockets.
+ * @return the length of this socket, or 0 if unsupported
+ */
+ virtual inline Q_ULONG size() const
+ { return 0; }
+
+ /**
+ * Returns relative position from start. This call is not supported on sockets.
+ * @return the relative position from the start, or 0 if unsupported
+ */
+ virtual inline Q_ULONG at() const
+ { return 0; }
+
+ /**
+ * Returns true if we are at position. This is not supported on sockets.
+ * @param i the position to check
+ * @return true if we art at the given position, or always true if unsupported.
+ */
+ virtual inline bool at(int i)
+ { Q_UNUSED(i);return true; }
+
+ /**
+ * Returns true if we are at the end. This is not supported on sockets, but
+ * we always are at the end in a socket...
+ * @return true if we are at the end. Always false if unsupported.
+ */
+ virtual inline bool atEnd() const
+ { return false; }
+
+ /**
+ * Reads a block of data from the socket.
+ *
+ * If the socket is not buffered, this function will simply call the underlying
+ * read method. This function will block if the socket is not on non-blocking mode
+ * (see setBlockingMode) and there is not enough data to be read in the
+ * Operating System yet. If we are in non-blocking operation, the call will
+ * fail in this case.
+ *
+ * However, if we are buffering, this function will instead read from the
+ * buffer while there is available data. This function will never block
+ * in buffering mode, which means that if you try to read while the buffers
+ * are empty, this function will always return -1 and set the system error to
+ * EWOULDBLOCK (aka EAGAIN), so as to mimic non-blocking operation.
+ *
+ * @param data where we will write the read data to
+ * @param maxlen maximum length of data to be read
+ * @return the number of bytes effectively read, or a negative number in case
+ * or an error. If the @p data param is not null, then this is also the number
+ * of bytes copied into that buffer. If the return value is different than
+ * @p maxlen, then this function encountered a situation in which no more
+ * bytes were available. Subsequent calls might cause this function to one
+ * of these behaviours:
+ * @li return an error, with EWOULDBLOCK system error, if we buffering
+ * or we are in non-blocking mode
+ * @li otherwise, it'll block
+ * This function returns 0, if the function detected end-of-file condition
+ * (socket was closed)
+ */
+ virtual Q_LONG readBlock(char *data, Q_ULONG maxlen);
+
+ /**
+ * Writes a block of data to the socket.
+ *
+ * If the socket is not buffered, this function will simply call the underlying
+ * write method. This means that the function might block if that method blocks
+ * as well. That situation is possible if we are not in non-blocking mode and
+ * the operating system buffers are full for this socket. If we are in
+ * non-blocking mode and the operating system buffers are full, this function
+ * will return -1 and the system error will be set to EWOULDBLOCK.
+ *
+ * If we are buffering, this function will simply transfer the data into the
+ * write buffer. This function will then always succeed, as long as there is
+ * enough room in the buffer. If the buffer size was limited and that limit
+ * is reached, this function will copy no more bytes than that limit. Trying
+ * to write with a full buffer will return -1 and set system error to
+ * EWOULDBLOCK.
+ *
+ * @param data the data to write
+ * @param len the length of data to write
+ * @return the number of bytes written from @p data buffer.
+ * The return value might be less than @p len if the output buffers cannot
+ * accommodate that many bytes and -1 in the case of an errro.
+ */
+ virtual Q_LONG writeBlock(const char *data, Q_ULONG len);
+
+ /**
+ * Peeks at a block of data from the socket.
+ *
+ * This is exactly like read, except that the data won't be flushed from the
+ * read buffer.
+ *
+ * If this socket is not buffered, this function will always return with
+ * 0 bytes copied.
+ *
+ * @param data where to store the data
+ * @param maxlen how many bytes to copy, at most
+ * @return the number of bytes copied. 0 does not mean end-of-file
+ * condition.
+ */
+ virtual int peekBlock(char *data, uint maxlen);
+
+ /**
+ * Reimplementation of unreadBlock() method. This is so because unreading in
+ * sockets doesn't make sense, so this function will always return -1 (error)
+ * and set the system error to ENOSYS.
+ * @return always -1 (error)
+ */
+ virtual int unreadBlock(const char *data, uint len);
+
+ /**
+ * Returns the number of available bytes yet to be read via readBlock
+ * and family of functions.
+ *
+ * Note: as of now, this only works on input-buffered sockets. This will
+ * change in the future
+ * @return The number of available bytes, or -1 on error or -2 if this call is invalid
+ * in the current state.
+ */
+ virtual int bytesAvailable() const;
+
+ /**
+ * Waits @p msec milliseconds for more data to be available (use 0 to
+ * wait forever). The return value is the amount of data available for
+ * read in the read buffer.
+ *
+ * @param msec milliseconds to wait
+ * @return -1 in case of system error and -2 in case of invalid socket
+ * state
+ */
+ virtual int waitForMore(int msec);
+
+ /**
+ * Gets a single character (unsigned char) from the stream.
+ * @return the value of the character. Negative if there was an error.
+ */
+ virtual int getch();
+
+ /**
+ * Writes a single character (unsigned char) to the stream. All other bits
+ * will be ignored.
+ * @param ch character to write, converted to char
+ */
+ virtual int putch(int ch);
+
+ /**
+ * Unreads one character from the stream. This is not possible on sockets.
+ * @return always returns -1 on sockets.
+ */
+ virtual int ungetch(int)
+ { return -1; }
+
+ /**
+ * Toggles the emission of the readyRead signal.
+ *
+ * Note that this signal is emitted every time more data is available to be
+ * read, so you might get flooded with it being emitted every time, when in
+ * non-buffered mode. However, in buffered mode, this signal will be
+ * emitted only when there is data coming in from the wire.
+ * By default, this flag is set to false, i.e., signal not being emitted.
+ * @param enable if true, the signal will be emitted
+ */
+ virtual void enableRead(bool enable);
+
+ /**
+ * Toggles the emission of the readyWrite signal.
+ *
+ * Note that this signal is emitted only when the OS is ready to receive more
+ * data, which means that the write buffer is empty. And when that is reached,
+ * this signal will possibly be emitted on every loop, so you might
+ * want to disable it. By default, this flag is set to false.
+ * @param enable if true, the signal will be emitted
+ */
+ virtual void enableWrite(bool enable);
+
+signals:
+ /**
+ * This signal is emitted whenever an asynchronous lookup process is done.
+ * The parameter @p count tells
+ * @param count the number of results
+ */
+ void lookupFinished(int count);
+
+ /**
+ * This signal is emitted whenever we connected asynchronously to a host.
+ */
+ void connectionSuccess();
+
+ /**
+ * This signal is emitted whenever our asynchronous connection attempt
+ * failed to all hosts listed.
+ * @param error the errno code of the last connection attempt
+ */
+ void connectionFailed(int error);
+
+ /**
+ * This signal is emitted whenever this socket is ready to accept another
+ * socket.
+ * @see accept()
+ */
+ void readyAccept();
+
+protected:
+ int sockfd; // file descriptor of the socket
+
+protected slots:
+
+ void socketActivityRead();
+ void socketActivityWrite();
+ void dnsResultsReady();
+ void startAsyncConnectSlot();
+ void connectionEvent();
+
+protected:
+
+ QSocketNotifier *readNotifier();
+ QSocketNotifier *writeNotifier();
+
+private:
+
+ // protection against accidental use
+ KExtendedSocket(KExtendedSocket&);
+ KExtendedSocket& operator=(KExtendedSocket&);
+
+ /**
+ * This is actually a wrapper around getaddrinfo().
+ * @internal
+ */
+ static int doLookup(const QString& host, const QString& serv, addrinfo& hint,
+ kde_addrinfo** result);
+
+protected:
+ /**
+ * Sets the error code
+ */
+ void setError(int errorkind, int error);
+
+ inline void cleanError()
+ { setError(IO_Ok, 0); }
+
+ /**
+ * Sets the socket status. For derived classes only.
+ */
+ void setSocketStatus(int status);
+
+public:
+ /**
+ * Performs resolution on the given socket address.
+ *
+ * That is, tries to resolve the raw form of the socket address into a textual
+ * representation.
+ *
+ * @param sock the socket address
+ * @param len the length of the socket address
+ * @param host where the hostname will be written
+ * @param port where the service-port will be written
+ * @param flags the same flags as getnameinfo()
+ * @returns 0 on success, nonzero otherwise.
+ */
+ static int resolve(sockaddr* sock, ksocklen_t len, QString& host, QString& port, int flags = 0) KDE_DEPRECATED;
+
+ /**
+ * Performs resolution on the given socket address.
+ *
+ * That is, tries to resolve the raw form of the socket address into a textual
+ * representation.
+ *
+ * @param sock the socket address
+ * @param host where the hostname will be written
+ * @param port where the service-port will be written
+ * @param flags the same flags as getnameinfo()
+ * @returns 0 on success, nonzero otherwise.
+ */
+ static int resolve(::KSocketAddress* sock, QString& host, QString& port, int flags = 0) KDE_DEPRECATED;
+
+ /** @deprecated
+ * This function is now deprecated. Please use @ref KNetwork::KResolver::resolve.
+ *
+ * Performs lookup on the given hostname/port combination and returns a list
+ * of matching addresses.
+ * The error code can be transformed into string by KExtendedSocket::strError()
+ * with code of IO_LookupError.
+ *
+ * IMPORTANT: the result values of the QPtrList must be deleted after use. So,
+ * if you don't copy the KAddressInfo objects, the best way to assure that
+ * is to call setAutoDelete(true) on the list right after this function
+ * returns. If you do copy the results out, you must assure that the objects
+ * get deleted when they are not needed any more.
+ *
+ * @param host the hostname to look up
+ * @param port the port/service to look up
+ * @param flags flags to be used when looking up, Flags
+ * @param error pointer to a variable holding the error code
+ * @return a list of KAddressInfos
+ */
+ static QPtrList<KAddressInfo> lookup(const QString& host, const QString& port, int flags = 0, int *error = 0) KDE_DEPRECATED;
+
+ /**
+ * Returns the local socket address
+ * Remember to delete the returned object when it is no longer needed.
+ * @param fd the file descriptor
+ * @return the local socket address or 0 if an error occurred. Delete after use.
+ */
+ static ::KSocketAddress *localAddress(int fd) KDE_DEPRECATED;
+
+ /**
+ * Returns the peer socket address. Use KExtendedSocket::resolve() to
+ * resolve this to a human-readable hostname/service or port.
+ * Remember to delete the returned object when it is no longer needed.
+ * @param fd the file descriptor
+ * @return the peer socket address or 0 if an error occurred. Delete after use.
+ */
+ static ::KSocketAddress *peerAddress(int fd) KDE_DEPRECATED;
+
+ /**
+ * Returns the representing text of this error code
+ * @param code the error code, as seen in status()
+ * @param syserr the system error, as from systemError()
+ * @return the text for the given error code
+ */
+ static QString strError(int code, int syserr);
+
+ /**
+ * Sets/unsets address reusing flag for this socket.
+ *
+ * This function returns true if the value was set correctly. That is NOT
+ * the result of the set.
+ * @param fd the file descriptor
+ * @param enable if true, set address reusable
+ * @return true on success, false on failure.
+ */
+ static bool setAddressReusable(int fd, bool enable) KDE_DEPRECATED;
+
+protected:
+ virtual void virtual_hook( int id, void* data );
+private:
+ KExtendedSocketPrivate *d;
+
+ friend class KSocket;
+ friend class KServerSocket;
+};
+
+/** @deprecated
+ * This class is now deprecated. Please see @ref KNetwork::KResolver for the new API.
+ *
+ * Contains information about an internet address. It wraps addrinfo,
+ * see getaddrinfo(3) for more information.
+ */
+class KDECORE_EXPORT KAddressInfo
+{
+private:
+ addrinfo *ai;
+ ::KSocketAddress *addr;
+
+ inline KAddressInfo() : ai(0), addr(0)
+ { }
+
+ // KAddressInfo(addrinfo *ai);
+ KAddressInfo(KAddressInfo&) { }
+ KAddressInfo& operator=(KAddressInfo&) { return *this; }
+
+public:
+ ~KAddressInfo();
+
+ /**
+ * Returns the KAddressInfo's KSocketAddress.
+ * Only valid as long as the KAddressInfo exists.
+ */
+ inline KDE_DEPRECATED operator const ::KSocketAddress*() const
+ { return addr; }
+
+ /**
+ * Returns the KAddressInfo's addrinfo.
+ */
+ inline KDE_DEPRECATED operator const addrinfo&() const
+ { return *ai; }
+
+ /**
+ * Returns a pointer to KAddressInfo's addrinfo.
+ * Only valid as long as the KAddressInfo exists.
+ */
+ inline KDE_DEPRECATED operator const addrinfo*() const
+ { return ai; }
+
+ /**
+ * Returns the KAddressInfo's KSocketAddress.
+ * Only valid as long as the KAddressInfo exists.
+ * @return the KAddressInfo's KSocketAddress.
+ */
+ inline KDE_DEPRECATED const ::KSocketAddress* address() const
+ { return addr; }
+
+ /**
+ * Returns the flags of the address info (see getaddrinfo(3)).
+ * @return the flags of the addres info.
+ */
+ int flags() const KDE_DEPRECATED;
+
+ /**
+ * Returns the family of the address info (see getaddrinfo(3)).
+ * @return the family of the addres info.
+ */
+ int family() const KDE_DEPRECATED;
+
+ /**
+ * Returns the socket type of the address info (see getaddrinfo(3)).
+ * @return the socket type of the addres info.
+ */
+ int socktype() const KDE_DEPRECATED;
+
+ /**
+ * Returns the protocol of the address info (see getaddrinfo(3)).
+ * @return the protocol of the addres info.
+ */
+ int protocol() const KDE_DEPRECATED;
+
+
+ /**
+ * Returns the official name of the host (see getaddrinfo(3)).
+ * Only valid as long as the KAddressInfo exists.
+ * @return the official name of the host
+ */
+ const char* canonname() const KDE_DEPRECATED;
+
+ /**
+ * Returns the length of the KSocketAddress.
+ * @return the KSocketAddress's length
+ */
+ inline int length() const
+ { if (addr) return addr->size(); return 0; }
+
+ friend class KExtendedSocket;
+};
+
+#endif //Q_OS_UNIX
+
+#endif // KEXTSOCK_H