1 /*************************************************************************
2 > File Name: pass_fd.c
3 > Author:Monica
4 > Mail:liling222@126.com
5 > Created Time: Mon 07 Jul 2014 09:52:49 PM CST
6 ************************************************************************/
7
8 #include <stdio.h>
9 #include <sys/types.h>
10 #include <sys/socket.h>
11 #include <strings.h>
12 #include <stdlib.h>
13 #include <unistd.h>
14 #include <signal.h>
15 #include <sys/stat.h>
16 #include <fcntl.h>
17 #include <string.h>
18
19 void my_handler(int signum)
20 {
21 wait(NULL);
22 exit(0);
23 }
24 void send_n(int fd_socket, int fd_to_send);
25 void recv_n(int fd_socket, int* fd_to_recv);
26
27 int main(int argc, char* argv[]) //exe filename
28 {
29 int fd_socket[2];
30 int fd_file;
31 if(socketpair(AF_LOCAL, SOCK_STREAM, 0, fd_socket) == -1)
32 {
33 perror("socketpair");
34 exit(-1);
35 }
36 if(fork()>0) //parent fd[0]
37 {
38 close(fd_socket[1]);
39 signal(SIGCHLD, my_handler);
40 fd_file = open(argv[1], O_RDONLY);
41 if(fd_file == -1)
42 {
43 perror("open");
44 close(fd_socket[0]);
45 close(fd_socket[1]);
46 exit(-1);
47 }
48 send_n(fd_socket[0], fd_file);
49 printf("parent fd_file:%d\n", fd_file);
50 close(fd_file);
51 close(fd_socket[0]);
52 return;
53 }
54 else //child fd[1]
55 {
56 int fd_to_recv;
57 char buf[1024];
58 close(fd_socket[0]);
59 recv_n(fd_socket[1], &fd_to_recv);
60 printf("child recv fd:%d\n", fd_to_recv);
61 FILE* fp = fdopen(fd_to_recv, "r");
62 while(bzero(buf, 1024), fgets(buf, 1024, fp) != NULL)
63 {
64 printf("%s", buf);
65 }
66 fclose(fp);
67 close(fd_to_recv);
68 close(fd_socket[1]);
69 }
70 return 0;
71 }
72 void send_n(int fd_socket, int fd_to_send)
73 {
74 struct msghdr send_msg;
75 struct iovec bufs[1];
76 struct cmsghdr *pcmsg;
77 char buffer[]="hello world";
78 int cmsglen = CMSG_LEN(sizeof(int));
79 send_msg.msg_name = NULL;
80 send_msg.msg_namelen = 0;
81 send_msg.msg_flags = 0;
82 bufs[0].iov_base = buffer;
83 bufs[0].iov_len = strlen(buffer);
84 send_msg.msg_iov = bufs;
85 send_msg.msg_iovlen = 1;
86 pcmsg = (struct cmsghdr*)calloc(1, cmsglen);
87 pcmsg->cmsg_len = cmsglen;
88 pcmsg->cmsg_level = SOL_SOCKET;
89 pcmsg->cmsg_type = SCM_RIGHTS;
90 *(int*)CMSG_DATA(pcmsg) = fd_to_send;
91 send_msg.msg_control = pcmsg;
92 send_msg.msg_controllen = cmsglen;
93 sendmsg(fd_socket, &send_msg, 0);
94 }
95
96 void recv_n(int fd_socket, int* fd_to_recv)
97 {
98 struct msghdr recv_msg;
99 struct iovec bufs[1];
100 struct cmsghdr* pcmsg;
101 char buffer[1024]="";
102 int cmsglen = CMSG_LEN(sizeof(int));
103 pcmsg = (struct cmsghdr*)calloc(1,cmsglen );
104 bufs[0].iov_base = buffer;
105 bufs[0].iov_len = 1024;
106 recv_msg.msg_iov = bufs;
107 recv_msg.msg_iovlen = 1;
108 recv_msg.msg_control = pcmsg;
109 recv_msg.msg_controllen = cmsglen;
110 recvmsg(fd_socket, &recv_msg, 0);
111 printf("buf:%s\n", buffer);
112 *fd_to_recv = *(int*)CMSG_DATA(pcmsg);
113 }