xref: /OK3568_Linux_fs/kernel/tools/testing/selftests/android/ion/ipcsocket.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun #include <stdio.h>
2*4882a593Smuzhiyun #include <stdlib.h>
3*4882a593Smuzhiyun #include <string.h>
4*4882a593Smuzhiyun #include <unistd.h>
5*4882a593Smuzhiyun #include <sys/types.h>
6*4882a593Smuzhiyun #include <sys/socket.h>
7*4882a593Smuzhiyun #include <sys/time.h>
8*4882a593Smuzhiyun #include <sys/un.h>
9*4882a593Smuzhiyun #include <errno.h>
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #include "ipcsocket.h"
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun 
opensocket(int * sockfd,const char * name,int connecttype)14*4882a593Smuzhiyun int opensocket(int *sockfd, const char *name, int connecttype)
15*4882a593Smuzhiyun {
16*4882a593Smuzhiyun 	int ret, temp = 1;
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun 	if (!name || strlen(name) > MAX_SOCK_NAME_LEN) {
19*4882a593Smuzhiyun 		fprintf(stderr, "<%s>: Invalid socket name.\n", __func__);
20*4882a593Smuzhiyun 		return -1;
21*4882a593Smuzhiyun 	}
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun 	ret = socket(PF_LOCAL, SOCK_STREAM, 0);
24*4882a593Smuzhiyun 	if (ret < 0) {
25*4882a593Smuzhiyun 		fprintf(stderr, "<%s>: Failed socket: <%s>\n",
26*4882a593Smuzhiyun 			__func__, strerror(errno));
27*4882a593Smuzhiyun 		return ret;
28*4882a593Smuzhiyun 	}
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun 	*sockfd = ret;
31*4882a593Smuzhiyun 	if (setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR,
32*4882a593Smuzhiyun 		(char *)&temp, sizeof(int)) < 0) {
33*4882a593Smuzhiyun 		fprintf(stderr, "<%s>: Failed setsockopt: <%s>\n",
34*4882a593Smuzhiyun 		__func__, strerror(errno));
35*4882a593Smuzhiyun 		goto err;
36*4882a593Smuzhiyun 	}
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun 	sprintf(sock_name, "/tmp/%s", name);
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun 	if (connecttype == 1) {
41*4882a593Smuzhiyun 		/* This is for Server connection */
42*4882a593Smuzhiyun 		struct sockaddr_un skaddr;
43*4882a593Smuzhiyun 		int clientfd;
44*4882a593Smuzhiyun 		socklen_t sklen;
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun 		unlink(sock_name);
47*4882a593Smuzhiyun 		memset(&skaddr, 0, sizeof(skaddr));
48*4882a593Smuzhiyun 		skaddr.sun_family = AF_LOCAL;
49*4882a593Smuzhiyun 		strcpy(skaddr.sun_path, sock_name);
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun 		ret = bind(*sockfd, (struct sockaddr *)&skaddr,
52*4882a593Smuzhiyun 			SUN_LEN(&skaddr));
53*4882a593Smuzhiyun 		if (ret < 0) {
54*4882a593Smuzhiyun 			fprintf(stderr, "<%s>: Failed bind: <%s>\n",
55*4882a593Smuzhiyun 			__func__, strerror(errno));
56*4882a593Smuzhiyun 			goto err;
57*4882a593Smuzhiyun 		}
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun 		ret = listen(*sockfd, 5);
60*4882a593Smuzhiyun 		if (ret < 0) {
61*4882a593Smuzhiyun 			fprintf(stderr, "<%s>: Failed listen: <%s>\n",
62*4882a593Smuzhiyun 			__func__, strerror(errno));
63*4882a593Smuzhiyun 			goto err;
64*4882a593Smuzhiyun 		}
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun 		memset(&skaddr, 0, sizeof(skaddr));
67*4882a593Smuzhiyun 		sklen = sizeof(skaddr);
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 		ret = accept(*sockfd, (struct sockaddr *)&skaddr,
70*4882a593Smuzhiyun 			(socklen_t *)&sklen);
71*4882a593Smuzhiyun 		if (ret < 0) {
72*4882a593Smuzhiyun 			fprintf(stderr, "<%s>: Failed accept: <%s>\n",
73*4882a593Smuzhiyun 			__func__, strerror(errno));
74*4882a593Smuzhiyun 			goto err;
75*4882a593Smuzhiyun 		}
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun 		clientfd = ret;
78*4882a593Smuzhiyun 		*sockfd = clientfd;
79*4882a593Smuzhiyun 	} else {
80*4882a593Smuzhiyun 		/* This is for client connection */
81*4882a593Smuzhiyun 		struct sockaddr_un skaddr;
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 		memset(&skaddr, 0, sizeof(skaddr));
84*4882a593Smuzhiyun 		skaddr.sun_family = AF_LOCAL;
85*4882a593Smuzhiyun 		strcpy(skaddr.sun_path, sock_name);
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 		ret = connect(*sockfd, (struct sockaddr *)&skaddr,
88*4882a593Smuzhiyun 			SUN_LEN(&skaddr));
89*4882a593Smuzhiyun 		if (ret < 0) {
90*4882a593Smuzhiyun 			fprintf(stderr, "<%s>: Failed connect: <%s>\n",
91*4882a593Smuzhiyun 			__func__, strerror(errno));
92*4882a593Smuzhiyun 			goto err;
93*4882a593Smuzhiyun 		}
94*4882a593Smuzhiyun 	}
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun 	return 0;
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun err:
99*4882a593Smuzhiyun 	if (*sockfd)
100*4882a593Smuzhiyun 		close(*sockfd);
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun 	return ret;
103*4882a593Smuzhiyun }
104*4882a593Smuzhiyun 
sendtosocket(int sockfd,struct socketdata * skdata)105*4882a593Smuzhiyun int sendtosocket(int sockfd, struct socketdata *skdata)
106*4882a593Smuzhiyun {
107*4882a593Smuzhiyun 	int ret, buffd;
108*4882a593Smuzhiyun 	unsigned int len;
109*4882a593Smuzhiyun 	char cmsg_b[CMSG_SPACE(sizeof(int))];
110*4882a593Smuzhiyun 	struct cmsghdr *cmsg;
111*4882a593Smuzhiyun 	struct msghdr msgh;
112*4882a593Smuzhiyun 	struct iovec iov;
113*4882a593Smuzhiyun 	struct timeval timeout;
114*4882a593Smuzhiyun 	fd_set selFDs;
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	if (!skdata) {
117*4882a593Smuzhiyun 		fprintf(stderr, "<%s>: socketdata is NULL\n", __func__);
118*4882a593Smuzhiyun 		return -1;
119*4882a593Smuzhiyun 	}
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun 	FD_ZERO(&selFDs);
122*4882a593Smuzhiyun 	FD_SET(0, &selFDs);
123*4882a593Smuzhiyun 	FD_SET(sockfd, &selFDs);
124*4882a593Smuzhiyun 	timeout.tv_sec = 20;
125*4882a593Smuzhiyun 	timeout.tv_usec = 0;
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun 	ret = select(sockfd+1, NULL, &selFDs, NULL, &timeout);
128*4882a593Smuzhiyun 	if (ret < 0) {
129*4882a593Smuzhiyun 		fprintf(stderr, "<%s>: Failed select: <%s>\n",
130*4882a593Smuzhiyun 		__func__, strerror(errno));
131*4882a593Smuzhiyun 		return -1;
132*4882a593Smuzhiyun 	}
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun 	if (FD_ISSET(sockfd, &selFDs)) {
135*4882a593Smuzhiyun 		buffd = skdata->data;
136*4882a593Smuzhiyun 		len = skdata->len;
137*4882a593Smuzhiyun 		memset(&msgh, 0, sizeof(msgh));
138*4882a593Smuzhiyun 		msgh.msg_control = &cmsg_b;
139*4882a593Smuzhiyun 		msgh.msg_controllen = CMSG_LEN(len);
140*4882a593Smuzhiyun 		iov.iov_base = "OK";
141*4882a593Smuzhiyun 		iov.iov_len = 2;
142*4882a593Smuzhiyun 		msgh.msg_iov = &iov;
143*4882a593Smuzhiyun 		msgh.msg_iovlen = 1;
144*4882a593Smuzhiyun 		cmsg = CMSG_FIRSTHDR(&msgh);
145*4882a593Smuzhiyun 		cmsg->cmsg_level = SOL_SOCKET;
146*4882a593Smuzhiyun 		cmsg->cmsg_type = SCM_RIGHTS;
147*4882a593Smuzhiyun 		cmsg->cmsg_len = CMSG_LEN(len);
148*4882a593Smuzhiyun 		memcpy(CMSG_DATA(cmsg), &buffd, len);
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 		ret = sendmsg(sockfd, &msgh, MSG_DONTWAIT);
151*4882a593Smuzhiyun 		if (ret < 0) {
152*4882a593Smuzhiyun 			fprintf(stderr, "<%s>: Failed sendmsg: <%s>\n",
153*4882a593Smuzhiyun 			__func__, strerror(errno));
154*4882a593Smuzhiyun 			return -1;
155*4882a593Smuzhiyun 		}
156*4882a593Smuzhiyun 	}
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 	return 0;
159*4882a593Smuzhiyun }
160*4882a593Smuzhiyun 
receivefromsocket(int sockfd,struct socketdata * skdata)161*4882a593Smuzhiyun int receivefromsocket(int sockfd, struct socketdata *skdata)
162*4882a593Smuzhiyun {
163*4882a593Smuzhiyun 	int ret, buffd;
164*4882a593Smuzhiyun 	unsigned int len = 0;
165*4882a593Smuzhiyun 	char cmsg_b[CMSG_SPACE(sizeof(int))];
166*4882a593Smuzhiyun 	struct cmsghdr *cmsg;
167*4882a593Smuzhiyun 	struct msghdr msgh;
168*4882a593Smuzhiyun 	struct iovec iov;
169*4882a593Smuzhiyun 	fd_set recvFDs;
170*4882a593Smuzhiyun 	char data[32];
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	if (!skdata) {
173*4882a593Smuzhiyun 		fprintf(stderr, "<%s>: socketdata is NULL\n", __func__);
174*4882a593Smuzhiyun 		return -1;
175*4882a593Smuzhiyun 	}
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun 	FD_ZERO(&recvFDs);
178*4882a593Smuzhiyun 	FD_SET(0, &recvFDs);
179*4882a593Smuzhiyun 	FD_SET(sockfd, &recvFDs);
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun 	ret = select(sockfd+1, &recvFDs, NULL, NULL, NULL);
182*4882a593Smuzhiyun 	if (ret < 0) {
183*4882a593Smuzhiyun 		fprintf(stderr, "<%s>: Failed select: <%s>\n",
184*4882a593Smuzhiyun 		__func__, strerror(errno));
185*4882a593Smuzhiyun 		return -1;
186*4882a593Smuzhiyun 	}
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun 	if (FD_ISSET(sockfd, &recvFDs)) {
189*4882a593Smuzhiyun 		len = sizeof(buffd);
190*4882a593Smuzhiyun 		memset(&msgh, 0, sizeof(msgh));
191*4882a593Smuzhiyun 		msgh.msg_control = &cmsg_b;
192*4882a593Smuzhiyun 		msgh.msg_controllen = CMSG_LEN(len);
193*4882a593Smuzhiyun 		iov.iov_base = data;
194*4882a593Smuzhiyun 		iov.iov_len = sizeof(data)-1;
195*4882a593Smuzhiyun 		msgh.msg_iov = &iov;
196*4882a593Smuzhiyun 		msgh.msg_iovlen = 1;
197*4882a593Smuzhiyun 		cmsg = CMSG_FIRSTHDR(&msgh);
198*4882a593Smuzhiyun 		cmsg->cmsg_level = SOL_SOCKET;
199*4882a593Smuzhiyun 		cmsg->cmsg_type = SCM_RIGHTS;
200*4882a593Smuzhiyun 		cmsg->cmsg_len = CMSG_LEN(len);
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun 		ret = recvmsg(sockfd, &msgh, MSG_DONTWAIT);
203*4882a593Smuzhiyun 		if (ret < 0) {
204*4882a593Smuzhiyun 			fprintf(stderr, "<%s>: Failed recvmsg: <%s>\n",
205*4882a593Smuzhiyun 			__func__, strerror(errno));
206*4882a593Smuzhiyun 			return -1;
207*4882a593Smuzhiyun 		}
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun 		memcpy(&buffd, CMSG_DATA(cmsg), len);
210*4882a593Smuzhiyun 		skdata->data = buffd;
211*4882a593Smuzhiyun 		skdata->len = len;
212*4882a593Smuzhiyun 	}
213*4882a593Smuzhiyun 	return 0;
214*4882a593Smuzhiyun }
215*4882a593Smuzhiyun 
closesocket(int sockfd,char * name)216*4882a593Smuzhiyun int closesocket(int sockfd, char *name)
217*4882a593Smuzhiyun {
218*4882a593Smuzhiyun 	char sockname[MAX_SOCK_NAME_LEN];
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun 	if (sockfd)
221*4882a593Smuzhiyun 		close(sockfd);
222*4882a593Smuzhiyun 	sprintf(sockname, "/tmp/%s", name);
223*4882a593Smuzhiyun 	unlink(sockname);
224*4882a593Smuzhiyun 	shutdown(sockfd, 2);
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun 	return 0;
227*4882a593Smuzhiyun }
228