• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* This program is used to test the QEMUD fast pipes.
2  * See external/qemu/docs/ANDROID-QEMUD-PIPES.TXT for details.
3  *
4  * The program acts as a simple TCP server that accepts data and sends
5  * them back to the client.
6  */
7 
8 #include <sys/socket.h>
9 #include <net/inet.h>
10 #include <stdio.h>
11 #include <unistd.h>
12 #include <errno.h>
13 #include <string.h>
14 
15 #define  DEFAULT_PORT  8012
16 
17 static void
socket_close(int sock)18 socket_close(int  sock)
19 {
20     int  old_errno = errno;
21     close(sock);
22     errno = old_errno;
23 }
24 
25 static int
socket_loopback_server(int port,int type)26 socket_loopback_server( int port, int type )
27 {
28     struct sockaddr_in  addr;
29 
30     int  sock = socket(AF_INET, type, 0);
31     if (sock < 0) {
32         return -1;
33     }
34 
35     memset(&addr, 0, sizeof(addr));
36     addr.sin_family      = AF_INET;
37     addr.sin_port        = htons(port);
38     addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
39 
40     int n = 1;
41     setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));
42 
43     if (TEMP_FAILURE_RETRY(bind(sock, &addr, sizeof(addr))) < 0) {
44         socket_close(sock);
45         return -1;
46     }
47 
48     if (type == SOCK_STREAM) {
49         if (TEMP_FAILURE_RETRY(listen(sock, 4)) < 0) {
50             socket_close(sock);
51             return -1;
52         }
53     }
54 
55     return sock;
56 }
57 
main(void)58 int main(void)
59 {
60     int sock, client;
61     int port = DEFAULT_PORT;
62 
63     printf("Starting pipe test server on local port %d\n", port);
64     sock = socket_loopback_server( port, SOCK_STREAM );
65     if (sock < 0) {
66         fprintf(stderr, "Could not start server: %s\n", strerror(errno));
67         return 1;
68     }
69 
70     client = accept(sock, NULL, NULL);
71     if (client < 0) {
72         fprintf(stderr, "Server error: %s\n", strerror(errno));
73         return 2;
74     }
75     printf("Client connected!\n");
76 
77     /* Now, accept any incoming data, and send it back */
78     for (;;) {
79         char  buff[1024], *p;
80         int   ret, count;
81 
82         do {
83             ret = read(client, buff, sizeof(buff));
84         } while (ret < 0 && errno == EINTR);
85 
86         if (ret < 0) {
87             fprintf(stderr, "Client read error: %s\n", strerror(errno));
88             close(client);
89             return 3;
90         }
91         count = ret;
92         p     = buff;
93         printf("   received: %d bytes\n", count);
94 
95         while (count > 0) {
96             do {
97                 ret = write(client, p, count);
98             } while (ret < 0 && errno == EINTR);
99 
100             if (ret < 0) {
101                 fprintf(stderr, "Client write error: %s\n", strerror(errno));
102                 close(client);
103                 return 4;
104             }
105             printf("   sent: %d bytes\n", ret);
106 
107             p     += ret;
108             count -= ret;
109         }
110     }
111 
112     return 0;
113 }
114