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