1 /* GNU LGPL version 2 (or later) - see LICENSE file for details */
2 #include <ccan/io/fdpass/fdpass.h>
3 #include <ccan/fdpass/fdpass.h>
4 #include <ccan/io/io_plan.h>
5 #include <errno.h>
6
do_fd_send(int fd,struct io_plan_arg * arg)7 static int do_fd_send(int fd, struct io_plan_arg *arg)
8 {
9 if (!fdpass_send(fd, arg->u1.s)) {
10 /* In case ccan/io ever gets smart with non-blocking. */
11 if (errno == EAGAIN || errno == EWOULDBLOCK)
12 return 0;
13 return -1;
14 }
15 if (arg->u2.s)
16 close(arg->u1.s);
17 return 1;
18 }
19
io_send_fd_(struct io_conn * conn,int fd,bool fdclose,struct io_plan * (* next)(struct io_conn *,void *),void * next_arg)20 struct io_plan *io_send_fd_(struct io_conn *conn,
21 int fd,
22 bool fdclose,
23 struct io_plan *(*next)(struct io_conn *, void *),
24 void *next_arg)
25 {
26 struct io_plan_arg *arg = io_plan_arg(conn, IO_OUT);
27
28 arg->u1.s = fd;
29 arg->u2.s = fdclose;
30
31 return io_set_plan(conn, IO_OUT, do_fd_send, next, next_arg);
32 }
33
do_fd_recv(int fd,struct io_plan_arg * arg)34 static int do_fd_recv(int fd, struct io_plan_arg *arg)
35 {
36 int fdin = fdpass_recv(fd);
37
38 if (fdin < 0) {
39 /* In case ccan/io ever gets smart with non-blocking. */
40 if (errno == EAGAIN || errno == EWOULDBLOCK)
41 return 0;
42 return -1;
43 }
44 *(int *)arg->u1.vp = fdin;
45 return 1;
46 }
47
io_recv_fd_(struct io_conn * conn,int * fd,struct io_plan * (* next)(struct io_conn *,void *),void * next_arg)48 struct io_plan *io_recv_fd_(struct io_conn *conn,
49 int *fd,
50 struct io_plan *(*next)(struct io_conn *, void *),
51 void *next_arg)
52 {
53 struct io_plan_arg *arg = io_plan_arg(conn, IO_IN);
54
55 arg->u1.vp = fd;
56
57 return io_set_plan(conn, IO_IN, do_fd_recv, next, next_arg);
58 }
59