nsprpub/pr/tests/peek.c

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 /*
     7  * A test case for the PR_MSG_PEEK flag of PR_Recv().
     8  *
     9  * Test both blocking and non-blocking sockets.
    10  */
    12 #include "nspr.h"
    14 #include <stdio.h>
    15 #include <stdlib.h>
    16 #include <string.h>
    18 #define BUFFER_SIZE 1024
    20 static int iterations = 10;
    22 /*
    23  * In iteration i, recv_amount[i] is the number of bytes we
    24  * wish to receive, and send_amount[i] is the number of bytes
    25  * we actually send.  Therefore, the number of elements in the
    26  * recv_amount or send_amount array should equal to 'iterations'.
    27  * For this test to pass we need to ensure that
    28  *     recv_amount[i] <= BUFFER_SIZE,
    29  *     send_amount[i] <= BUFFER_SIZE,
    30  *     send_amount[i] <= recv_amount[i].
    31  */
    32 static PRInt32 recv_amount[10] = {
    33     16, 128, 256, 1024, 512, 512, 128, 256, 32, 32};
    34 static PRInt32 send_amount[10] = {
    35     16,  64, 128, 1024, 512, 256, 128,  64, 16, 32};
    37 /* Blocking I/O */
    38 static void ServerB(void *arg)
    39 {
    40     PRFileDesc *listenSock = (PRFileDesc *) arg;
    41     PRFileDesc *sock;
    42     char buf[BUFFER_SIZE];
    43     PRInt32 nbytes;
    44     int i;
    45     int j;
    47     sock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT);
    48     if (NULL == sock) {
    49         fprintf(stderr, "PR_Accept failed\n");
    50         exit(1);
    51     }
    53     for (i = 0; i < iterations; i++) {
    54         memset(buf, 0, sizeof(buf));
    55         nbytes = PR_Recv(sock, buf, recv_amount[i],
    56                 PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT);
    57         if (-1 == nbytes) {
    58             fprintf(stderr, "PR_Recv failed\n");
    59             exit(1);
    60         }
    61         if (send_amount[i] != nbytes) {
    62             fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes);
    63             exit(1);
    64         }
    65         for (j = 0; j < nbytes; j++) {
    66             if (buf[j] != 2*i) {
    67                 fprintf(stderr, "byte %d should be %d but is %d\n",
    68                         j, 2*i, buf[j]);
    69                 exit(1);
    70             }
    71         }
    72         fprintf(stderr, "server: peeked expected data\n");
    74         memset(buf, 0, sizeof(buf));
    75         nbytes = PR_Recv(sock, buf, recv_amount[i],
    76                 PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT);
    77         if (-1 == nbytes) {
    78             fprintf(stderr, "PR_Recv failed\n");
    79             exit(1);
    80         }
    81         if (send_amount[i] != nbytes) {
    82             fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes);
    83             exit(1);
    84         }
    85         for (j = 0; j < nbytes; j++) {
    86             if (buf[j] != 2*i) {
    87                 fprintf(stderr, "byte %d should be %d but is %d\n",
    88                         j, 2*i, buf[j]);
    89                 exit(1);
    90             }
    91         }
    92         fprintf(stderr, "server: peeked expected data\n");
    94         memset(buf, 0, sizeof(buf));
    95         nbytes = PR_Recv(sock, buf, recv_amount[i],
    96                 0, PR_INTERVAL_NO_TIMEOUT);
    97         if (-1 == nbytes) {
    98             fprintf(stderr, "PR_Recv failed\n");
    99             exit(1);
   100         }
   101         if (send_amount[i] != nbytes) {
   102             fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes);
   103             exit(1);
   104         }
   105         for (j = 0; j < nbytes; j++) {
   106             if (buf[j] != 2*i) {
   107                 fprintf(stderr, "byte %d should be %d but is %d\n",
   108                         j, 2*i, buf[j]);
   109                 exit(1);
   110             }
   111         }
   112         fprintf(stderr, "server: received expected data\n");
   114         PR_Sleep(PR_SecondsToInterval(1));
   115         memset(buf, 2*i+1, send_amount[i]);
   116         nbytes = PR_Send(sock, buf, send_amount[i],
   117                 0, PR_INTERVAL_NO_TIMEOUT);
   118         if (-1 == nbytes) {
   119             fprintf(stderr, "PR_Send failed\n");
   120             exit(1);
   121         }
   122         if (send_amount[i] != nbytes) {
   123             fprintf(stderr, "PR_Send returned %d, absurd!\n", nbytes);
   124             exit(1);
   125         }
   126     }
   127     if (PR_Close(sock) == PR_FAILURE) {
   128         fprintf(stderr, "PR_Close failed\n");
   129         exit(1);
   130     }
   131 }
   133 /* Non-blocking I/O */
   134 static void ClientNB(void *arg)
   135 {
   136     PRFileDesc *sock;
   137     PRSocketOptionData opt;
   138     PRUint16 port = (PRUint16) arg;
   139     PRNetAddr addr;
   140     char buf[BUFFER_SIZE];
   141     PRPollDesc pd;
   142     PRInt32 npds;
   143     PRInt32 nbytes;
   144     int i;
   145     int j;
   147     sock = PR_OpenTCPSocket(PR_AF_INET6);
   148     if (NULL == sock) {
   149         fprintf(stderr, "PR_OpenTCPSocket failed\n");
   150         exit(1);
   151     }
   152     opt.option = PR_SockOpt_Nonblocking;
   153     opt.value.non_blocking = PR_TRUE;
   154     if (PR_SetSocketOption(sock, &opt) == PR_FAILURE) {
   155         fprintf(stderr, "PR_SetSocketOption failed\n");
   156         exit(1);
   157     }
   158     memset(&addr, 0, sizeof(addr));
   159     if (PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET6, port, &addr)
   160             == PR_FAILURE) {
   161         fprintf(stderr, "PR_SetNetAddr failed\n");
   162         exit(1);
   163     }
   164     if (PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) {
   165         if (PR_GetError() != PR_IN_PROGRESS_ERROR) {
   166             fprintf(stderr, "PR_Connect failed\n");
   167             exit(1);
   168         }
   169         pd.fd = sock;
   170         pd.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
   171         npds = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
   172         if (-1 == npds) {
   173             fprintf(stderr, "PR_Poll failed\n");
   174             exit(1);
   175         }
   176         if (1 != npds) {
   177             fprintf(stderr, "PR_Poll returned %d, absurd!\n", npds);
   178             exit(1);
   179         }
   180         if (PR_GetConnectStatus(&pd) == PR_FAILURE) {
   181             fprintf(stderr, "PR_GetConnectStatus failed\n");
   182             exit(1);
   183         }
   184     }
   186     for (i = 0; i < iterations; i++) {
   187         PR_Sleep(PR_SecondsToInterval(1));
   188         memset(buf, 2*i, send_amount[i]);
   189         while ((nbytes = PR_Send(sock, buf, send_amount[i],
   190                 0, PR_INTERVAL_NO_TIMEOUT)) == -1) {
   191             if (PR_GetError() != PR_WOULD_BLOCK_ERROR) {
   192                 fprintf(stderr, "PR_Send failed\n");
   193                 exit(1);
   194             }
   195             pd.fd = sock;
   196             pd.in_flags = PR_POLL_WRITE;
   197             npds = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
   198             if (-1 == npds) {
   199                 fprintf(stderr, "PR_Poll failed\n");
   200                 exit(1);
   201             }
   202             if (1 != npds) {
   203                 fprintf(stderr, "PR_Poll returned %d, absurd!\n", npds);
   204                 exit(1);
   205             }
   206         }
   207         if (send_amount[i] != nbytes) {
   208             fprintf(stderr, "PR_Send returned %d, absurd!\n", nbytes);
   209             exit(1);
   210         }
   212         memset(buf, 0, sizeof(buf));
   213         while ((nbytes = PR_Recv(sock, buf, recv_amount[i],
   214                 PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT)) == -1) {
   215             if (PR_GetError() != PR_WOULD_BLOCK_ERROR) {
   216                 fprintf(stderr, "PR_Recv failed\n");
   217                 exit(1);
   218             }
   219             pd.fd = sock;
   220             pd.in_flags = PR_POLL_READ;
   221             npds = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
   222             if (-1 == npds) {
   223                 fprintf(stderr, "PR_Poll failed\n");
   224                 exit(1);
   225             }
   226             if (1 != npds) {
   227                 fprintf(stderr, "PR_Poll returned %d, absurd!\n", npds);
   228                 exit(1);
   229             }
   230         }
   231         if (send_amount[i] != nbytes) {
   232             fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes);
   233             exit(1);
   234         }
   235         for (j = 0; j < nbytes; j++) {
   236             if (buf[j] != 2*i+1) {
   237                 fprintf(stderr, "byte %d should be %d but is %d\n",
   238                         j, 2*i+1, buf[j]);
   239                 exit(1);
   240             }
   241         }
   242         fprintf(stderr, "client: peeked expected data\n");
   244         memset(buf, 0, sizeof(buf));
   245         nbytes = PR_Recv(sock, buf, recv_amount[i],
   246                 PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT);
   247         if (-1 == nbytes) {
   248             fprintf(stderr, "PR_Recv failed\n");
   249             exit(1);
   250         }
   251         if (send_amount[i] != nbytes) {
   252             fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes);
   253             exit(1);
   254         }
   255         for (j = 0; j < nbytes; j++) {
   256             if (buf[j] != 2*i+1) {
   257                 fprintf(stderr, "byte %d should be %d but is %d\n",
   258                         j, 2*i+1, buf[j]);
   259                 exit(1);
   260             }
   261         }
   262         fprintf(stderr, "client: peeked expected data\n");
   264         memset(buf, 0, sizeof(buf));
   265         nbytes = PR_Recv(sock, buf, recv_amount[i],
   266                 0, PR_INTERVAL_NO_TIMEOUT);
   267         if (-1 == nbytes) {
   268             fprintf(stderr, "PR_Recv failed\n");
   269             exit(1);
   270         }
   271         if (send_amount[i] != nbytes) {
   272             fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes);
   273             exit(1);
   274         }
   275         for (j = 0; j < nbytes; j++) {
   276             if (buf[j] != 2*i+1) {
   277                 fprintf(stderr, "byte %d should be %d but is %d\n",
   278                         j, 2*i+1, buf[j]);
   279                 exit(1);
   280             }
   281         }
   282         fprintf(stderr, "client: received expected data\n");
   283     }
   284     if (PR_Close(sock) == PR_FAILURE) {
   285         fprintf(stderr, "PR_Close failed\n");
   286         exit(1);
   287     }
   288 }
   290 static void
   291 RunTest(PRThreadScope scope, PRFileDesc *listenSock, PRUint16 port)
   292 {
   293     PRThread *server, *client;
   295     server = PR_CreateThread(PR_USER_THREAD, ServerB, listenSock,
   296             PR_PRIORITY_NORMAL, scope, PR_JOINABLE_THREAD, 0);
   297     if (NULL == server) {
   298         fprintf(stderr, "PR_CreateThread failed\n");
   299         exit(1);
   300     }
   301     client = PR_CreateThread(
   302             PR_USER_THREAD, ClientNB, (void *) port,
   303             PR_PRIORITY_NORMAL, scope, PR_JOINABLE_THREAD, 0);
   304     if (NULL == client) {
   305         fprintf(stderr, "PR_CreateThread failed\n");
   306         exit(1);
   307     }
   309     if (PR_JoinThread(server) == PR_FAILURE) {
   310         fprintf(stderr, "PR_JoinThread failed\n");
   311         exit(1);
   312     }
   313     if (PR_JoinThread(client) == PR_FAILURE) {
   314         fprintf(stderr, "PR_JoinThread failed\n");
   315         exit(1);
   316     }
   317 }
   319 int main(int argc, char **argv)
   320 {
   321     PRFileDesc *listenSock;
   322     PRNetAddr addr;
   323     PRUint16 port;
   325     listenSock = PR_OpenTCPSocket(PR_AF_INET6);
   326     if (NULL == listenSock) {
   327         fprintf(stderr, "PR_OpenTCPSocket failed\n");
   328         exit(1);
   329     }
   330     memset(&addr, 0, sizeof(addr));
   331     if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, &addr) == PR_FAILURE) {
   332         fprintf(stderr, "PR_SetNetAddr failed\n");
   333         exit(1);
   334     }
   335     if (PR_Bind(listenSock, &addr) == PR_FAILURE) {
   336         fprintf(stderr, "PR_Bind failed\n");
   337         exit(1);
   338     }
   339     if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) {
   340         fprintf(stderr, "PR_GetSockName failed\n");
   341         exit(1);
   342     }
   343     port = PR_ntohs(addr.ipv6.port);
   344     if (PR_Listen(listenSock, 5) == PR_FAILURE) {
   345         fprintf(stderr, "PR_Listen failed\n");
   346         exit(1);
   347     }
   349     fprintf(stderr, "Running the test with local threads\n");
   350     RunTest(PR_LOCAL_THREAD, listenSock, port);
   351     fprintf(stderr, "Running the test with global threads\n");
   352     RunTest(PR_GLOBAL_THREAD, listenSock, port);
   354     if (PR_Close(listenSock) == PR_FAILURE) {
   355         fprintf(stderr, "PR_Close failed\n");
   356         exit(1);
   357     }
   358     printf("PASS\n");
   359     return 0;
   360 }

mercurial