6 * io - simple library for stateful io handling.
8 * io provides a simple mechanism to write I/O servers with multiple
9 * connections. Handling of connections is multiplexed, and function
10 * indicate what they want written or read, and what follow-on
11 * function to call on success (or failure).
14 * // Given tr A-Z a-z outputs tr a-z a-z
15 * #include <ccan/io/io.h>
16 * #include <ccan/err/err.h>
20 * #include <sys/types.h>
21 * #include <sys/wait.h>
24 * size_t max, off, rlen;
28 * struct stdin_buffer {
29 * struct io_conn *reader, *writer;
34 * // This reads from stdin.
35 * static struct io_plan *wake_writer(struct io_conn *, struct stdin_buffer *);
36 * // This writes the stdin buffer to the child.
37 * static struct io_plan *write_to_child(struct io_conn *c,
38 * struct stdin_buffer *b);
39 * static struct io_plan *read_stdin(struct io_conn *c, struct stdin_buffer *b)
41 * assert(c == b->reader);
42 * b->len = sizeof(b->inbuf);
43 * return io_read_partial(c, b->inbuf, &b->len, wake_writer, b);
46 * static struct io_plan *wake_writer(struct io_conn *c, struct stdin_buffer *b)
48 * assert(c == b->reader);
49 * io_wake(b->writer, write_to_child, b);
53 * static void reader_exit(struct io_conn *c, struct stdin_buffer *b)
55 * assert(c == b->reader);
56 * io_wake(b->writer, write_to_child, b);
60 * static struct io_plan *wake_reader(struct io_conn *c, struct stdin_buffer *b)
62 * assert(c == b->writer);
63 * io_wake(b->reader, read_stdin, b);
67 * static struct io_plan *write_to_child(struct io_conn *conn,
68 * struct stdin_buffer *b)
70 * assert(conn == b->writer);
72 * return io_close(conn, NULL);
73 * return io_write(conn, b->inbuf, b->len, wake_reader, b);
76 * static struct io_plan *start_writer(struct io_conn *conn,
77 * struct stdin_buffer *b)
79 * assert(conn == b->writer);
80 * return io_idle(conn);
83 * static void fail_child_write(struct io_conn *conn, struct stdin_buffer *b)
86 * err(1, "Failed writing to child.");
89 * // This reads from the child and saves it into buffer.
90 * static struct io_plan *read_from_child(struct io_conn *conn,
95 * if (b->off == b->max) {
98 * else if (b->max >= 1024*1024)
99 * b->max += 1024*1024;
102 * b->buf = realloc(b->buf, b->max);
105 * b->rlen = b->max - b->off;
106 * return io_read_partial(conn, b->buf + b->off, &b->rlen,
107 * read_from_child, b);
110 * // Feed a program our stdin, gather its stdout, print that at end.
111 * int main(int argc, char *argv[])
113 * int tochild[2], fromchild[2];
114 * struct buffer out = { 0, 0, 0, NULL };
115 * struct stdin_buffer sbuf;
121 * errx(1, "Usage: runner <cmdline>...");
123 * if (pipe(tochild) != 0 || pipe(fromchild) != 0)
124 * err(1, "Creating pipes");
127 * // Child runs command.
129 * close(fromchild[0]);
131 * dup2(tochild[0], STDIN_FILENO);
132 * dup2(fromchild[1], STDOUT_FILENO);
133 * execvp(argv[1], argv + 1);
138 * close(fromchild[1]);
139 * signal(SIGPIPE, SIG_IGN);
141 * sbuf.reader = io_new_conn(STDIN_FILENO, read_stdin, reader_exit, &sbuf);
142 * sbuf.writer = io_new_conn(tochild[1], start_writer, fail_child_write,
144 * if (!sbuf.reader || !sbuf.writer
145 * || !io_new_conn(fromchild[0], read_from_child, NULL, &out))
146 * err(1, "Allocating connections");
151 * for (off = 0; off < out.off; off += ret) {
152 * ret = write(STDOUT_FILENO, out.buf+off, out.off-off);
154 * err(1, "Writing stdout");
158 * return WIFEXITED(status) ? WEXITSTATUS(status) : 2;
161 * License: LGPL (v2.1 or any later version)
162 * Author: Rusty Russell <rusty@rustcorp.com.au>
164 int main(int argc, char *argv[])
169 if (strcmp(argv[1], "depends") == 0) {
170 printf("ccan/time\n");
171 printf("ccan/timer\n");