// Copyright (C) 1999-2005 Open Source Telecom Corporation. // // 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 #endif #ifndef CCXX_SOCKET_H_ #include #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 * @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 * @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 * @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 * @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