_info 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "config.h"
  4. /**
  5. * io - simple library for stateful io handling.
  6. *
  7. * io provides a simple mechanism to write I/O servers with multiple
  8. * connections. Handling of connections is multiplexed, and function
  9. * indicate what they want written or read, and what follow-on
  10. * function to call on success (or failure).
  11. *
  12. * Example:
  13. * // Given tr A-Z a-z outputs tr a-z a-z
  14. * #include <ccan/io/io.h>
  15. * #include <ccan/err/err.h>
  16. * #include <assert.h>
  17. * #include <stdlib.h>
  18. * #include <signal.h>
  19. * #include <sys/types.h>
  20. * #include <sys/wait.h>
  21. *
  22. * struct buffer {
  23. * size_t max, off, rlen;
  24. * char *buf;
  25. * };
  26. *
  27. * struct stdin_buffer {
  28. * struct io_conn *reader, *writer;
  29. * size_t len;
  30. * char inbuf[4096];
  31. * };
  32. *
  33. * // This reads from stdin.
  34. * static struct io_plan *wake_writer(struct io_conn *, struct stdin_buffer *);
  35. * // This writes the stdin buffer to the child.
  36. * static struct io_plan *write_to_child(struct io_conn *c,
  37. * struct stdin_buffer *b);
  38. * static struct io_plan *read_stdin(struct io_conn *c, struct stdin_buffer *b)
  39. * {
  40. * assert(c == b->reader);
  41. * b->len = sizeof(b->inbuf);
  42. * return io_read_partial(b->inbuf, &b->len,
  43. * io_next(c, wake_writer, b));
  44. * }
  45. *
  46. * static struct io_plan *wake_writer(struct io_conn *c, struct stdin_buffer *b)
  47. * {
  48. * assert(c == b->reader);
  49. * io_wake(b->writer, write_to_child, b);
  50. * return io_idle(c);
  51. * }
  52. *
  53. * static void reader_exit(struct io_conn *c, struct stdin_buffer *b)
  54. * {
  55. * assert(c == b->reader);
  56. * io_wake(b->writer, write_to_child, b);
  57. * b->reader = NULL;
  58. * }
  59. *
  60. * static struct io_plan *wake_reader(struct io_conn *c, struct stdin_buffer *b)
  61. * {
  62. * assert(c == b->writer);
  63. * io_wake(b->reader, read_stdin, b);
  64. * return io_idle(c);
  65. * }
  66. *
  67. * static struct io_plan *write_to_child(struct io_conn *conn,
  68. * struct stdin_buffer *b)
  69. * {
  70. * assert(conn == b->writer);
  71. * if (!b->reader)
  72. * return io_close(conn, NULL);
  73. * return io_write(b->inbuf, b->len, io_next(conn, wake_reader, b));
  74. * }
  75. *
  76. * static struct io_plan *start_writer(struct io_conn *conn,
  77. * struct stdin_buffer *b)
  78. * {
  79. * assert(conn == b->writer);
  80. * return io_idle(conn);
  81. * }
  82. *
  83. * static void fail_child_write(struct io_conn *conn, struct stdin_buffer *b)
  84. * {
  85. * if (b->reader)
  86. * err(1, "Failed writing to child.");
  87. * }
  88. *
  89. * // This reads from the child and saves it into buffer.
  90. * static struct io_plan *read_from_child(struct io_conn *conn,
  91. * struct buffer *b)
  92. * {
  93. * b->off += b->rlen;
  94. *
  95. * if (b->off == b->max) {
  96. * if (b->max == 0)
  97. * b->max = 128;
  98. * else if (b->max >= 1024*1024)
  99. * b->max += 1024*1024;
  100. * else
  101. * b->max *= 2;
  102. * b->buf = realloc(b->buf, b->max);
  103. * }
  104. *
  105. * b->rlen = b->max - b->off;
  106. * return io_read_partial(b->buf + b->off, &b->rlen,
  107. * io_next(conn, read_from_child, b));
  108. * }
  109. *
  110. * // Feed a program our stdin, gather its stdout, print that at end.
  111. * int main(int argc, char *argv[])
  112. * {
  113. * int tochild[2], fromchild[2];
  114. * struct buffer out = { 0, 0, 0, NULL };
  115. * struct stdin_buffer sbuf;
  116. * int status;
  117. * size_t off;
  118. * ssize_t ret;
  119. *
  120. * if (argc == 1)
  121. * errx(1, "Usage: runner <cmdline>...");
  122. *
  123. * if (pipe(tochild) != 0 || pipe(fromchild) != 0)
  124. * err(1, "Creating pipes");
  125. *
  126. * if (!fork()) {
  127. * // Child runs command.
  128. * close(tochild[1]);
  129. * close(fromchild[0]);
  130. *
  131. * dup2(tochild[0], STDIN_FILENO);
  132. * dup2(fromchild[1], STDOUT_FILENO);
  133. * execvp(argv[1], argv + 1);
  134. * exit(127);
  135. * }
  136. *
  137. * close(tochild[0]);
  138. * close(fromchild[1]);
  139. * signal(SIGPIPE, SIG_IGN);
  140. *
  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,
  143. * &sbuf);
  144. * if (!sbuf.reader || !sbuf.writer
  145. * || !io_new_conn(fromchild[0], read_from_child, NULL, &out))
  146. * err(1, "Allocating connections");
  147. *
  148. * io_loop();
  149. * wait(&status);
  150. *
  151. * for (off = 0; off < out.off; off += ret) {
  152. * ret = write(STDOUT_FILENO, out.buf+off, out.off-off);
  153. * if (ret < 0)
  154. * err(1, "Writing stdout");
  155. * }
  156. * free(out.buf);
  157. *
  158. * return WIFEXITED(status) ? WEXITSTATUS(status) : 2;
  159. * }
  160. *
  161. * License: LGPL (v2.1 or any later version)
  162. * Author: Rusty Russell <rusty@rustcorp.com.au>
  163. */
  164. int main(int argc, char *argv[])
  165. {
  166. if (argc != 2)
  167. return 1;
  168. if (strcmp(argv[1], "depends") == 0) {
  169. printf("ccan/time\n");
  170. printf("ccan/timer\n");
  171. return 0;
  172. }
  173. return 1;
  174. }