nsprpub/pr/tests/selct_nm.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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 **  1997 - Netscape Communications Corporation
     8 **
     9 ** Name: prselect_norm.c
    10 **
    11 ** Description: tests PR_Select with sockets - Normal operations.
    12 **
    13 ** Modification History:
    14 ** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
    15 **	         The debug mode will print all of the printfs associated with this test.
    16 **			 The regress mode will be the default mode. Since the regress tool limits
    17 **           the output to a one line status:PASS or FAIL,all of the printf statements
    18 **			 have been handled with an if (debug_mode) statement.
    19 ** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
    20 **			recognize the return code from tha main program.
    21 ***********************************************************************/
    23 /***********************************************************************
    24 ** Includes
    25 ***********************************************************************/
    26 /* Used to get the command line option */
    27 #include "plgetopt.h"
    29 #include "prinit.h"
    30 #include "prio.h"
    31 #include "prlog.h"
    32 #include "prprf.h"
    33 #include "prerror.h"
    34 #include "prnetdb.h"
    36 #include "obsolete/probslet.h"
    38 #include <stdio.h>
    39 #include <string.h>
    40 #include <stdlib.h>
    42 PRIntn failed_already=0;
    43 PRIntn debug_mode;
    45 static void
    46 clientThreadFunc(void *arg)
    47 {
    48     PRUintn port = (PRUintn) arg;
    49     PRFileDesc *sock;
    50     PRNetAddr addr;
    51     char buf[128];
    52     int i;
    54     addr.inet.family = PR_AF_INET;
    55     addr.inet.port = PR_htons((PRUint16)port);
    56     addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
    57     PR_snprintf(buf, sizeof(buf), "%hu", addr.inet.port);
    59     for (i = 0; i < 5; i++) {
    60 	sock = PR_NewTCPSocket();
    61         PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT);
    62 	PR_Write(sock, buf, sizeof(buf));
    63 	PR_Close(sock);
    64     }
    65 }
    67 int main(int argc, char **argv)
    68 {
    69     PRFileDesc *listenSock1, *listenSock2;
    70     PRFileDesc *fds0[10], *fds1[10], **fds, **other_fds;
    71     PRIntn nfds;
    72     PRUint16 listenPort1, listenPort2;
    73     PRNetAddr addr;
    74     PR_fd_set readFdSet;
    75     char buf[128];
    76     PRThread *clientThread;
    77     PRInt32 retVal;
    78     PRIntn i, j;
    80 	/* The command line argument: -d is used to determine if the test is being run
    81 	in debug mode. The regress tool requires only one line output:PASS or FAIL.
    82 	All of the printfs associated with this test has been handled with a if (debug_mode)
    83 	test.
    84 	Usage: test_name -d
    85 	*/
    86 	PLOptStatus os;
    87 	PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
    88 	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
    89     {
    90 		if (PL_OPT_BAD == os) continue;
    91         switch (opt->option)
    92         {
    93         case 'd':  /* debug mode */
    94 			debug_mode = 1;
    95             break;
    96          default:
    97             break;
    98         }
    99     }
   100 	PL_DestroyOptState(opt);
   102  /* main test */
   104     PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
   105     PR_STDIO_INIT();
   107     if (debug_mode) {
   108 		printf("This program tests PR_Select with sockets.  \n");
   109 		printf(" Normal operation are tested.\n\n");
   110 	}
   112     /* Create two listening sockets */
   113     if ((listenSock1 = PR_NewTCPSocket()) == NULL) {
   114 	fprintf(stderr, "Can't create a new TCP socket\n");
   115 	failed_already=1;
   116 	goto exit_now;
   117     }
   118     addr.inet.family = PR_AF_INET;
   119     addr.inet.ip = PR_htonl(PR_INADDR_ANY);
   120     addr.inet.port = PR_htons(0);
   121     if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
   122 	fprintf(stderr, "Can't bind socket\n");
   123 	failed_already=1;
   124 	goto exit_now;
   125     }
   126     if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) {
   127 	fprintf(stderr, "PR_GetSockName failed\n");
   128 	failed_already=1;
   129 	goto exit_now;
   130     }
   131     listenPort1 = PR_ntohs(addr.inet.port);
   132     if (PR_Listen(listenSock1, 5) == PR_FAILURE) {
   133 	fprintf(stderr, "Can't listen on a socket\n");
   134 	failed_already=1;
   135 	goto exit_now;
   136     }
   138     if ((listenSock2  = PR_NewTCPSocket()) == NULL) {
   139 	fprintf(stderr, "Can't create a new TCP socket\n");
   140 	failed_already=1;
   141 	goto exit_now;
   142     }
   143     addr.inet.family = PR_AF_INET;
   144     addr.inet.ip = PR_htonl(PR_INADDR_ANY);
   145     addr.inet.port = PR_htons(0);
   146     if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
   147 	fprintf(stderr, "Can't bind socket\n");
   148 	failed_already=1;
   149 	goto exit_now;
   150     }
   151     if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) {
   152 	fprintf(stderr, "PR_GetSockName failed\n");
   153 	failed_already=1;
   154 	goto exit_now;
   155     }
   156     listenPort2 = PR_ntohs(addr.inet.port);
   157     if (PR_Listen(listenSock2, 5) == PR_FAILURE) {
   158 	fprintf(stderr, "Can't listen on a socket\n");
   159 failed_already=1;
   160 	goto exit_now;
   161     }
   162     PR_snprintf(buf, sizeof(buf),
   163 	    "The server thread is listening on ports %hu and %hu\n\n",
   164 	    listenPort1, listenPort2);
   165     if (debug_mode) printf("%s", buf);
   167     clientThread = PR_CreateThread(PR_USER_THREAD,
   168 	    clientThreadFunc, (void *) listenPort1,
   169 	    PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
   170 	    PR_UNJOINABLE_THREAD, 0);
   171     if (clientThread == NULL) {
   172 	fprintf(stderr, "can't create thread\n");
   173 	failed_already=1;
   174 	goto exit_now;
   175     }
   177     clientThread = PR_CreateThread(PR_USER_THREAD,
   178 	    clientThreadFunc, (void *) listenPort2,
   179 	    PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
   180 	    PR_UNJOINABLE_THREAD, 0);
   181     if (clientThread == NULL) {
   182 	fprintf(stderr, "can't create thread\n");
   183 	failed_already=1;
   184 	goto exit_now;
   185     }
   187     if (debug_mode) {
   188 		printf("Two client threads are created.  Each of them will\n");
   189 		printf("send data to one of the two ports the server is listening on.\n");
   190 		printf("The data they send is the port number.  Each of them send\n");
   191 		printf("the data five times, so you should see ten lines below,\n");
   192 		printf("interleaved in an arbitrary order.\n");
   193 	}
   194     /* set up the fd array */
   195     fds = fds0;
   196     other_fds = fds1;
   197     fds[0] = listenSock1;
   198     fds[1] = listenSock2;
   199     nfds = 2;
   200     /* Set up the fd set */
   201     PR_FD_ZERO(&readFdSet);
   202     PR_FD_SET(listenSock1, &readFdSet);
   203     PR_FD_SET(listenSock2, &readFdSet);
   205     /* 20 events total */
   206     i = 0;
   207     while (i < 20) {
   208 	PRFileDesc **tmp;
   209 	int nextIndex;
   210 	int nEvents = 0;
   212 	retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL,
   213 		PR_INTERVAL_NO_TIMEOUT);
   214 	PR_ASSERT(retVal != 0);  /* no timeout */
   215 	if (retVal == -1) {
   216 	    fprintf(stderr, "PR_Select failed (%d, %d)\n", PR_GetError(),
   217 		    PR_GetOSError());
   218 	failed_already=1;
   219 	    goto exit_now;
   220 	}
   222 	nextIndex = 2;
   223 	/* the two listening sockets */
   224 	for (j = 0; j < 2; j++) {
   225 	    other_fds[j] = fds[j];
   226 	    if (PR_FD_ISSET(fds[j], &readFdSet)) {
   227 		PRFileDesc *sock;
   229 		nEvents++;
   230 		sock = PR_Accept(fds[j], NULL, PR_INTERVAL_NO_TIMEOUT);
   231 		if (sock == NULL) {
   232 		    fprintf(stderr, "PR_Accept() failed\n");
   233 		failed_already=1;
   234 		    goto exit_now;
   235 		}
   236 		other_fds[nextIndex] = sock;
   237 		PR_FD_SET(sock, &readFdSet);
   238 		nextIndex++;
   239 	    }
   240 	    PR_FD_SET(fds[j], &readFdSet);
   241 	}
   243 	for (j = 2; j < nfds; j++) {
   244 	    if (PR_FD_ISSET(fds[j], &readFdSet)) {
   245 		PRInt32 nBytes;
   247 		PR_FD_CLR(fds[j], &readFdSet);
   248 		nEvents++;
   249 		nBytes = PR_Read(fds[j], buf, sizeof(buf));
   250 		if (nBytes == -1) {
   251 		    fprintf(stderr, "PR_Read() failed\n");
   252 		failed_already=1;
   253 		    goto exit_now;
   254 		}
   255 		/* Just to be safe */
   256 		buf[127] = '\0';
   257 		PR_Close(fds[j]);
   258 		if (debug_mode) printf("The server received \"%s\" from a client\n", buf);
   259 	    } else {
   260 		PR_FD_SET(fds[j], &readFdSet);
   261 		other_fds[nextIndex] = fds[j];
   262 		nextIndex++;
   263 	    }
   264 	}
   266 	PR_ASSERT(retVal == nEvents);
   267 	/* swap */
   268 	tmp = fds;
   269 	fds = other_fds;
   270 	other_fds = tmp;
   271 	nfds = nextIndex;
   272 	i += nEvents;
   273     }
   275     if (debug_mode) printf("Test passed\n");
   277     PR_Cleanup();
   278 	goto exit_now;
   279 exit_now:
   280 	if(failed_already)	
   281 		return 1;
   282 	else
   283 		return 0;
   284 }

mercurial