136a483b2SMatthew Dillon
236a483b2SMatthew Dillon /*
336a483b2SMatthew Dillon * cc -Wall fdpassing.c -o /tmp/fdp
436a483b2SMatthew Dillon */
536a483b2SMatthew Dillon #include <sys/types.h>
636a483b2SMatthew Dillon #include <sys/socket.h>
736a483b2SMatthew Dillon #include <sys/wait.h>
836a483b2SMatthew Dillon #include <sys/uio.h>
936a483b2SMatthew Dillon #include <sys/stat.h>
1036a483b2SMatthew Dillon #include <stdio.h>
1136a483b2SMatthew Dillon #include <stdlib.h>
1236a483b2SMatthew Dillon #include <unistd.h>
1336a483b2SMatthew Dillon #include <string.h>
1436a483b2SMatthew Dillon #include <fcntl.h>
1536a483b2SMatthew Dillon #include <errno.h>
1636a483b2SMatthew Dillon
1736a483b2SMatthew Dillon void sendfd(int s, int fd);
1836a483b2SMatthew Dillon int recvfd(int s);
1936a483b2SMatthew Dillon
2036a483b2SMatthew Dillon int
main(int ac,char ** av)2136a483b2SMatthew Dillon main(int ac, char **av)
2236a483b2SMatthew Dillon {
2336a483b2SMatthew Dillon struct stat st;
2436a483b2SMatthew Dillon int fds[2];
2536a483b2SMatthew Dillon int fd;
2636a483b2SMatthew Dillon int i;
2736a483b2SMatthew Dillon int dummy;
2836a483b2SMatthew Dillon
2936a483b2SMatthew Dillon if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fds) < 0) {
30*0dc51cc9SSascha Wildner perror("socketpair");
3136a483b2SMatthew Dillon exit(1);
3236a483b2SMatthew Dillon }
3336a483b2SMatthew Dillon fcntl(fds[0], F_SETFL, 0);
3436a483b2SMatthew Dillon fcntl(fds[1], F_SETFL, 0);
3536a483b2SMatthew Dillon if (fork() == 0) {
3636a483b2SMatthew Dillon close(fds[1]);
3736a483b2SMatthew Dillon while ((fd = recvfd(fds[0])) >= 0) {
3836a483b2SMatthew Dillon fflush(stdout);
3936a483b2SMatthew Dillon usleep(1000000 / 10);
4036a483b2SMatthew Dillon if (fstat(fd, &st) < 0)
4136a483b2SMatthew Dillon printf("B");
4236a483b2SMatthew Dillon else if (read(fd, &dummy, sizeof(dummy)) != sizeof(dummy))
4336a483b2SMatthew Dillon printf("b");
4436a483b2SMatthew Dillon else
4536a483b2SMatthew Dillon printf("r");
4636a483b2SMatthew Dillon close(fd);
4736a483b2SMatthew Dillon usleep(1000000 / 10);
4836a483b2SMatthew Dillon }
4936a483b2SMatthew Dillon printf("X\n");
5036a483b2SMatthew Dillon _exit(0);
5136a483b2SMatthew Dillon }
5236a483b2SMatthew Dillon close(fds[0]);
5336a483b2SMatthew Dillon
5436a483b2SMatthew Dillon for (;;) {
5536a483b2SMatthew Dillon for (i = 1; i < ac; ++i) {
5636a483b2SMatthew Dillon if ((fd = open(av[i], O_RDONLY, 0666)) < 0) {
5736a483b2SMatthew Dillon fprintf(stderr, "unable to open %s\n", av[i]);
5836a483b2SMatthew Dillon } else {
5936a483b2SMatthew Dillon sendfd(fds[1], fd);
6036a483b2SMatthew Dillon printf("w");
6136a483b2SMatthew Dillon fflush(stdout);
6236a483b2SMatthew Dillon close(fd);
6336a483b2SMatthew Dillon }
6436a483b2SMatthew Dillon }
6536a483b2SMatthew Dillon usleep(1000000 / 5 - 10000);
6636a483b2SMatthew Dillon }
6736a483b2SMatthew Dillon printf("DONE\n");
6836a483b2SMatthew Dillon close(fds[1]);
6936a483b2SMatthew Dillon while (wait(NULL) < 0)
7036a483b2SMatthew Dillon ;
7136a483b2SMatthew Dillon return(0);
7236a483b2SMatthew Dillon }
7336a483b2SMatthew Dillon
7436a483b2SMatthew Dillon void
sendfd(int s,int fd)7536a483b2SMatthew Dillon sendfd(int s, int fd)
7636a483b2SMatthew Dillon {
7736a483b2SMatthew Dillon struct msghdr msg;
7836a483b2SMatthew Dillon struct {
7936a483b2SMatthew Dillon struct cmsghdr cmsg;
8036a483b2SMatthew Dillon int fd;
8136a483b2SMatthew Dillon } cmsg;
8236a483b2SMatthew Dillon struct iovec iov;
8336a483b2SMatthew Dillon
8436a483b2SMatthew Dillon bzero(&msg, sizeof(msg));
8536a483b2SMatthew Dillon bzero(&cmsg, sizeof(cmsg));
8636a483b2SMatthew Dillon
8736a483b2SMatthew Dillon iov.iov_base = NULL;
8836a483b2SMatthew Dillon iov.iov_len = 0;
8936a483b2SMatthew Dillon
9036a483b2SMatthew Dillon msg.msg_iov = &iov;
9136a483b2SMatthew Dillon msg.msg_iovlen = 1;
9236a483b2SMatthew Dillon msg.msg_control = (caddr_t)&cmsg;
9336a483b2SMatthew Dillon msg.msg_controllen = sizeof(cmsg);
9436a483b2SMatthew Dillon
9536a483b2SMatthew Dillon cmsg.cmsg.cmsg_level = SOL_SOCKET;
9636a483b2SMatthew Dillon cmsg.cmsg.cmsg_type = SCM_RIGHTS;
9736a483b2SMatthew Dillon cmsg.cmsg.cmsg_len = sizeof(cmsg);
9836a483b2SMatthew Dillon cmsg.fd = fd;
9936a483b2SMatthew Dillon
10036a483b2SMatthew Dillon if (sendmsg(s, &msg, 0) < 0) {
10136a483b2SMatthew Dillon printf("sendfd: failed %s\n", strerror(errno));
10236a483b2SMatthew Dillon exit(1);
10336a483b2SMatthew Dillon }
10436a483b2SMatthew Dillon }
10536a483b2SMatthew Dillon
10636a483b2SMatthew Dillon int
recvfd(int s)10736a483b2SMatthew Dillon recvfd(int s)
10836a483b2SMatthew Dillon {
10936a483b2SMatthew Dillon struct msghdr msg;
11036a483b2SMatthew Dillon struct {
11136a483b2SMatthew Dillon struct cmsghdr cmsg;
11236a483b2SMatthew Dillon int fd;
11336a483b2SMatthew Dillon } cmsg;
11436a483b2SMatthew Dillon struct iovec iov;
11536a483b2SMatthew Dillon int r;
11636a483b2SMatthew Dillon int dummy;
11736a483b2SMatthew Dillon
11836a483b2SMatthew Dillon bzero(&msg, sizeof(msg));
11936a483b2SMatthew Dillon bzero(&cmsg, sizeof(cmsg));
12036a483b2SMatthew Dillon
12136a483b2SMatthew Dillon iov.iov_base = &dummy;
12236a483b2SMatthew Dillon iov.iov_len = sizeof(dummy);
12336a483b2SMatthew Dillon
12436a483b2SMatthew Dillon msg.msg_iov = &iov;
12536a483b2SMatthew Dillon msg.msg_iovlen = 1;
12636a483b2SMatthew Dillon msg.msg_control = (caddr_t)&cmsg;
12736a483b2SMatthew Dillon msg.msg_controllen = sizeof(cmsg);
12836a483b2SMatthew Dillon
12936a483b2SMatthew Dillon #if 0
13036a483b2SMatthew Dillon cmsg.cmsg.cmsg_level = SOL_SOCKET;
13136a483b2SMatthew Dillon cmsg.cmsg.cmsg_type = SCM_RIGHTS;
13236a483b2SMatthew Dillon #endif
13336a483b2SMatthew Dillon cmsg.cmsg.cmsg_len = sizeof(cmsg);
13436a483b2SMatthew Dillon cmsg.fd = -1;
13536a483b2SMatthew Dillon
13636a483b2SMatthew Dillon if ((r = recvmsg(s, &msg, MSG_EOR)) < 0) {
13736a483b2SMatthew Dillon printf("recvmsg: failed %s\n", strerror(errno));
13836a483b2SMatthew Dillon return(-1);
13936a483b2SMatthew Dillon }
14036a483b2SMatthew Dillon return(cmsg.fd);
14136a483b2SMatthew Dillon }
142