blob: b6be17ffc44f574a56bb9845b89bdcde20d0c1e8 [file] [log] [blame]
Emeric Vigier2f625822012-08-06 11:09:52 -04001// Copyright (C) 1999-2005 Open Source Telecom Corporation.
2// Copyright (C) 2006-2010 David Sugar, Tycho Softworks.
3//
4// This program is free software; you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation; either version 2 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program; if not, write to the Free Software
16// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17//
18// As a special exception, you may use this file as part of a free software
19// library without restriction. Specifically, if other files instantiate
20// templates or use macros or inline functions from this file, or you compile
21// this file and link it with other files to produce an executable, this
22// file does not by itself cause the resulting executable to be covered by
23// the GNU General Public License. This exception does not however
24// invalidate any other reasons why the executable file might be covered by
25// the GNU General Public License.
26//
27// This exception applies only to the code released under the name GNU
28// Common C++. If you copy code from other releases into a copy of GNU
29// Common C++, as the General Public License permits, the exception does
30// not apply to the code that you add in this way. To avoid misleading
31// anyone as to the status of such modified files, you must delete
32// this exception notice from them.
33//
34// If you write modifications of your own for GNU Common C++, it is your choice
35// whether to permit this exception to apply to your modifications.
36// If you do not wish that, delete this exception notice.
37//
38
39/**
40 * @file unix.h
41 * @short UNIX domain sockets, streams and sessions.
42 **/
43
44#ifndef CCXX_UNIX_H_
45#define CCXX_UNIX_H_
46
47#ifndef CCXX_MISSING_H_
48#include <cc++/missing.h>
49#endif
50
51#ifndef CCXX_SOCKET_H_
52#include <cc++/socket.h>
53#endif
54
55#ifdef CCXX_NAMESPACES
56namespace ost {
57#endif
58
59#ifndef WIN32
60
61 /**
62 * Unix domain sockets are used for stream based connected sessions between
63 * processes on the same machine.
64
65 * An implicit and unique UnixSocket object exists in Common C++ to represent
66 * a bound Unix domain socket acting as a "server" for receiving connection requests.
67 * This class is not part of UnixStream because such objects normally perform
68 * no physical I/O (read or write operations) other than to specify a listen
69 * backlog queue and perform "accept" operations for pending connections.
70 *
71 * @author Alex Pavloff <alex@pavloff.net>
72 * @short bound server for Unix domain streams and sessions.
73 */
74 class UnixSocket : protected Socket {
75 protected:
76 friend class UnixStream;
77 friend class SocketPort;
78 friend class unixstream;
79
80 void close(void);
81 char *path;
82
83 public:
84 /**
85 * A Unix domain "server" is created as a Unix domain socket that is bound
86 * to a pathname and that has a backlog queue to listen for connection
87 * requests. If the server cannot be created, an exception is thrown.
88 *
89 * @param pathname pathname to socket file
90 * @param backlog size of connection request queue.
91 */
92 UnixSocket(const char* pathname, int backlog = 5);
93
94 /**
95 * Used to wait for pending connection requests.
96 */
97 inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF) /** not const -- jfc */
98 {return Socket::isPending(pendingInput, timeout);}
99
100 /**
101 * Use base socket handler for ending this socket.
102 */
103 virtual ~UnixSocket();
104 };
105
106 /**
107 * Unix streams are used to represent Unix domain client connections to a
108 * local server for accepting client connections. The Unix
109 * stream is a C++ "stream" class, and can accept streaming of data to
110 * and from other C++ objects using the << and >> operators.
111 *
112 * Unix Stream itself can be formed either by connecting to a bound network
113 * address of a Unix domain server, or can be created when "accepting" a
114 * network connection from a Unix domain server.
115 *
116 * @author Alex Pavloff <alex@pavloff.net>
117 * @short streamable Unix domain socket connection.
118 */
119 class UnixStream : public Socket, public std::streambuf, public std::iostream {
120 private:
121 int doallocate();
122
123 protected:
124 timeout_t timeout;
125 int bufsize;
126 char *gbuf, *pbuf;
127
128 /**
129 * The constructor required for "unixstream", a more C++ style
130 * version of the TCPStream class.
131 */
132 UnixStream(bool throwflag = true);
133
134 /**
135 * Used to allocate the buffer space needed for iostream
136 * operations. This function is called by the constructor.
137 *
138 * @param size of stream buffers from constructor.
139 */
140 void allocate(int size);
141
142 /**
143 * Used to terminate the buffer space and cleanup the socket
144 * connection. This fucntion is called by the destructor.
145 */
146 void endStream(void);
147
148 /**
149 * This streambuf method is used to load the input buffer
150 * through the established unix domain socket connection.
151 *
152 * @return char from get buffer, EOF if not connected.
153 */
154 virtual int underflow(void);
155
156 /**
157 * This streambuf method is used for doing unbuffered reads
158 * through the established unix domain socket connection when in interactive mode.
159 * Also this method will handle proper use of buffers if not in
160 * interative mode.
161 *
162 * @return char from unix domain socket connection, EOF if not connected.
163 */
164 int uflow(void);
165
166 /**
167 * This streambuf method is used to write the output
168 * buffer through the established unix domain connection.
169 *
170 * @param ch char to push through.
171 * @return char pushed through.
172 */
173 int overflow(int ch);
174
175 /**
176 * Create a Unix domain stream by connecting to a Unix domain socket
177 *
178 * @param pathname path to socket
179 * @param size of streaming input and output buffers.
180 */
181 void connect(const char* pathname, int size);
182
183 /**
184 * Used in derived classes to refer to the current object via
185 * it's iostream. For example, to send a set of characters
186 * in a derived method, one might use *tcp() << "test".
187 *
188 * @return stream pointer of this object.
189 */
190 std::iostream *unixstr(void)
191 {return ((std::iostream *)this);};
192
193 public:
194 /**
195 * Create a Unix domain stream by accepting a connection from a bound
196 * Unix domain socket acting as a server. This performs an "accept"
197 * call.
198 *
199 * @param server socket listening.
200 * @param size of streaming input and output buffers.
201 * @param throwflag flag to throw errors.
202 * @param timeout for all operations.
203 */
204 UnixStream(UnixSocket &server, int size = 512, bool throwflag = true, timeout_t timeout = 0);
205
206 /**
207 * Create a Unix domain stream by connecting to a Unix domain socket
208 *
209 * @param pathname path to socket
210 * @param size of streaming input and output buffers.
211 * @param throwflag flag to throw errors.
212 * @param to timeout for all operations.
213 */
214 UnixStream(const char* pathname, int size = 512, bool throwflag = true, timeout_t to = 0);
215
216 /**
217 * Set the I/O operation timeout for socket I/O operations.
218 *
219 * @param to timeout to set.
220 */
221 inline void setTimeout(timeout_t to)
222 {timeout = to;};
223
224 /**
225 * A copy constructor creates a new stream buffer.
226 *
227 * @param source of copy.
228 *
229 */
230 UnixStream(const UnixStream &source);
231
232 /**
233 * Flush and empty all buffers, and then remove the allocated
234 * buffers.
235 */
236 virtual ~UnixStream();
237
238 /**
239 * Flushes the stream input and output buffers, writes
240 * pending output.
241 *
242 * @return 0 on success.
243 */
244 int sync(void);
245
246 /**
247 * Get the status of pending stream data. This can be used to
248 * examine if input or output is waiting, or if an error or
249 * disconnect has occured on the stream. If a read buffer
250 * contains data then input is ready and if write buffer
251 * contains data it is first flushed and then checked.
252 */
253 bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
254
255 /**
256 * Return the size of the current stream buffering used.
257 *
258 * @return size of stream buffers.
259 */
260 int getBufferSize(void) const
261 {return bufsize;};
262 };
263
264 /**
265 * A more natural C++ "unixstream" class for use by non-threaded
266 * applications. This class behaves a lot more like fstream and
267 * similar classes.
268 *
269 * @author Alex Pavloff <alex@pavloff.net>
270 * @short C++ "fstream" style unixstream class.
271 */
272 class unixstream : public UnixStream {
273 public:
274 /**
275 * Construct an unopened "tcpstream" object.
276 */
277 unixstream();
278
279 /**
280 * Construct and "open" (connect) the tcp stream to a remote
281 * socket.
282 *
283 * @param pathname pathname to socket file
284 * @param buffer size for streaming (optional).
285 */
286 unixstream(const char *pathname, int buffer = 512);
287
288 /**
289 * Construct and "accept" (connect) the tcp stream through
290 * a server.
291 *
292 * @param unixsock socket to accept from.
293 * @param buffer size for streaming (optional).
294 */
295 unixstream(UnixSocket &unixsock, int buffer = 512);
296
297 /**
298 * Open a tcp stream connection. This will close the currently
299 * active connection first.
300 *
301 * @param pathname pathname to socket file
302 * @param buffer size for streaming (optional)
303 */
304 void open(const char *pathname, int buffer = 512)
305 {UnixStream::connect( pathname, buffer );}
306
307 /**
308 * Open a tcp stream connection by accepting a tcp socket.
309 *
310 * @param unixsock socket to accept from.
311 * @param buffer size for streaming (optional)
312 */
313 void open(UnixSocket &unixsock, int buffer = 512);
314
315 /**
316 * Close the active tcp stream connection.
317 */
318 void close(void);
319
320 /**
321 * Test to see if stream is open.
322 */
323 bool operator!() const;
324 };
325
326 /**
327 * The Unix domain session is used to primarily to represent a client connection
328 * that can be managed on a seperate thread. The Unix domain session also supports
329 * a non-blocking connection scheme which prevents blocking during the
330 * constructor and moving the process of completing a connection into the
331 * thread that executes for the session.
332 *
333 * @author Alex Pavloff <alex@pavloff.net>
334 * @short Threaded streamable unix domain socket with non-blocking constructor.
335 */
336 class __EXPORT UnixSession : public Thread, public UnixStream {
337 protected:
338 /**
339 * Normally called during the thread Initial() method by default,
340 * this will wait for the socket connection to complete when
341 * connecting to a remote socket. One might wish to use
342 * setCompletion() to change the socket back to blocking I/O
343 * calls after the connection completes. To implement the
344 * session one must create a derived class which implements
345 * Run().
346 *
347 * @return 0 if successful, -1 if timed out.
348 * @param timeout to wait for completion in milliseconds.
349 */
350 int waitConnection(timeout_t timeout = TIMEOUT_INF);
351
352 /**
353 * The initial method is used to esablish a connection when
354 * delayed completion is used. This assures the constructor
355 * terminates without having to wait for a connection request
356 * to complete.
357 */
358 void initial(void);
359
360 public:
361 /**
362 * Create a Unix domain socket that will be connected to a local server
363 * server and that will execute under it's own thread.
364 *
365 * @param pathname path to socket
366 * @param size of streaming buffer.
367 * @param pri execution priority relative to parent.
368 * @param stack allocation needed on some platforms.
369 */
370 UnixSession(const char* pathname, int size = 512, int pri = 0, int stack = 0);
371
372 /**
373 * Create a Unix domain socket from a bound Unix domain server by accepting a pending
374 * connection from that server and execute a thread for the accepted connection.
375 *
376 * @param server unix domain socket to accept a connection from.
377 * @param size of streaming buffer.
378 * @param pri execution priority relative to parent.
379 * @param stack allocation needed on some platforms.
380 */
381 UnixSession(UnixSocket &server, int size = 512,
382 int pri = 0, int stack = 0);
383
384 /**
385 * Virtual destructor.
386 */
387 virtual ~UnixSession();
388 };
389
390#endif // ndef WIN32
391
392#ifdef CCXX_NAMESPACES
393}
394#endif
395
396#endif
397
398
399