/usr/include/nih/io.h is in libnih-dev 1.0.3-6ubuntu2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 | /* libnih
*
* Copyright © 2009 Scott James Remnant <scott@netsplit.com>.
* Copyright © 2009 Canonical Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2, as
* published by the Free Software Foundation.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef NIH_IO_H
#define NIH_IO_H
#include <sys/types.h>
#include <sys/socket.h>
#include <nih/macros.h>
#include <nih/list.h>
/**
* NihIoType:
*
* Whether an NihIo structure is used for a buffered stream of data, or
* a queue of discreet messages.
**/
typedef enum {
NIH_IO_STREAM,
NIH_IO_MESSAGE
} NihIoType;
/**
* NihIoEvents:
*
* Events that we can watch for, generally used as a bit mask of the events
* that have occurred.
**/
typedef enum {
NIH_IO_NONE = 00,
NIH_IO_READ = 01,
NIH_IO_WRITE = 02,
NIH_IO_EXCEPT = 04,
} NihIoEvents;
/* Predefine the typedefs as we use them in the callbacks */
typedef struct nih_io_watch NihIoWatch;
typedef struct nih_io NihIo;
/**
* NihIoWatcher:
* @data: data pointer given when registered,
* @watch: #NihIoWatch for which an event occurred,
* @events: events that occurred.
*
* An I/O watcher is a function that is called whenever an event occurs
* on a file descriptor or socket being watched. It is safe for the
* watcher to remove the watch during the call.
**/
typedef void (*NihIoWatcher) (void *data, NihIoWatch *watch,
NihIoEvents events);
/**
* NihIoReader:
* @data: data pointer given when registered,
* @io: NihIo with data to be read,
* @buf: buffer data is available in,
* @len: bytes in @buf.
*
* An I/O reader is a function that is called whenever new data or a new
* message has been received on a file descriptor or socket and placed
* into the receive buffer or queue.
*
* In stream mode, @buf and @len will point to the entire receive buffer
* and this function need not clear the buffer, it is entirely permitted
* for the data to be left there. When further data arrives, the buffer
* will be extended and the reader called again.
*
* In message mode, @buf and @len will point to the contents of the oldest
* message in the receive queue. You'll almost certainly want to remove
* this message from the queue, otherwise when a new message arrives, the
* function will still be called with the same oldest message.
*
* It is safe to call nih_io_close() from within the reader function, this
* results in the structure being flagged to be closed when the watcher
* that invokes it has finished. You must not nih_free() @io or cause it
* to be freed from within this function, except by nih_io_close().
**/
typedef void (*NihIoReader) (void *data, NihIo *io,
const char *buf, size_t len);
/**
* NihIoCloseHandler:
* @data: data pointer given when registered.
* @io: NihIo that closed.
*
* An I/O close handler is a function that is called when the remote end
* of a file descriptor or socket is closed and data can no longer be
* read from it.
*
* It should take appropriate action, which may include closing the
* file descriptor with nih_io_close(). You must not nih_free() @io or
* cause it to be freed from within this function, except by nih_io_close().
**/
typedef void (*NihIoCloseHandler) (void *data, NihIo *io);
/**
* NihIoErrorHandler:
* @data: data pointer given when registered,
* @io: NihIo that caused the error.
*
* An I/O error handler is a function that is called to handle an error
* raise while reading from the file descriptor or socket. The error
* itself can be obtained using nih_error_get().
*
* It should take appropriate action, which may include closing the
* file descriptor with nih_io_close(). You must not nih_free() @io or
* cause it to be freed from within this function, except by nih_io_close().
**/
typedef void (*NihIoErrorHandler) (void *data, NihIo *io);
/**
* NihIoWatch:
* @entry: list header,
* @fd: file descriptor,
* @events: events to watch for,
* @watcher: function called when @events occur on @fd,
* @data: pointer passed to @watcher.
*
* This structure represents the most basic kind of I/O handling, a watch
* on a file descriptor or socket that causes a function to be called
* when listed events occur.
*
* The watch can be cancelled by calling nih_list_remove() on the structure
* as they are held in a list internally.
**/
struct nih_io_watch {
NihList entry;
int fd;
NihIoEvents events;
NihIoWatcher watcher;
void *data;
};
/**
* NihIoBuffer:
* @buf: memory allocated for buffer,
* @size: allocated size of @buf,
* @len: number of bytes of @buf used.
*
* This structure is used to represent a buffer holding data that is
* waiting to be sent or processed.
**/
typedef struct nih_io_buffer {
char *buf;
size_t size;
size_t len;
} NihIoBuffer;
/**
* NihIoMessage:
* @entry: list header,
* @addr: address received from or to be sent to,
* @addrlen: length of @addr,
* @data: buffer for message data,
* @control: NULL-terminated array of control messages,
* @int_data: user-supplied integer data,
* @ptr_data: user-supplied pointer data.
*
* This structure is used to represent an individual message waiting in
* a queue to be sent or processed.
*
* When a message is in the queue, it is sometimes useful to be able to
* associate it with the source or destination of the message, for example
* when handling errors. You may use the @int_data or @ptr_member to store
* an integer or pointer value that is useful to you. These are not usually
* initialised.
**/
typedef struct nih_io_message {
NihList entry;
struct sockaddr *addr;
socklen_t addrlen;
NihIoBuffer *data;
struct cmsghdr **control;
union {
int int_data;
void *ptr_data;
};
} NihIoMessage;
/**
* NihIo:
* @type: type of structure,
* @watch: associated file descriptor watch,
* @send_buf: buffer that pools data to be sent (NIH_IO_STREAM),
* @send_q: queue of messages to be sent (NIH_IO_MESSAGE),
* @recv_buf: buffer that pools data received (NIH_IO_STREAM),
* @recv_q: queue of messages received (NIH_IO_MESSAGE),
* @reader: function called when new data in @recv_buf or @recv_q,
* @close_handler: function called when socket closes,
* @error_handler: function called when an error occurs,
* @data: pointer passed to functions,
* @shutdown: TRUE if the structure should be freed once the buffers are empty,
* @free: pointer to variable to set to TRUE if freed during the watcher.
*
* This structure implements more featureful I/O handling than provided by
* an NihIoWatch alone.
*
* When used in the stream mode (@type is NIH_IO_STREAM), it combines an
* NihIoWatch and two NihIoBuffer structures to implement a high-throughput
* alternative to the traditional stdio functions.
*
* Those functions are optimised to reduce the number of read() or write()
* calls made on a file descriptor, and cannot be used to pool large
* amounts of data for processing.
*
* The NihIo functions are instead optimised for being able to queue and
* receive much data as possible, and have the data sent in the background
* or processed at your leisure.
*
* When used in the message mode (@type is NIH_IO_MESSAGE), it combines the
* NihIoWatch with an NihList of NihIoMessage structures to implement
* asynchronous handling of datagram sockets.
**/
struct nih_io {
NihIoType type;
NihIoWatch *watch;
union {
NihIoBuffer *send_buf;
NihList *send_q;
};
union {
NihIoBuffer *recv_buf;
NihList *recv_q;
};
NihIoReader reader;
NihIoCloseHandler close_handler;
NihIoErrorHandler error_handler;
void *data;
int shutdown;
int *free;
};
NIH_BEGIN_EXTERN
extern NihList *nih_io_watches;
void nih_io_init (void);
NihIoWatch * nih_io_add_watch (const void *parent, int fd,
NihIoEvents events,
NihIoWatcher watcher, void *data)
__attribute__ ((warn_unused_result));
void nih_io_select_fds (int *nfds, fd_set *readfds,
fd_set *writefds, fd_set *exceptfds);
void nih_io_handle_fds (fd_set *readfds, fd_set *writewfds,
fd_set *exceptfds);
NihIoBuffer * nih_io_buffer_new (const void *parent)
__attribute__ ((warn_unused_result));
int nih_io_buffer_resize (NihIoBuffer *buffer, size_t grow);
char * nih_io_buffer_pop (const void *parent,
NihIoBuffer *buffer, size_t *len)
__attribute__ ((warn_unused_result));
void nih_io_buffer_shrink (NihIoBuffer *buffer, size_t len);
int nih_io_buffer_push (NihIoBuffer *buffer,
const char *str, size_t len)
__attribute__ ((warn_unused_result));
NihIoMessage *nih_io_message_new (const void *parent)
__attribute__ ((warn_unused_result));
int nih_io_message_add_control (NihIoMessage *message, int level,
int type, socklen_t len,
const void *data)
__attribute__ ((warn_unused_result));
NihIoMessage *nih_io_message_recv (const void *parent, int fd,
size_t *len)
__attribute__ ((warn_unused_result));
ssize_t nih_io_message_send (NihIoMessage *message, int fd)
__attribute__ ((warn_unused_result));
NihIo * nih_io_reopen (const void *parent, int fd,
NihIoType type, NihIoReader reader,
NihIoCloseHandler close_handler,
NihIoErrorHandler error_handler,
void *data)
__attribute__ ((warn_unused_result));
void nih_io_shutdown (NihIo *io);
int nih_io_destroy (NihIo *io);
NihIoMessage *nih_io_read_message (const void *parent, NihIo *io);
void nih_io_send_message (NihIo *io, NihIoMessage *message);
char * nih_io_read (const void *parent, NihIo *io,
size_t *len)
__attribute__ ((warn_unused_result));
int nih_io_write (NihIo *io, const char *str,
size_t len)
__attribute__ ((warn_unused_result));
char * nih_io_get (const void *parent, NihIo *io,
const char *delim)
__attribute__ ((warn_unused_result));
int nih_io_printf (NihIo *io, const char *format, ...)
__attribute__ ((warn_unused_result, format (printf, 2, 3)));
int nih_io_set_nonblock (int fd);
int nih_io_set_cloexec (int fd);
ssize_t nih_io_get_family (int fd);
NIH_END_EXTERN
#endif /* NIH_IO_H */
|