]> git.ozlabs.org Git - ccan/blob - ccan/io/_info
io/fdpass: new module for async fd passing.
[ccan] / ccan / io / _info
1 #include "config.h"
2 #include <stdio.h>
3 #include <string.h>
4
5 /**
6  * io - simple library for asynchronous io handling.
7  *
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
11  * plans.
12  *
13  * Example:
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>
17  * #include <assert.h>
18  * #include <stdlib.h>
19  * #include <signal.h>
20  * #include <sys/types.h>
21  * #include <sys/wait.h>
22  * #include <string.h>
23  *
24  * struct buffer {
25  *      bool finished;
26  *      size_t start, end, rlen, wlen;
27  *      char buf[4096];
28  * };
29  *
30  * static void finish(struct io_conn *c, struct buffer *b)
31  * {
32  *      // Mark us finished.
33  *      b->finished = true;
34  *      // Wake writer just in case it's asleep.
35  *      io_wake(b);
36  * }
37  *
38  * static struct io_plan *read_in(struct io_conn *c, struct buffer *b)
39  * {
40  *      // Add what we just read.
41  *      b->end += b->rlen;
42  *      assert(b->end <= sizeof(b->buf));
43  *
44  *      // If we just read something, wake writer.
45  *      if (b->rlen != 0)
46  *              io_wake(b);
47  *
48  *      // If buffer is empty, return to start.
49  *      if (b->start == b->end)
50  *              b->start = b->end = 0;
51  *
52  *      // No room?  Wait for writer
53  *      if (b->end == sizeof(b->buf))
54  *              return io_wait(c, b, read_in, b);
55  *
56  *      return io_read_partial(c, b->buf + b->end, sizeof(b->buf) - b->end,
57  *                             &b->rlen, read_in, b);
58  * }
59  *
60  * static struct io_plan *write_out(struct io_conn *c, struct buffer *b)
61  * {
62  *      // Remove what we just wrote.
63  *      b->start += b->wlen;
64  *      assert(b->start <= sizeof(b->buf));
65  *
66  *      // If we wrote something, wake writer.
67  *      if (b->wlen != 0)
68  *              io_wake(b);
69  *
70  *      // Nothing to write?  Wait for reader.
71  *      if (b->end == b->start) {
72  *              if (b->finished)
73  *                      return io_close(c);
74  *              return io_wait(c, b, write_out, b);
75  *      }
76  *
77  *      return io_write_partial(c, b->buf + b->start, b->end - b->start,
78  *                              &b->wlen, write_out, b);
79  * }
80  *
81  * // Feed a program our stdin, gather its stdout, print that at end.
82  * int main(int argc, char *argv[])
83  * {
84  *      int tochild[2], fromchild[2];
85  *      struct buffer to, from;
86  *      int status;
87  *      struct io_conn *reader;
88  *
89  *      if (argc == 1)
90  *              errx(1, "Usage: runner <cmdline>...");
91  *
92  *      if (pipe(tochild) != 0 || pipe(fromchild) != 0)
93  *              err(1, "Creating pipes");
94  *
95  *      if (!fork()) {
96  *              // Child runs command.
97  *              close(tochild[1]);
98  *              close(fromchild[0]);
99  *
100  *              dup2(tochild[0], STDIN_FILENO);
101  *              dup2(fromchild[1], STDOUT_FILENO);
102  *              execvp(argv[1], argv + 1);
103  *              exit(127);
104  *      }
105  *
106  *      close(tochild[0]);
107  *      close(fromchild[1]);
108  *      signal(SIGPIPE, SIG_IGN);
109  *
110  *      // Read from stdin, write to child.
111  *      memset(&to, 0, sizeof(to));
112  *      reader = io_new_conn(NULL, STDIN_FILENO, read_in, &to);
113  *      io_set_finish(reader, finish, &to);
114  *      io_new_conn(NULL, tochild[1], write_out, &to);
115  *
116  *      // Read from child, write to stdout.
117  *      reader = io_new_conn(NULL, fromchild[0], read_in, &from);
118  *      io_set_finish(reader, finish, &from);
119  *      io_new_conn(NULL, STDOUT_FILENO, write_out, &from);
120  *
121  *      io_loop(NULL, NULL);
122  *      wait(&status);
123  *
124  *      return WIFEXITED(status) ? WEXITSTATUS(status) : 2;
125  * }
126  *
127  * License: LGPL (v2.1 or any later version)
128  * Author: Rusty Russell <rusty@rustcorp.com.au>
129  */
130 int main(int argc, char *argv[])
131 {
132         if (argc != 2)
133                 return 1;
134
135         if (strcmp(argv[1], "depends") == 0) {
136                 printf("ccan/container_of\n");
137                 printf("ccan/list\n");
138                 printf("ccan/tal\n");
139                 printf("ccan/time\n");
140                 printf("ccan/timer\n");
141                 printf("ccan/typesafe_cb\n");
142                 return 0;
143         }
144
145         return 1;
146 }