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, false, 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 */
82int 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}
96