3
* Copyright Ā© 2009 Scott James Remnant <scott@netsplit.com>.
4
* Copyright Ā© 2009 Canonical Ltd.
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License version 2, as
8
* published by the Free Software Foundation.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License along
16
* with this program; if not, write to the Free Software Foundation, Inc.,
17
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23
#include <sys/types.h>
24
#include <sys/socket.h>
26
#include <nih/macros.h>
33
* Whether an NihIo structure is used for a buffered stream of data, or
34
* a queue of discreet messages.
44
* Events that we can watch for, generally used as a bit mask of the events
55
/* Predefine the typedefs as we use them in the callbacks */
56
typedef struct nih_io_watch NihIoWatch;
57
typedef struct nih_io NihIo;
61
* @data: data pointer given when registered,
62
* @watch: #NihIoWatch for which an event occurred,
63
* @events: events that occurred.
65
* An I/O watcher is a function that is called whenever an event occurs
66
* on a file descriptor or socket being watched. It is safe for the
67
* watcher to remove the watch during the call.
69
typedef void (*NihIoWatcher) (void *data, NihIoWatch *watch,
74
* @data: data pointer given when registered,
75
* @io: NihIo with data to be read,
76
* @buf: buffer data is available in,
77
* @len: bytes in @buf.
79
* An I/O reader is a function that is called whenever new data or a new
80
* message has been received on a file descriptor or socket and placed
81
* into the receive buffer or queue.
83
* In stream mode, @buf and @len will point to the entire receive buffer
84
* and this function need not clear the buffer, it is entirely permitted
85
* for the data to be left there. When further data arrives, the buffer
86
* will be extended and the reader called again.
88
* In message mode, @buf and @len will point to the contents of the oldest
89
* message in the receive queue. You'll almost certainly want to remove
90
* this message from the queue, otherwise when a new message arrives, the
91
* function will still be called with the same oldest message.
93
* It is safe to call nih_io_close() from within the reader function, this
94
* results in the structure being flagged to be closed when the watcher
95
* that invokes it has finished. You must not nih_free() @io or cause it
96
* to be freed from within this function, except by nih_io_close().
98
typedef void (*NihIoReader) (void *data, NihIo *io,
99
const char *buf, size_t len);
103
* @data: data pointer given when registered.
104
* @io: NihIo that closed.
106
* An I/O close handler is a function that is called when the remote end
107
* of a file descriptor or socket is closed and data can no longer be
110
* It should take appropriate action, which may include closing the
111
* file descriptor with nih_io_close(). You must not nih_free() @io or
112
* cause it to be freed from within this function, except by nih_io_close().
114
typedef void (*NihIoCloseHandler) (void *data, NihIo *io);
118
* @data: data pointer given when registered,
119
* @io: NihIo that caused the error.
121
* An I/O error handler is a function that is called to handle an error
122
* raise while reading from the file descriptor or socket. The error
123
* itself can be obtained using nih_error_get().
125
* It should take appropriate action, which may include closing the
126
* file descriptor with nih_io_close(). You must not nih_free() @io or
127
* cause it to be freed from within this function, except by nih_io_close().
129
typedef void (*NihIoErrorHandler) (void *data, NihIo *io);
134
* @entry: list header,
135
* @fd: file descriptor,
136
* @events: events to watch for,
137
* @watcher: function called when @events occur on @fd,
138
* @data: pointer passed to @watcher.
140
* This structure represents the most basic kind of I/O handling, a watch
141
* on a file descriptor or socket that causes a function to be called
142
* when listed events occur.
144
* The watch can be cancelled by calling nih_list_remove() on the structure
145
* as they are held in a list internally.
147
struct nih_io_watch {
152
NihIoWatcher watcher;
158
* @buf: memory allocated for buffer,
159
* @size: allocated size of @buf,
160
* @len: number of bytes of @buf used.
162
* This structure is used to represent a buffer holding data that is
163
* waiting to be sent or processed.
165
typedef struct nih_io_buffer {
173
* @entry: list header,
174
* @addr: address received from or to be sent to,
175
* @addrlen: length of @addr,
176
* @data: buffer for message data,
177
* @control: NULL-terminated array of control messages,
178
* @int_data: user-supplied integer data,
179
* @ptr_data: user-supplied pointer data.
181
* This structure is used to represent an individual message waiting in
182
* a queue to be sent or processed.
184
* When a message is in the queue, it is sometimes useful to be able to
185
* associate it with the source or destination of the message, for example
186
* when handling errors. You may use the @int_data or @ptr_member to store
187
* an integer or pointer value that is useful to you. These are not usually
190
typedef struct nih_io_message {
193
struct sockaddr *addr;
197
struct cmsghdr **control;
207
* @type: type of structure,
208
* @watch: associated file descriptor watch,
209
* @send_buf: buffer that pools data to be sent (NIH_IO_STREAM),
210
* @send_q: queue of messages to be sent (NIH_IO_MESSAGE),
211
* @recv_buf: buffer that pools data received (NIH_IO_STREAM),
212
* @recv_q: queue of messages received (NIH_IO_MESSAGE),
213
* @reader: function called when new data in @recv_buf or @recv_q,
214
* @close_handler: function called when socket closes,
215
* @error_handler: function called when an error occurs,
216
* @data: pointer passed to functions,
217
* @shutdown: TRUE if the structure should be freed once the buffers are empty,
218
* @free: pointer to variable to set to TRUE if freed during the watcher.
220
* This structure implements more featureful I/O handling than provided by
221
* an NihIoWatch alone.
223
* When used in the stream mode (@type is NIH_IO_STREAM), it combines an
224
* NihIoWatch and two NihIoBuffer structures to implement a high-throughput
225
* alternative to the traditional stdio functions.
227
* Those functions are optimised to reduce the number of read() or write()
228
* calls made on a file descriptor, and cannot be used to pool large
229
* amounts of data for processing.
231
* The NihIo functions are instead optimised for being able to queue and
232
* receive much data as possible, and have the data sent in the background
233
* or processed at your leisure.
235
* When used in the message mode (@type is NIH_IO_MESSAGE), it combines the
236
* NihIoWatch with an NihList of NihIoMessage structures to implement
237
* asynchronous handling of datagram sockets.
244
NihIoBuffer *send_buf;
248
NihIoBuffer *recv_buf;
253
NihIoCloseHandler close_handler;
254
NihIoErrorHandler error_handler;
264
extern NihList *nih_io_watches;
267
void nih_io_init (void);
269
NihIoWatch * nih_io_add_watch (const void *parent, int fd,
271
NihIoWatcher watcher, void *data)
272
__attribute__ ((warn_unused_result, malloc));
274
void nih_io_select_fds (int *nfds, fd_set *readfds,
275
fd_set *writefds, fd_set *exceptfds);
276
void nih_io_handle_fds (fd_set *readfds, fd_set *writewfds,
280
NihIoBuffer * nih_io_buffer_new (const void *parent)
281
__attribute__ ((warn_unused_result, malloc));
283
int nih_io_buffer_resize (NihIoBuffer *buffer, size_t grow);
284
char * nih_io_buffer_pop (const void *parent,
285
NihIoBuffer *buffer, size_t *len)
286
__attribute__ ((warn_unused_result, malloc));
287
void nih_io_buffer_shrink (NihIoBuffer *buffer, size_t len);
288
int nih_io_buffer_push (NihIoBuffer *buffer,
289
const char *str, size_t len)
290
__attribute__ ((warn_unused_result));
293
NihIoMessage *nih_io_message_new (const void *parent)
294
__attribute__ ((warn_unused_result, malloc));
296
int nih_io_message_add_control (NihIoMessage *message, int level,
297
int type, socklen_t len,
299
__attribute__ ((warn_unused_result));
301
NihIoMessage *nih_io_message_recv (const void *parent, int fd,
303
__attribute__ ((warn_unused_result, malloc));
304
ssize_t nih_io_message_send (NihIoMessage *message, int fd)
305
__attribute__ ((warn_unused_result));
308
NihIo * nih_io_reopen (const void *parent, int fd,
309
NihIoType type, NihIoReader reader,
310
NihIoCloseHandler close_handler,
311
NihIoErrorHandler error_handler,
313
__attribute__ ((warn_unused_result, malloc));
314
void nih_io_shutdown (NihIo *io);
315
int nih_io_destroy (NihIo *io);
317
NihIoMessage *nih_io_read_message (const void *parent, NihIo *io);
318
void nih_io_send_message (NihIo *io, NihIoMessage *message);
320
char * nih_io_read (const void *parent, NihIo *io,
322
__attribute__ ((warn_unused_result, malloc));
323
int nih_io_write (NihIo *io, const char *str,
325
__attribute__ ((warn_unused_result));
327
char * nih_io_get (const void *parent, NihIo *io,
329
__attribute__ ((warn_unused_result, malloc));
331
int nih_io_printf (NihIo *io, const char *format, ...)
332
__attribute__ ((warn_unused_result, format (printf, 2, 3)));
335
int nih_io_set_nonblock (int fd);
336
int nih_io_set_cloexec (int fd);
338
ssize_t nih_io_get_family (int fd);
342
#endif /* NIH_IO_H */