X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Fio%2Fio.h;h=510ee0be0166033618768b91cbcafcec8541c85b;hb=a5881c0deb210f56c2095366ae6cdabd5230d68d;hp=fe040bce2f0a6c4c6f8070ecdb02b101e46b7360;hpb=96dcdfbf1a400f7cb43cf3f0761f52fd6de9ff65;p=ccan diff --git a/ccan/io/io.h b/ccan/io/io.h index fe040bce..510ee0be 100644 --- a/ccan/io/io.h +++ b/ccan/io/io.h @@ -4,6 +4,7 @@ #include #include #include +#include #include struct timers; @@ -109,7 +110,8 @@ void io_set_finish_(struct io_conn *conn, * @arg: the argument to @init. * * When @fd becomes readable, we accept(), create a new connection, - * (tal'ocated off @ctx) and pass that to init(). + * (tal'ocated off @ctx) and pass that to init(). Note that if there is + * an error on this file descriptor, it will be freed. * * Returns NULL on error (and sets errno). * @@ -221,7 +223,8 @@ struct io_plan *io_write_(struct io_conn *conn, * * This creates a plan to read data into a buffer. Once it's all * read, the @next function will be called: on an error, the finish - * function is called instead. + * function is called instead. If read() returns 0 (EOF) errno is set + * to 0. * * Note that the I/O may actually be done immediately. * @@ -254,7 +257,8 @@ struct io_plan *io_read_(struct io_conn *conn, * * This creates a plan to read data into a buffer. Once any data is * read, @len is updated and the @next function will be called: on an - * error, the finish function is called instead. + * error, the finish function is called instead. If read() returns 0 (EOF) + * errno is set to 0. * * Note that the I/O may actually be done immediately. * @@ -595,14 +599,16 @@ struct io_plan *io_never(struct io_conn *conn, void *unused); /* FIXME: io_recvfrom/io_sendto */ /** - * io_close - plan to close a connection. + * io_close - close a connection. * @conn: the connection to close. * - * On return to io_loop, the connection will be closed. It doesn't have - * to be the current connection and it doesn't need to be idle. No more - * IO or callbacks will occur. + * The connection is immediately freed: it doesn't have to be the + * current connection and it doesn't need to be idle. No more IO or + * callbacks will occur, but if a function was added by io_set_finish() + * it will be called with the current errno preserved. * - * You can close a connection twice without harmful effects. + * This is equivalent to tal_free(io_conn), except it returns an io_plan + * for use in an io callback. * * Example: * static struct io_plan *close_on_timeout(struct io_conn *conn, const char *msg) @@ -617,14 +623,34 @@ struct io_plan *io_close(struct io_conn *conn); * io_close_cb - helper callback to close a connection. * @conn: the connection. * - * This schedules a connection to be closed; designed to be used as - * a callback function. + * This is closes a connection; designed to be used as a callback + * function. * * Example: * #define close_on_timeout io_close_cb */ struct io_plan *io_close_cb(struct io_conn *, void *unused); +/** + * io_close_taken_fd - close a connection, but remove the filedescriptor first. + * @conn: the connection to take the file descriptor from and close. + * + * io_close closes the file descriptor underlying the io_conn; this version does + * not. Presumably you have used io_conn_fd() on it beforehand and will take + * care of the fd yourself. + * + * Note that this also turns off O_NONBLOCK on the fd. + * + * Example: + * static struct io_plan *steal_fd(struct io_conn *conn, int *fd) + * { + * *fd = io_conn_fd(conn); + * printf("stealing fd %i and closing\n", *fd); + * return io_close_taken_fd(conn); + * } + */ +struct io_plan *io_close_taken_fd(struct io_conn *conn); + /** * io_loop - process fds until all closed on io_break. * @timers - timers which are waiting to go off (or NULL for none) @@ -643,10 +669,69 @@ void *io_loop(struct timers *timers, struct timer **expired); * io_conn_fd - get the fd from a connection. * @conn: the connection. * - * Sometimes useful, eg for getsockname(). + * Sometimes useful, eg for getsockname(). Note that the fd is O_NONBLOCK. + * + * See Also: + * io_close_taken_fd */ int io_conn_fd(const struct io_conn *conn); +/** + * io_plan_in_started - is this conn doing input I/O now? + * @conn: the conn. + * + * This returns true if input I/O has been performed on the conn but + * @next hasn't been called yet. For example, io_read() may have done + * a partial read. + * + * This can be useful if we want to terminate a connection only after + * reading a whole packet: if this returns true, we would wait until + * @next is called. + */ +bool io_plan_in_started(const struct io_conn *conn); + +/** + * io_plan_out_started - is this conn doing output I/O now? + * @conn: the conn. + * + * This returns true if output I/O has been performed on the conn but + * @next hasn't been called yet. For example, io_write() may have done + * a partial write. + * + * This can be useful if we want to terminate a connection only after + * writing a whole packet: if this returns true, we would wait until + * @next is called. + */ +bool io_plan_out_started(const struct io_conn *conn); + +/** + * io_flush_sync - (synchronously) complete any outstanding output. + * @conn: the connection. + * + * This is generally used as an emergency escape, for example when we + * want to write an error message on a socket before terminating, but it may + * be in the middle of existing I/O. We don't want to service any other + * IO, either. + * + * This returns true if all pending output is complete, false on error. + * The next callback is not called on the conn, but will be as soon as + * io_loop() is called. + * + * See Also: + * io_close_taken_fd + */ +bool io_flush_sync(struct io_conn *conn); + +/** + * io_fd_block - helper to set an fd blocking/nonblocking. + * @fd: the file descriptor + * @block: true to set blocking, false to set non-blocking. + * + * Generally only fails is @fd isn't a valid file descriptor, otherwise + * returns true. + */ +bool io_fd_block(int fd, bool block); + /** * io_time_override - override the normal call for time. * @nowfn: the function to call. @@ -657,4 +742,14 @@ int io_conn_fd(const struct io_conn *conn); */ struct timemono (*io_time_override(struct timemono (*now)(void)))(void); +/** + * io_poll_override - override the normal call for poll. + * @pollfn: the function to call. + * + * io usually uses poll() internally, but this forces it to use your + * function (eg. for debugging, suppressing fds, or polling on others unknown + * to ccan/io). Returns the old one. + */ +int (*io_poll_override(int (*poll)(struct pollfd *fds, nfds_t nfds, int timeout)))(struct pollfd *, nfds_t, int); + #endif /* CCAN_IO_H */