Home | History | Annotate | Download | only in tests
      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
     18 socket_close(int  sock)
     19 {
     20     int  old_errno = errno;
     21     close(sock);
     22     errno = old_errno;
     23 }
     24 
     25 static int
     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 
     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