~jamesodhunt/ubuntu/raring/upstart/1.6

« back to all changes in this revision

Viewing changes to nih/io.h

  • Committer: Scott James Remnant
  • Date: 2010-02-04 23:39:59 UTC
  • mfrom: (1182.1.45 upstart)
  • mto: This revision was merged to the branch mainline in revision 1250.
  • Revision ID: scott@netsplit.com-20100204233959-7kajqjnaoh7208ob
Tags: upstream-0.6.5
ImportĀ upstreamĀ versionĀ 0.6.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* libnih
2
 
 *
3
 
 * Copyright Ā© 2009 Scott James Remnant <scott@netsplit.com>.
4
 
 * Copyright Ā© 2009 Canonical Ltd.
5
 
 *
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.
9
 
 *
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.
14
 
 *
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.
18
 
 */
19
 
 
20
 
#ifndef NIH_IO_H
21
 
#define NIH_IO_H
22
 
 
23
 
#include <sys/types.h>
24
 
#include <sys/socket.h>
25
 
 
26
 
#include <nih/macros.h>
27
 
#include <nih/list.h>
28
 
 
29
 
 
30
 
/**
31
 
 * NihIoType:
32
 
 *
33
 
 * Whether an NihIo structure is used for a buffered stream of data, or
34
 
 * a queue of discreet messages.
35
 
 **/
36
 
typedef enum {
37
 
        NIH_IO_STREAM,
38
 
        NIH_IO_MESSAGE
39
 
} NihIoType;
40
 
 
41
 
/**
42
 
 * NihIoEvents:
43
 
 *
44
 
 * Events that we can watch for, generally used as a bit mask of the events
45
 
 * that have occurred.
46
 
 **/
47
 
typedef enum {
48
 
        NIH_IO_NONE   = 00,
49
 
        NIH_IO_READ   = 01,
50
 
        NIH_IO_WRITE  = 02,
51
 
        NIH_IO_EXCEPT = 04,
52
 
} NihIoEvents;
53
 
 
54
 
 
55
 
/* Predefine the typedefs as we use them in the callbacks */
56
 
typedef struct nih_io_watch NihIoWatch;
57
 
typedef struct nih_io       NihIo;
58
 
 
59
 
/**
60
 
 * NihIoWatcher:
61
 
 * @data: data pointer given when registered,
62
 
 * @watch: #NihIoWatch for which an event occurred,
63
 
 * @events: events that occurred.
64
 
 *
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.
68
 
 **/
69
 
typedef void (*NihIoWatcher) (void *data, NihIoWatch *watch,
70
 
                              NihIoEvents events);
71
 
 
72
 
/**
73
 
 * NihIoReader:
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.
78
 
 *
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.
82
 
 *
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.
87
 
 *
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.
92
 
 *
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().
97
 
 **/
98
 
typedef void (*NihIoReader) (void *data, NihIo *io,
99
 
                             const char *buf, size_t len);
100
 
 
101
 
/**
102
 
 * NihIoCloseHandler:
103
 
 * @data: data pointer given when registered.
104
 
 * @io: NihIo that closed.
105
 
 *
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
108
 
 * read from it.
109
 
 *
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().
113
 
 **/
114
 
typedef void (*NihIoCloseHandler) (void *data, NihIo *io);
115
 
 
116
 
/**
117
 
 * NihIoErrorHandler:
118
 
 * @data: data pointer given when registered,
119
 
 * @io: NihIo that caused the error.
120
 
 *
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().
124
 
 *
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().
128
 
 **/
129
 
typedef void (*NihIoErrorHandler) (void *data, NihIo *io);
130
 
 
131
 
 
132
 
/**
133
 
 * NihIoWatch:
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.
139
 
 *
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.
143
 
 *
144
 
 * The watch can be cancelled by calling nih_list_remove() on the structure
145
 
 * as they are held in a list internally.
146
 
 **/
147
 
struct nih_io_watch {
148
 
        NihList       entry;
149
 
        int           fd;
150
 
        NihIoEvents   events;
151
 
 
152
 
        NihIoWatcher  watcher;
153
 
        void         *data;
154
 
};
155
 
 
156
 
/**
157
 
 * NihIoBuffer:
158
 
 * @buf: memory allocated for buffer,
159
 
 * @size: allocated size of @buf,
160
 
 * @len: number of bytes of @buf used.
161
 
 *
162
 
 * This structure is used to represent a buffer holding data that is
163
 
 * waiting to be sent or processed.
164
 
 **/
165
 
typedef struct nih_io_buffer {
166
 
        char   *buf;
167
 
        size_t  size;
168
 
        size_t  len;
169
 
} NihIoBuffer;
170
 
 
171
 
/**
172
 
 * NihIoMessage:
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.
180
 
 *
181
 
 * This structure is used to represent an individual message waiting in
182
 
 * a queue to be sent or processed.
183
 
 *
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
188
 
 * initialised.
189
 
 **/
190
 
typedef struct nih_io_message {
191
 
        NihList           entry;
192
 
 
193
 
        struct sockaddr  *addr;
194
 
        socklen_t         addrlen;
195
 
 
196
 
        NihIoBuffer      *data;
197
 
        struct cmsghdr  **control;
198
 
 
199
 
        union {
200
 
                int      int_data;
201
 
                void    *ptr_data;
202
 
        };
203
 
} NihIoMessage;
204
 
 
205
 
/**
206
 
 * NihIo:
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.
219
 
 *
220
 
 * This structure implements more featureful I/O handling than provided by
221
 
 * an NihIoWatch alone.
222
 
 *
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.
226
 
 *
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.
230
 
 *
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.
234
 
 *
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.
238
 
 **/
239
 
struct nih_io {
240
 
        NihIoType            type;
241
 
 
242
 
        NihIoWatch          *watch;
243
 
        union {
244
 
                NihIoBuffer *send_buf;
245
 
                NihList     *send_q;
246
 
        };
247
 
        union {
248
 
                NihIoBuffer *recv_buf;
249
 
                NihList     *recv_q;
250
 
        };
251
 
 
252
 
        NihIoReader          reader;
253
 
        NihIoCloseHandler    close_handler;
254
 
        NihIoErrorHandler    error_handler;
255
 
        void                *data;
256
 
 
257
 
        int                  shutdown;
258
 
        int                 *free;
259
 
};
260
 
 
261
 
 
262
 
NIH_BEGIN_EXTERN
263
 
 
264
 
extern NihList *nih_io_watches;
265
 
 
266
 
 
267
 
void          nih_io_init                (void);
268
 
 
269
 
NihIoWatch *  nih_io_add_watch           (const void *parent, int fd,
270
 
                                          NihIoEvents events,
271
 
                                          NihIoWatcher watcher, void *data)
272
 
        __attribute__ ((warn_unused_result, malloc));
273
 
 
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,
277
 
                                          fd_set *exceptfds);
278
 
 
279
 
 
280
 
NihIoBuffer * nih_io_buffer_new          (const void *parent)
281
 
        __attribute__ ((warn_unused_result, malloc));
282
 
 
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));
291
 
 
292
 
 
293
 
NihIoMessage *nih_io_message_new         (const void *parent)
294
 
        __attribute__ ((warn_unused_result, malloc));
295
 
 
296
 
int           nih_io_message_add_control (NihIoMessage *message, int level,
297
 
                                          int type, socklen_t len,
298
 
                                          const void *data)
299
 
        __attribute__ ((warn_unused_result));
300
 
 
301
 
NihIoMessage *nih_io_message_recv        (const void *parent, int fd,
302
 
                                          size_t *len)
303
 
        __attribute__ ((warn_unused_result, malloc));
304
 
ssize_t       nih_io_message_send        (NihIoMessage *message, int fd)
305
 
        __attribute__ ((warn_unused_result));
306
 
 
307
 
 
308
 
NihIo *       nih_io_reopen              (const void *parent, int fd,
309
 
                                          NihIoType type, NihIoReader reader,
310
 
                                          NihIoCloseHandler close_handler,
311
 
                                          NihIoErrorHandler error_handler,
312
 
                                          void *data)
313
 
        __attribute__ ((warn_unused_result, malloc));
314
 
void          nih_io_shutdown            (NihIo *io);
315
 
int           nih_io_destroy             (NihIo *io);
316
 
 
317
 
NihIoMessage *nih_io_read_message        (const void *parent, NihIo *io);
318
 
void          nih_io_send_message        (NihIo *io, NihIoMessage *message);
319
 
 
320
 
char *        nih_io_read                (const void *parent, NihIo *io,
321
 
                                          size_t *len)
322
 
        __attribute__ ((warn_unused_result, malloc));
323
 
int           nih_io_write               (NihIo *io, const char *str,
324
 
                                          size_t len)
325
 
        __attribute__ ((warn_unused_result));
326
 
 
327
 
char *        nih_io_get                 (const void *parent, NihIo *io,
328
 
                                          const char *delim)
329
 
        __attribute__ ((warn_unused_result, malloc));
330
 
 
331
 
int           nih_io_printf              (NihIo *io, const char *format, ...)
332
 
        __attribute__ ((warn_unused_result, format (printf, 2, 3)));
333
 
 
334
 
 
335
 
int           nih_io_set_nonblock        (int fd);
336
 
int           nih_io_set_cloexec         (int fd);
337
 
 
338
 
ssize_t       nih_io_get_family          (int fd);
339
 
 
340
 
NIH_END_EXTERN
341
 
 
342
 
#endif /* NIH_IO_H */