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/. */
5
6 /***********************************************************************
7 ** 1997 - Netscape Communications Corporation
8 **
9 ** Name: prselect_err.c
10 **
11 ** Description: tests PR_Select with sockets Error condition functions.
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 ***********************************************************************/
22
23 /***********************************************************************
24 ** Includes
25 ***********************************************************************/
26 /* Used to get the command line option */
27 #include "plgetopt.h"
28
29 #include "primpl.h"
30 #include "pprio.h"
31 #include "prnetdb.h"
32
33 #include <stdio.h>
34 #include <string.h>
35 #include <stdlib.h>
36
37
38 PRIntn failed_already=0;
39 PRIntn debug_mode;
40
main(int argc,char ** argv)41 int main(int argc, char **argv)
42 {
43 PRFileDesc *listenSock1, *listenSock2;
44 PRFileDesc *badFD;
45 PRUint16 listenPort1, listenPort2;
46 PRNetAddr addr;
47 PR_fd_set readFdSet;
48 char buf[128];
49 PRInt32 retVal;
50
51 /* The command line argument: -d is used to determine if the test is being run
52 in debug mode. The regress tool requires only one line output:PASS or FAIL.
53 All of the printfs associated with this test has been handled with a if (debug_mode)
54 test.
55 Usage: test_name -d
56 */
57 PLOptStatus os;
58 PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
59 while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
60 {
61 if (PL_OPT_BAD == os) {
62 continue;
63 }
64 switch (opt->option)
65 {
66 case 'd': /* debug mode */
67 debug_mode = 1;
68 break;
69 default:
70 break;
71 }
72 }
73 PL_DestroyOptState(opt);
74
75 /* main test */
76
77 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
78 PR_STDIO_INIT();
79
80 if (debug_mode) {
81 printf("This program tests PR_Select with sockets. Error\n");
82 printf("reporting operations are tested.\n\n");
83 }
84
85 /* Create two listening sockets */
86 if ((listenSock1 = PR_NewTCPSocket()) == NULL) {
87 fprintf(stderr, "Can't create a new TCP socket\n");
88 failed_already=1;
89 goto exit_now;
90 }
91 addr.inet.family = AF_INET;
92 addr.inet.ip = PR_htonl(INADDR_ANY);
93 addr.inet.port = PR_htons(0);
94 if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
95 fprintf(stderr, "Can't bind socket\n");
96 failed_already=1;
97 goto exit_now;
98 }
99 if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) {
100 fprintf(stderr, "PR_GetSockName failed\n");
101 failed_already=1;
102 goto exit_now;
103 }
104 listenPort1 = PR_ntohs(addr.inet.port);
105 if (PR_Listen(listenSock1, 5) == PR_FAILURE) {
106 fprintf(stderr, "Can't listen on a socket\n");
107 failed_already=1;
108 goto exit_now;
109 }
110
111 if ((listenSock2 = PR_NewTCPSocket()) == NULL) {
112 fprintf(stderr, "Can't create a new TCP socket\n");
113 failed_already=1;
114 goto exit_now;
115 }
116 addr.inet.family = AF_INET;
117 addr.inet.ip = PR_htonl(INADDR_ANY);
118 addr.inet.port = PR_htons(0);
119 if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
120 fprintf(stderr, "Can't bind socket\n");
121 failed_already=1;
122 goto exit_now;
123 }
124 if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) {
125 fprintf(stderr, "PR_GetSockName failed\n");
126 failed_already=1;
127 goto exit_now;
128 }
129 listenPort2 = PR_ntohs(addr.inet.port);
130 if (PR_Listen(listenSock2, 5) == PR_FAILURE) {
131 fprintf(stderr, "Can't listen on a socket\n");
132 failed_already=1;
133 goto exit_now;
134 }
135 PR_snprintf(buf, sizeof(buf),
136 "The server thread is listening on ports %hu and %hu\n\n",
137 listenPort1, listenPort2);
138 if (debug_mode) {
139 printf("%s", buf);
140 }
141
142 /* Set up the fd set */
143 PR_FD_ZERO(&readFdSet);
144 PR_FD_SET(listenSock1, &readFdSet);
145 PR_FD_SET(listenSock2, &readFdSet);
146
147
148 /* Testing bad fd */
149 if (debug_mode) {
150 printf("PR_Select should detect a bad file descriptor\n");
151 }
152 if ((badFD = PR_NewTCPSocket()) == NULL) {
153 fprintf(stderr, "Can't create a TCP socket\n");
154 failed_already=1;
155 goto exit_now;
156 }
157
158 PR_FD_SET(badFD, &readFdSet);
159 /*
160 * Make the fd invalid
161 */
162 #if defined(XP_UNIX)
163 close(PR_FileDesc2NativeHandle(badFD));
164 #elif defined(XP_OS2)
165 soclose(PR_FileDesc2NativeHandle(badFD));
166 #elif defined(WIN32) || defined(WIN16)
167 closesocket(PR_FileDesc2NativeHandle(badFD));
168 #else
169 #error "Unknown architecture"
170 #endif
171
172 retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL,
173 PR_INTERVAL_NO_TIMEOUT);
174 if (retVal != -1 || PR_GetError() != PR_BAD_DESCRIPTOR_ERROR) {
175 fprintf(stderr, "Failed to detect the bad fd: "
176 "PR_Select returns %d\n", retVal);
177 if (retVal == -1) {
178 fprintf(stderr, "Error %d, oserror %d\n", PR_GetError(),
179 PR_GetOSError());
180 failed_already=1;
181 }
182 goto exit_now;
183 }
184 if (debug_mode) {
185 printf("PR_Select detected a bad fd. Test passed.\n\n");
186 }
187 PR_FD_CLR(badFD, &readFdSet);
188
189 PR_Cleanup();
190 goto exit_now;
191 exit_now:
192 if(failed_already) {
193 return 1;
194 }
195 else {
196 return 0;
197 }
198
199 }
200
201