| // Copyright (C) 1999-2005 Open Source Telecom Corporation. |
| // Copyright (C) 2006-2010 David Sugar, Tycho Softworks. |
| // |
| // This program is free software; you can redistribute it and/or modify |
| // it under the terms of the GNU General Public License as published by |
| // the Free Software Foundation; either version 2 of the License, or |
| // (at your option) any later version. |
| // |
| // This program 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 General Public License for more details. |
| // |
| // You should have received a copy of the GNU General Public License |
| // along with this program; if not, write to the Free Software |
| // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| // |
| // As a special exception, you may use this file as part of a free software |
| // library without restriction. Specifically, if other files instantiate |
| // templates or use macros or inline functions from this file, or you compile |
| // this file and link it with other files to produce an executable, this |
| // file does not by itself cause the resulting executable to be covered by |
| // the GNU General Public License. This exception does not however |
| // invalidate any other reasons why the executable file might be covered by |
| // the GNU General Public License. |
| // |
| // This exception applies only to the code released under the name GNU |
| // Common C++. If you copy code from other releases into a copy of GNU |
| // Common C++, as the General Public License permits, the exception does |
| // not apply to the code that you add in this way. To avoid misleading |
| // anyone as to the status of such modified files, you must delete |
| // this exception notice from them. |
| // |
| // If you write modifications of your own for GNU Common C++, it is your choice |
| // whether to permit this exception to apply to your modifications. |
| // If you do not wish that, delete this exception notice. |
| // |
| |
| /** |
| * @file unix.h |
| * @short UNIX domain sockets, streams and sessions. |
| **/ |
| |
| #ifndef CCXX_UNIX_H_ |
| #define CCXX_UNIX_H_ |
| |
| #ifndef CCXX_MISSING_H_ |
| #include <cc++/missing.h> |
| #endif |
| |
| #ifndef CCXX_SOCKET_H_ |
| #include <cc++/socket.h> |
| #endif |
| |
| #ifdef CCXX_NAMESPACES |
| namespace ost { |
| #endif |
| |
| #ifndef WIN32 |
| |
| /** |
| * Unix domain sockets are used for stream based connected sessions between |
| * processes on the same machine. |
| |
| * An implicit and unique UnixSocket object exists in Common C++ to represent |
| * a bound Unix domain socket acting as a "server" for receiving connection requests. |
| * This class is not part of UnixStream because such objects normally perform |
| * no physical I/O (read or write operations) other than to specify a listen |
| * backlog queue and perform "accept" operations for pending connections. |
| * |
| * @author Alex Pavloff <alex@pavloff.net> |
| * @short bound server for Unix domain streams and sessions. |
| */ |
| class UnixSocket : protected Socket { |
| protected: |
| friend class UnixStream; |
| friend class SocketPort; |
| friend class unixstream; |
| |
| void close(void); |
| char *path; |
| |
| public: |
| /** |
| * A Unix domain "server" is created as a Unix domain socket that is bound |
| * to a pathname and that has a backlog queue to listen for connection |
| * requests. If the server cannot be created, an exception is thrown. |
| * |
| * @param pathname pathname to socket file |
| * @param backlog size of connection request queue. |
| */ |
| UnixSocket(const char* pathname, int backlog = 5); |
| |
| /** |
| * Used to wait for pending connection requests. |
| */ |
| inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF) /** not const -- jfc */ |
| {return Socket::isPending(pendingInput, timeout);} |
| |
| /** |
| * Use base socket handler for ending this socket. |
| */ |
| virtual ~UnixSocket(); |
| }; |
| |
| /** |
| * Unix streams are used to represent Unix domain client connections to a |
| * local server for accepting client connections. The Unix |
| * stream is a C++ "stream" class, and can accept streaming of data to |
| * and from other C++ objects using the << and >> operators. |
| * |
| * Unix Stream itself can be formed either by connecting to a bound network |
| * address of a Unix domain server, or can be created when "accepting" a |
| * network connection from a Unix domain server. |
| * |
| * @author Alex Pavloff <alex@pavloff.net> |
| * @short streamable Unix domain socket connection. |
| */ |
| class UnixStream : public Socket, public std::streambuf, public std::iostream { |
| private: |
| int doallocate(); |
| |
| protected: |
| timeout_t timeout; |
| int bufsize; |
| char *gbuf, *pbuf; |
| |
| /** |
| * The constructor required for "unixstream", a more C++ style |
| * version of the TCPStream class. |
| */ |
| UnixStream(bool throwflag = true); |
| |
| /** |
| * Used to allocate the buffer space needed for iostream |
| * operations. This function is called by the constructor. |
| * |
| * @param size of stream buffers from constructor. |
| */ |
| void allocate(int size); |
| |
| /** |
| * Used to terminate the buffer space and cleanup the socket |
| * connection. This fucntion is called by the destructor. |
| */ |
| void endStream(void); |
| |
| /** |
| * This streambuf method is used to load the input buffer |
| * through the established unix domain socket connection. |
| * |
| * @return char from get buffer, EOF if not connected. |
| */ |
| virtual int underflow(void); |
| |
| /** |
| * This streambuf method is used for doing unbuffered reads |
| * through the established unix domain socket connection when in interactive mode. |
| * Also this method will handle proper use of buffers if not in |
| * interative mode. |
| * |
| * @return char from unix domain socket connection, EOF if not connected. |
| */ |
| int uflow(void); |
| |
| /** |
| * This streambuf method is used to write the output |
| * buffer through the established unix domain connection. |
| * |
| * @param ch char to push through. |
| * @return char pushed through. |
| */ |
| int overflow(int ch); |
| |
| /** |
| * Create a Unix domain stream by connecting to a Unix domain socket |
| * |
| * @param pathname path to socket |
| * @param size of streaming input and output buffers. |
| */ |
| void connect(const char* pathname, int size); |
| |
| /** |
| * Used in derived classes to refer to the current object via |
| * it's iostream. For example, to send a set of characters |
| * in a derived method, one might use *tcp() << "test". |
| * |
| * @return stream pointer of this object. |
| */ |
| std::iostream *unixstr(void) |
| {return ((std::iostream *)this);}; |
| |
| public: |
| /** |
| * Create a Unix domain stream by accepting a connection from a bound |
| * Unix domain socket acting as a server. This performs an "accept" |
| * call. |
| * |
| * @param server socket listening. |
| * @param size of streaming input and output buffers. |
| * @param throwflag flag to throw errors. |
| * @param timeout for all operations. |
| */ |
| UnixStream(UnixSocket &server, int size = 512, bool throwflag = true, timeout_t timeout = 0); |
| |
| /** |
| * Create a Unix domain stream by connecting to a Unix domain socket |
| * |
| * @param pathname path to socket |
| * @param size of streaming input and output buffers. |
| * @param throwflag flag to throw errors. |
| * @param to timeout for all operations. |
| */ |
| UnixStream(const char* pathname, int size = 512, bool throwflag = true, timeout_t to = 0); |
| |
| /** |
| * Set the I/O operation timeout for socket I/O operations. |
| * |
| * @param to timeout to set. |
| */ |
| inline void setTimeout(timeout_t to) |
| {timeout = to;}; |
| |
| /** |
| * A copy constructor creates a new stream buffer. |
| * |
| * @param source of copy. |
| * |
| */ |
| UnixStream(const UnixStream &source); |
| |
| /** |
| * Flush and empty all buffers, and then remove the allocated |
| * buffers. |
| */ |
| virtual ~UnixStream(); |
| |
| /** |
| * Flushes the stream input and output buffers, writes |
| * pending output. |
| * |
| * @return 0 on success. |
| */ |
| int sync(void); |
| |
| /** |
| * Get the status of pending stream data. This can be used to |
| * examine if input or output is waiting, or if an error or |
| * disconnect has occured on the stream. If a read buffer |
| * contains data then input is ready and if write buffer |
| * contains data it is first flushed and then checked. |
| */ |
| bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF); |
| |
| /** |
| * Return the size of the current stream buffering used. |
| * |
| * @return size of stream buffers. |
| */ |
| int getBufferSize(void) const |
| {return bufsize;}; |
| }; |
| |
| /** |
| * A more natural C++ "unixstream" class for use by non-threaded |
| * applications. This class behaves a lot more like fstream and |
| * similar classes. |
| * |
| * @author Alex Pavloff <alex@pavloff.net> |
| * @short C++ "fstream" style unixstream class. |
| */ |
| class unixstream : public UnixStream { |
| public: |
| /** |
| * Construct an unopened "tcpstream" object. |
| */ |
| unixstream(); |
| |
| /** |
| * Construct and "open" (connect) the tcp stream to a remote |
| * socket. |
| * |
| * @param pathname pathname to socket file |
| * @param buffer size for streaming (optional). |
| */ |
| unixstream(const char *pathname, int buffer = 512); |
| |
| /** |
| * Construct and "accept" (connect) the tcp stream through |
| * a server. |
| * |
| * @param unixsock socket to accept from. |
| * @param buffer size for streaming (optional). |
| */ |
| unixstream(UnixSocket &unixsock, int buffer = 512); |
| |
| /** |
| * Open a tcp stream connection. This will close the currently |
| * active connection first. |
| * |
| * @param pathname pathname to socket file |
| * @param buffer size for streaming (optional) |
| */ |
| void open(const char *pathname, int buffer = 512) |
| {UnixStream::connect( pathname, buffer );} |
| |
| /** |
| * Open a tcp stream connection by accepting a tcp socket. |
| * |
| * @param unixsock socket to accept from. |
| * @param buffer size for streaming (optional) |
| */ |
| void open(UnixSocket &unixsock, int buffer = 512); |
| |
| /** |
| * Close the active tcp stream connection. |
| */ |
| void close(void); |
| |
| /** |
| * Test to see if stream is open. |
| */ |
| bool operator!() const; |
| }; |
| |
| /** |
| * The Unix domain session is used to primarily to represent a client connection |
| * that can be managed on a seperate thread. The Unix domain session also supports |
| * a non-blocking connection scheme which prevents blocking during the |
| * constructor and moving the process of completing a connection into the |
| * thread that executes for the session. |
| * |
| * @author Alex Pavloff <alex@pavloff.net> |
| * @short Threaded streamable unix domain socket with non-blocking constructor. |
| */ |
| class __EXPORT UnixSession : public Thread, public UnixStream { |
| protected: |
| /** |
| * Normally called during the thread Initial() method by default, |
| * this will wait for the socket connection to complete when |
| * connecting to a remote socket. One might wish to use |
| * setCompletion() to change the socket back to blocking I/O |
| * calls after the connection completes. To implement the |
| * session one must create a derived class which implements |
| * Run(). |
| * |
| * @return 0 if successful, -1 if timed out. |
| * @param timeout to wait for completion in milliseconds. |
| */ |
| int waitConnection(timeout_t timeout = TIMEOUT_INF); |
| |
| /** |
| * The initial method is used to esablish a connection when |
| * delayed completion is used. This assures the constructor |
| * terminates without having to wait for a connection request |
| * to complete. |
| */ |
| void initial(void); |
| |
| public: |
| /** |
| * Create a Unix domain socket that will be connected to a local server |
| * server and that will execute under it's own thread. |
| * |
| * @param pathname path to socket |
| * @param size of streaming buffer. |
| * @param pri execution priority relative to parent. |
| * @param stack allocation needed on some platforms. |
| */ |
| UnixSession(const char* pathname, int size = 512, int pri = 0, int stack = 0); |
| |
| /** |
| * Create a Unix domain socket from a bound Unix domain server by accepting a pending |
| * connection from that server and execute a thread for the accepted connection. |
| * |
| * @param server unix domain socket to accept a connection from. |
| * @param size of streaming buffer. |
| * @param pri execution priority relative to parent. |
| * @param stack allocation needed on some platforms. |
| */ |
| UnixSession(UnixSocket &server, int size = 512, |
| int pri = 0, int stack = 0); |
| |
| /** |
| * Virtual destructor. |
| */ |
| virtual ~UnixSession(); |
| }; |
| |
| #endif // ndef WIN32 |
| |
| #ifdef CCXX_NAMESPACES |
| } |
| #endif |
| |
| #endif |
| |
| |
| |