io/fdpass: add flag to close fd after sending.
[ccan] / ccan / io / fdpass / _info
1 #include "config.h"
2 #include <stdio.h>
3 #include <string.h>
4
5 /**
6  * io/fdpass - IO helper for passing file descriptors across local sockets
7  *
8  * This code adds the ability to pass file descriptors to ccan/io.
9  *
10  * License: LGPL (v2.1 or any later version)
11  * Author: Rusty Russell <rusty@rustcorp.com.au>
12  *
13  * Example:
14  *      // Given "hello" outputs hello
15  *      #include <ccan/io/fdpass/fdpass.h>
16  *      #include <sys/types.h>
17  *      #include <sys/socket.h>
18  *      #include <sys/un.h>
19  *      #include <stdio.h>
20  *      #include <stdlib.h>
21  *      #include <unistd.h>
22  *
23  *      // Child reads stdin into the buffer, prints it out.
24  *      struct buf {
25  *              size_t used;
26  *              char c[100];
27  *      };
28  *      static struct io_plan *read_more(struct io_conn *conn, struct buf *buf)
29  *      {
30  *              printf("%.*s", (int)buf->used, buf->c);
31  *              return io_read_partial(conn, buf->c, sizeof(buf->c), &buf->used,
32  *                                      read_more, buf);
33  *      }
34  *
35  *      // Child has received fd, start reading loop.
36  *      static struct io_plan *got_infd(struct io_conn *conn, int *infd)
37  *      {
38  *              struct buf *buf = calloc(1, sizeof(*buf));
39  *
40  *              io_new_conn(NULL, *infd, read_more, buf);
41  *              return io_close(conn);
42  *      }
43  *      // Child is receiving the fd to read into. 
44  *      static struct io_plan *recv_infd(struct io_conn *conn, int *infd)
45  *      {
46  *              return io_recv_fd(conn, infd, got_infd, infd);
47  *      }
48  *
49  *      // Gets passed fd (stdin), which it reads from.
50  *      static void child(int sockfd)
51  *      {
52  *              int infd;
53  *
54  *              io_new_conn(NULL, sockfd, recv_infd, &infd);
55  *              io_loop(NULL, NULL);
56  *              exit(0);
57  *      }
58  *
59  *      static struct io_plan *send_stdin(struct io_conn *conn, void *unused)
60  *      {
61  *              return io_send_fd(conn, STDIN_FILENO, io_close_cb, NULL);
62  *      }
63  *
64  *      static void parent(int sockfd)
65  *      {
66  *              io_new_conn(NULL, sockfd, send_stdin, NULL);
67  *              io_loop(NULL, NULL);
68  *              exit(0);
69  *      }
70  *      
71  *      int main(void)
72  *      {
73  *              int sv[2];
74  *      
75  *              socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
76  *              if (fork() == 0)
77  *                      child(sv[0]);
78  *              else
79  *                      parent(sv[1]);
80  *      }
81  */
82 int main(int argc, char *argv[])
83 {
84         /* Expect exactly one argument */
85         if (argc != 2)
86                 return 1;
87
88         if (strcmp(argv[1], "depends") == 0) {
89                 printf("ccan/fdpass\n");
90                 printf("ccan/io\n");
91                 return 0;
92         }
93
94         return 1;
95 }