Mercurial > trustbridge > nss-cmake-static
comparison nspr/pr/src/md/windows/w95sock.c @ 0:1e5118fa0cb1
This is NSS with a Cmake Buildsyste
To compile a static NSS library for Windows we've used the
Chromium-NSS fork and added a Cmake buildsystem to compile
it statically for Windows. See README.chromium for chromium
changes and README.trustbridge for our modifications.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Mon, 28 Jul 2014 10:47:06 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1e5118fa0cb1 |
---|---|
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 /* Win95 Sockets module | |
7 * | |
8 */ | |
9 | |
10 #include "primpl.h" | |
11 | |
12 #define READ_FD 1 | |
13 #define WRITE_FD 2 | |
14 #define CONNECT_FD 3 | |
15 | |
16 static PRInt32 socket_io_wait( | |
17 PROsfd osfd, | |
18 PRInt32 fd_type, | |
19 PRIntervalTime timeout); | |
20 | |
21 | |
22 /* --- SOCKET IO --------------------------------------------------------- */ | |
23 | |
24 static PRBool socketFixInet6RcvBuf = PR_FALSE; | |
25 | |
26 void _PR_MD_InitSockets(void) | |
27 { | |
28 OSVERSIONINFO osvi; | |
29 | |
30 memset(&osvi, 0, sizeof(osvi)); | |
31 osvi.dwOSVersionInfoSize = sizeof(osvi); | |
32 GetVersionEx(&osvi); | |
33 | |
34 if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) | |
35 { | |
36 /* if Windows XP (32-bit) */ | |
37 socketFixInet6RcvBuf = PR_TRUE; | |
38 } | |
39 } | |
40 | |
41 void _PR_MD_CleanupSockets(void) | |
42 { | |
43 socketFixInet6RcvBuf = PR_FALSE; | |
44 } | |
45 | |
46 PROsfd | |
47 _PR_MD_SOCKET(int af, int type, int flags) | |
48 { | |
49 SOCKET sock; | |
50 u_long one = 1; | |
51 | |
52 sock = socket(af, type, flags); | |
53 | |
54 if (sock == INVALID_SOCKET ) | |
55 { | |
56 _PR_MD_MAP_SOCKET_ERROR(WSAGetLastError()); | |
57 return (PROsfd)sock; | |
58 } | |
59 | |
60 /* | |
61 ** Make the socket Non-Blocking | |
62 */ | |
63 if (ioctlsocket( sock, FIONBIO, &one) != 0) | |
64 { | |
65 PR_SetError(PR_UNKNOWN_ERROR, WSAGetLastError()); | |
66 closesocket(sock); | |
67 return -1; | |
68 } | |
69 | |
70 if (af == AF_INET6 && socketFixInet6RcvBuf) | |
71 { | |
72 int bufsize; | |
73 int len = sizeof(bufsize); | |
74 int rv; | |
75 | |
76 /* Windows XP 32-bit returns an error on getpeername() for AF_INET6 | |
77 * sockets if the receive buffer size is greater than 65535 before | |
78 * the connection is initiated. The default receive buffer size may | |
79 * be 128000 so fix it here to always be <= 65535. See bug 513659 | |
80 * and IBM DB2 support technote "Receive/Send IPv6 Socket Size | |
81 * Problem in Windows XP SP2 & SP3". | |
82 */ | |
83 rv = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char*)&bufsize, &len); | |
84 if (rv == 0 && bufsize > 65535) | |
85 { | |
86 bufsize = 65535; | |
87 setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char*)&bufsize, len); | |
88 } | |
89 } | |
90 | |
91 return (PROsfd)sock; | |
92 } | |
93 | |
94 /* | |
95 ** _MD_CloseSocket() -- Close a socket | |
96 ** | |
97 */ | |
98 PRInt32 | |
99 _MD_CloseSocket(PROsfd osfd) | |
100 { | |
101 PRInt32 rv; | |
102 | |
103 rv = closesocket((SOCKET) osfd ); | |
104 if (rv < 0) | |
105 _PR_MD_MAP_CLOSE_ERROR(WSAGetLastError()); | |
106 | |
107 return rv; | |
108 } | |
109 | |
110 PRInt32 | |
111 _MD_SocketAvailable(PRFileDesc *fd) | |
112 { | |
113 PRInt32 result; | |
114 | |
115 if (ioctlsocket(fd->secret->md.osfd, FIONREAD, &result) < 0) { | |
116 PR_SetError(PR_BAD_DESCRIPTOR_ERROR, WSAGetLastError()); | |
117 return -1; | |
118 } | |
119 return result; | |
120 } | |
121 | |
122 PROsfd _MD_Accept( | |
123 PRFileDesc *fd, | |
124 PRNetAddr *raddr, | |
125 PRUint32 *rlen, | |
126 PRIntervalTime timeout ) | |
127 { | |
128 PROsfd osfd = fd->secret->md.osfd; | |
129 SOCKET sock; | |
130 PRInt32 rv, err; | |
131 | |
132 while ((sock = accept(osfd, (struct sockaddr *) raddr, rlen)) == -1) | |
133 { | |
134 err = WSAGetLastError(); | |
135 if ((err == WSAEWOULDBLOCK) && (!fd->secret->nonblocking)) | |
136 { | |
137 if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0) | |
138 { | |
139 break; | |
140 } | |
141 } | |
142 else | |
143 { | |
144 _PR_MD_MAP_ACCEPT_ERROR(err); | |
145 break; | |
146 } | |
147 } | |
148 return(sock); | |
149 } /* end _MD_accept() */ | |
150 | |
151 PRInt32 | |
152 _PR_MD_CONNECT(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, | |
153 PRIntervalTime timeout) | |
154 { | |
155 PROsfd osfd = fd->secret->md.osfd; | |
156 PRInt32 rv; | |
157 int err; | |
158 | |
159 if ((rv = connect(osfd, (struct sockaddr *) addr, addrlen)) == -1) | |
160 { | |
161 err = WSAGetLastError(); | |
162 if ((!fd->secret->nonblocking) && (err == WSAEWOULDBLOCK)) | |
163 { | |
164 rv = socket_io_wait(osfd, CONNECT_FD, timeout); | |
165 if ( rv < 0 ) | |
166 { | |
167 return(-1); | |
168 } | |
169 else | |
170 { | |
171 PR_ASSERT(rv > 0); | |
172 /* it's connected */ | |
173 return(0); | |
174 } | |
175 } | |
176 _PR_MD_MAP_CONNECT_ERROR(err); | |
177 } | |
178 return rv; | |
179 } | |
180 | |
181 PRInt32 | |
182 _PR_MD_BIND(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen) | |
183 { | |
184 PRInt32 rv; | |
185 | |
186 rv = bind(fd->secret->md.osfd, (const struct sockaddr *)&(addr->inet), addrlen); | |
187 | |
188 if (rv == SOCKET_ERROR) { | |
189 _PR_MD_MAP_BIND_ERROR(WSAGetLastError()); | |
190 return -1; | |
191 } | |
192 | |
193 return 0; | |
194 } | |
195 | |
196 PRInt32 | |
197 _PR_MD_LISTEN(PRFileDesc *fd, PRIntn backlog) | |
198 { | |
199 PRInt32 rv; | |
200 | |
201 rv = listen(fd->secret->md.osfd, backlog); | |
202 | |
203 if (rv == SOCKET_ERROR) { | |
204 _PR_MD_MAP_DEFAULT_ERROR(WSAGetLastError()); | |
205 return -1; | |
206 } | |
207 | |
208 return 0; | |
209 } | |
210 | |
211 PRInt32 | |
212 _PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, | |
213 PRIntervalTime timeout) | |
214 { | |
215 PROsfd osfd = fd->secret->md.osfd; | |
216 PRInt32 rv, err; | |
217 int osflags; | |
218 | |
219 if (0 == flags) { | |
220 osflags = 0; | |
221 } else { | |
222 PR_ASSERT(PR_MSG_PEEK == flags); | |
223 osflags = MSG_PEEK; | |
224 } | |
225 while ((rv = recv( osfd, buf, amount, osflags)) == -1) | |
226 { | |
227 if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) | |
228 && (!fd->secret->nonblocking)) | |
229 { | |
230 rv = socket_io_wait(osfd, READ_FD, timeout); | |
231 if ( rv < 0 ) | |
232 { | |
233 return -1; | |
234 } | |
235 } | |
236 else | |
237 { | |
238 _PR_MD_MAP_RECV_ERROR(err); | |
239 break; | |
240 } | |
241 } /* end while() */ | |
242 return(rv); | |
243 } | |
244 | |
245 PRInt32 | |
246 _PR_MD_SEND(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, | |
247 PRIntervalTime timeout) | |
248 { | |
249 PROsfd osfd = fd->secret->md.osfd; | |
250 PRInt32 rv, err; | |
251 PRInt32 bytesSent = 0; | |
252 | |
253 while(bytesSent < amount ) | |
254 { | |
255 while ((rv = send( osfd, buf, amount, 0 )) == -1) | |
256 { | |
257 if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) | |
258 && (!fd->secret->nonblocking)) | |
259 { | |
260 rv = socket_io_wait(osfd, WRITE_FD, timeout); | |
261 if ( rv < 0 ) | |
262 { | |
263 return -1; | |
264 } | |
265 } | |
266 else | |
267 { | |
268 _PR_MD_MAP_SEND_ERROR(err); | |
269 return -1; | |
270 } | |
271 } | |
272 bytesSent += rv; | |
273 if (fd->secret->nonblocking) | |
274 { | |
275 break; | |
276 } | |
277 if (bytesSent < amount) | |
278 { | |
279 rv = socket_io_wait(osfd, WRITE_FD, timeout); | |
280 if ( rv < 0 ) | |
281 { | |
282 return -1; | |
283 } | |
284 } | |
285 } | |
286 return bytesSent; | |
287 } | |
288 | |
289 PRInt32 | |
290 _PR_MD_SENDTO(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, | |
291 const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout) | |
292 { | |
293 PROsfd osfd = fd->secret->md.osfd; | |
294 PRInt32 rv, err; | |
295 PRInt32 bytesSent = 0; | |
296 | |
297 while(bytesSent < amount) | |
298 { | |
299 while ((rv = sendto( osfd, buf, amount, 0, (struct sockaddr *) addr, | |
300 addrlen)) == -1) | |
301 { | |
302 if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) | |
303 && (!fd->secret->nonblocking)) | |
304 { | |
305 rv = socket_io_wait(osfd, WRITE_FD, timeout); | |
306 if ( rv < 0 ) | |
307 { | |
308 return -1; | |
309 } | |
310 } | |
311 else | |
312 { | |
313 _PR_MD_MAP_SENDTO_ERROR(err); | |
314 return -1; | |
315 } | |
316 } | |
317 bytesSent += rv; | |
318 if (fd->secret->nonblocking) | |
319 { | |
320 break; | |
321 } | |
322 if (bytesSent < amount) | |
323 { | |
324 rv = socket_io_wait(osfd, WRITE_FD, timeout); | |
325 if (rv < 0) | |
326 { | |
327 return -1; | |
328 } | |
329 } | |
330 } | |
331 return bytesSent; | |
332 } | |
333 | |
334 PRInt32 | |
335 _PR_MD_RECVFROM(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, | |
336 PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout) | |
337 { | |
338 PROsfd osfd = fd->secret->md.osfd; | |
339 PRInt32 rv, err; | |
340 | |
341 while ((rv = recvfrom( osfd, buf, amount, 0, (struct sockaddr *) addr, | |
342 addrlen)) == -1) | |
343 { | |
344 if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) | |
345 && (!fd->secret->nonblocking)) | |
346 { | |
347 rv = socket_io_wait(osfd, READ_FD, timeout); | |
348 if ( rv < 0) | |
349 { | |
350 return -1; | |
351 } | |
352 } | |
353 else | |
354 { | |
355 _PR_MD_MAP_RECVFROM_ERROR(err); | |
356 break; | |
357 } | |
358 } | |
359 return(rv); | |
360 } | |
361 | |
362 PRInt32 | |
363 _PR_MD_WRITEV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, PRIntervalTime timeout) | |
364 { | |
365 int index; | |
366 int sent = 0; | |
367 int rv; | |
368 | |
369 for (index=0; index < iov_size; index++) | |
370 { | |
371 rv = _PR_MD_SEND(fd, iov[index].iov_base, iov[index].iov_len, 0, timeout); | |
372 if (rv > 0) | |
373 sent += rv; | |
374 if ( rv != iov[index].iov_len ) | |
375 { | |
376 if (rv < 0) | |
377 { | |
378 if (fd->secret->nonblocking | |
379 && (PR_GetError() == PR_WOULD_BLOCK_ERROR) | |
380 && (sent > 0)) | |
381 { | |
382 return sent; | |
383 } | |
384 else | |
385 { | |
386 return -1; | |
387 } | |
388 } | |
389 /* Only a nonblocking socket can have partial sends */ | |
390 PR_ASSERT(fd->secret->nonblocking); | |
391 return sent; | |
392 } | |
393 } | |
394 return sent; | |
395 } | |
396 | |
397 PRInt32 | |
398 _PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how) | |
399 { | |
400 PRInt32 rv; | |
401 | |
402 rv = shutdown(fd->secret->md.osfd, how); | |
403 if (rv < 0) | |
404 _PR_MD_MAP_SHUTDOWN_ERROR(WSAGetLastError()); | |
405 return rv; | |
406 } | |
407 | |
408 PRStatus | |
409 _PR_MD_GETSOCKNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *len) | |
410 { | |
411 PRInt32 rv; | |
412 | |
413 rv = getsockname((SOCKET)fd->secret->md.osfd, (struct sockaddr *)addr, len); | |
414 if (rv==0) { | |
415 return PR_SUCCESS; | |
416 } else { | |
417 _PR_MD_MAP_GETSOCKNAME_ERROR(WSAGetLastError()); | |
418 return PR_FAILURE; | |
419 } | |
420 } | |
421 | |
422 PRStatus | |
423 _PR_MD_GETPEERNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *len) | |
424 { | |
425 PRInt32 rv; | |
426 | |
427 rv = getpeername((SOCKET)fd->secret->md.osfd, (struct sockaddr *)addr, len); | |
428 if (rv==0) { | |
429 return PR_SUCCESS; | |
430 } else { | |
431 _PR_MD_MAP_GETPEERNAME_ERROR(WSAGetLastError()); | |
432 return PR_FAILURE; | |
433 } | |
434 } | |
435 | |
436 PRStatus | |
437 _PR_MD_GETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen) | |
438 { | |
439 PRInt32 rv; | |
440 | |
441 rv = getsockopt((SOCKET)fd->secret->md.osfd, level, optname, optval, optlen); | |
442 if (rv==0) { | |
443 return PR_SUCCESS; | |
444 } else { | |
445 _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError()); | |
446 return PR_FAILURE; | |
447 } | |
448 } | |
449 | |
450 PRStatus | |
451 _PR_MD_SETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, const char* optval, PRInt32 optlen) | |
452 { | |
453 PRInt32 rv; | |
454 | |
455 rv = setsockopt((SOCKET)fd->secret->md.osfd, level, optname, optval, optlen); | |
456 if (rv==0) { | |
457 return PR_SUCCESS; | |
458 } else { | |
459 _PR_MD_MAP_SETSOCKOPT_ERROR(WSAGetLastError()); | |
460 return PR_FAILURE; | |
461 } | |
462 } | |
463 | |
464 void | |
465 _MD_MakeNonblock(PRFileDesc *f) | |
466 { | |
467 return; /* do nothing */ | |
468 } | |
469 | |
470 | |
471 | |
472 /* | |
473 * socket_io_wait -- | |
474 * | |
475 * Wait for socket i/o, periodically checking for interrupt. | |
476 * | |
477 * This function returns 1 on success. On failure, it returns | |
478 * -1 and sets the error codes. It never returns 0. | |
479 */ | |
480 #define _PR_INTERRUPT_CHECK_INTERVAL_SECS 5 | |
481 | |
482 static PRInt32 socket_io_wait( | |
483 PROsfd osfd, | |
484 PRInt32 fd_type, | |
485 PRIntervalTime timeout) | |
486 { | |
487 PRInt32 rv = -1; | |
488 struct timeval tv; | |
489 PRThread *me = _PR_MD_CURRENT_THREAD(); | |
490 PRIntervalTime elapsed, remaining; | |
491 PRBool wait_for_remaining; | |
492 fd_set rd_wr, ex; | |
493 int err, len; | |
494 | |
495 switch (timeout) { | |
496 case PR_INTERVAL_NO_WAIT: | |
497 PR_SetError(PR_IO_TIMEOUT_ERROR, 0); | |
498 break; | |
499 case PR_INTERVAL_NO_TIMEOUT: | |
500 /* | |
501 * This is a special case of the 'default' case below. | |
502 * Please see the comments there. | |
503 */ | |
504 tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS; | |
505 tv.tv_usec = 0; | |
506 FD_ZERO(&rd_wr); | |
507 FD_ZERO(&ex); | |
508 do { | |
509 FD_SET(osfd, &rd_wr); | |
510 FD_SET(osfd, &ex); | |
511 switch( fd_type ) | |
512 { | |
513 case READ_FD: | |
514 rv = _MD_SELECT(0, &rd_wr, NULL, NULL, &tv); | |
515 break; | |
516 case WRITE_FD: | |
517 rv = _MD_SELECT(0, NULL, &rd_wr, NULL, &tv); | |
518 break; | |
519 case CONNECT_FD: | |
520 rv = _MD_SELECT(0, NULL, &rd_wr, &ex, &tv); | |
521 break; | |
522 default: | |
523 PR_ASSERT(0); | |
524 break; | |
525 } /* end switch() */ | |
526 if (rv == -1 ) | |
527 { | |
528 _PR_MD_MAP_SELECT_ERROR(WSAGetLastError()); | |
529 break; | |
530 } | |
531 if ( rv > 0 && fd_type == CONNECT_FD ) | |
532 { | |
533 /* | |
534 * Call Sleep(0) to work around a Winsock timing bug. | |
535 */ | |
536 Sleep(0); | |
537 if (FD_ISSET((SOCKET)osfd, &ex)) | |
538 { | |
539 len = sizeof(err); | |
540 if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, | |
541 (char *) &err, &len) == SOCKET_ERROR) | |
542 { | |
543 _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError()); | |
544 return -1; | |
545 } | |
546 if (err != 0) | |
547 _PR_MD_MAP_CONNECT_ERROR(err); | |
548 else | |
549 PR_SetError(PR_UNKNOWN_ERROR, 0); | |
550 return -1; | |
551 } | |
552 if (FD_ISSET((SOCKET)osfd, &rd_wr)) | |
553 { | |
554 /* it's connected */ | |
555 return 1; | |
556 } | |
557 PR_ASSERT(0); | |
558 } | |
559 if (_PR_PENDING_INTERRUPT(me)) { | |
560 me->flags &= ~_PR_INTERRUPT; | |
561 PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); | |
562 rv = -1; | |
563 break; | |
564 } | |
565 } while (rv == 0); | |
566 break; | |
567 default: | |
568 remaining = timeout; | |
569 FD_ZERO(&rd_wr); | |
570 FD_ZERO(&ex); | |
571 do { | |
572 /* | |
573 * We block in _MD_SELECT for at most | |
574 * _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds, | |
575 * so that there is an upper limit on the delay | |
576 * before the interrupt bit is checked. | |
577 */ | |
578 wait_for_remaining = PR_TRUE; | |
579 tv.tv_sec = PR_IntervalToSeconds(remaining); | |
580 if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) { | |
581 wait_for_remaining = PR_FALSE; | |
582 tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS; | |
583 tv.tv_usec = 0; | |
584 } else { | |
585 tv.tv_usec = PR_IntervalToMicroseconds( | |
586 remaining - | |
587 PR_SecondsToInterval(tv.tv_sec)); | |
588 } | |
589 FD_SET(osfd, &rd_wr); | |
590 FD_SET(osfd, &ex); | |
591 switch( fd_type ) | |
592 { | |
593 case READ_FD: | |
594 rv = _MD_SELECT(0, &rd_wr, NULL, NULL, &tv); | |
595 break; | |
596 case WRITE_FD: | |
597 rv = _MD_SELECT(0, NULL, &rd_wr, NULL, &tv); | |
598 break; | |
599 case CONNECT_FD: | |
600 rv = _MD_SELECT(0, NULL, &rd_wr, &ex, &tv); | |
601 break; | |
602 default: | |
603 PR_ASSERT(0); | |
604 break; | |
605 } /* end switch() */ | |
606 if (rv == -1) | |
607 { | |
608 _PR_MD_MAP_SELECT_ERROR(WSAGetLastError()); | |
609 break; | |
610 } | |
611 if ( rv > 0 && fd_type == CONNECT_FD ) | |
612 { | |
613 /* | |
614 * Call Sleep(0) to work around a Winsock timing bug. | |
615 */ | |
616 Sleep(0); | |
617 if (FD_ISSET((SOCKET)osfd, &ex)) | |
618 { | |
619 len = sizeof(err); | |
620 if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, | |
621 (char *) &err, &len) == SOCKET_ERROR) | |
622 { | |
623 _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError()); | |
624 return -1; | |
625 } | |
626 if (err != 0) | |
627 _PR_MD_MAP_CONNECT_ERROR(err); | |
628 else | |
629 PR_SetError(PR_UNKNOWN_ERROR, 0); | |
630 return -1; | |
631 } | |
632 if (FD_ISSET((SOCKET)osfd, &rd_wr)) | |
633 { | |
634 /* it's connected */ | |
635 return 1; | |
636 } | |
637 PR_ASSERT(0); | |
638 } | |
639 if (_PR_PENDING_INTERRUPT(me)) { | |
640 me->flags &= ~_PR_INTERRUPT; | |
641 PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); | |
642 rv = -1; | |
643 break; | |
644 } | |
645 /* | |
646 * We loop again if _MD_SELECT timed out and the | |
647 * timeout deadline has not passed yet. | |
648 */ | |
649 if (rv == 0 ) | |
650 { | |
651 if (wait_for_remaining) { | |
652 elapsed = remaining; | |
653 } else { | |
654 elapsed = PR_SecondsToInterval(tv.tv_sec) | |
655 + PR_MicrosecondsToInterval(tv.tv_usec); | |
656 } | |
657 if (elapsed >= remaining) { | |
658 PR_SetError(PR_IO_TIMEOUT_ERROR, 0); | |
659 rv = -1; | |
660 break; | |
661 } else { | |
662 remaining = remaining - elapsed; | |
663 } | |
664 } | |
665 } while (rv == 0 ); | |
666 break; | |
667 } | |
668 return(rv); | |
669 } /* end socket_io_wait() */ |