6 * io - simple library for asynchronous io handling.
8 * io provides a mechanism to write I/O servers with multiple
9 * connections. Each callback indicates what I/O they plan next
10 * (eg. read, write). It is also possible to write custom I/O
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>
26 * size_t start, end, rlen, wlen;
30 * static void finish(struct io_conn *c, struct buffer *b)
32 * // Mark us finished.
34 * // Wake writer just in case it's asleep.
38 * static struct io_plan *read_in(struct io_conn *c, struct buffer *b)
40 * // Add what we just read.
42 * assert(b->end <= sizeof(b->buf));
44 * // If we just read something, wake writer.
48 * // If buffer is empty, return to start.
49 * if (b->start == b->end)
50 * b->start = b->end = 0;
52 * // No room? Wait for writer
53 * if (b->end == sizeof(b->buf))
54 * return io_wait(c, b, read_in, b);
56 * return io_read_partial(c, b->buf + b->end, sizeof(b->buf) - b->end,
57 * &b->rlen, read_in, b);
60 * static struct io_plan *write_out(struct io_conn *c, struct buffer *b)
62 * // Remove what we just wrote.
63 * b->start += b->wlen;
65 * assert(b->start <= sizeof(b->buf));
67 * // If we wrote something, wake reader.
71 * // Nothing to write? Wait for reader.
72 * if (b->end == b->start) {
75 * return io_wait(c, b, write_out, b);
78 * return io_write_partial(c, b->buf + b->start, b->end - b->start,
79 * &b->wlen, write_out, b);
82 * // Feed a program our stdin, gather its stdout, print that at end.
83 * int main(int argc, char *argv[])
85 * int tochild[2], fromchild[2];
86 * struct buffer to, from;
88 * struct io_conn *reader;
91 * errx(1, "Usage: runner <cmdline>...");
93 * if (pipe(tochild) != 0 || pipe(fromchild) != 0)
94 * err(1, "Creating pipes");
97 * // Child runs command.
99 * close(fromchild[0]);
101 * dup2(tochild[0], STDIN_FILENO);
102 * dup2(fromchild[1], STDOUT_FILENO);
103 * execvp(argv[1], argv + 1);
108 * close(fromchild[1]);
109 * signal(SIGPIPE, SIG_IGN);
111 * // Read from stdin, write to child.
112 * memset(&to, 0, sizeof(to));
113 * reader = io_new_conn(NULL, STDIN_FILENO, read_in, &to);
114 * io_set_finish(reader, finish, &to);
115 * io_new_conn(NULL, tochild[1], write_out, &to);
117 * // Read from child, write to stdout.
118 * memset(&from, 0, sizeof(from));
119 * reader = io_new_conn(NULL, fromchild[0], read_in, &from);
120 * io_set_finish(reader, finish, &from);
121 * io_new_conn(NULL, STDOUT_FILENO, write_out, &from);
123 * io_loop(NULL, NULL);
126 * return WIFEXITED(status) ? WEXITSTATUS(status) : 2;
129 * License: LGPL (v2.1 or any later version)
130 * Author: Rusty Russell <rusty@rustcorp.com.au>
132 int main(int argc, char *argv[])
137 if (strcmp(argv[1], "depends") == 0) {
138 printf("ccan/container_of\n");
139 printf("ccan/list\n");
140 printf("ccan/tal\n");
141 printf("ccan/time\n");
142 printf("ccan/timer\n");
143 printf("ccan/typesafe_cb\n");