1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/nsprpub/pr/src/md/os2/os2sock.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,654 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 + 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +/* OS/2 Sockets module 1.11 + * 1.12 + */ 1.13 + 1.14 +/*Note from DSR111297 - it should be noted that there are two flavors of select() on OS/2 */ 1.15 +/*There is standard BSD (which is kind of slow) and a new flavor of select() that takes */ 1.16 +/*an integer list of sockets, the number of read sockets, write sockets, except sockets, and */ 1.17 +/*a millisecond count for timeout. In the interest of performance I have choosen the OS/2 */ 1.18 +/*specific version of select(). See OS/2 TCP/IP Programmer's Toolkit for more info. */ 1.19 + 1.20 +#include "primpl.h" 1.21 + 1.22 +#include <sys/time.h> /* For timeval. */ 1.23 + 1.24 +#define _PR_INTERRUPT_CHECK_INTERVAL_SECS 5 1.25 +#define READ_FD 1 1.26 +#define WRITE_FD 2 1.27 + 1.28 +/* --- SOCKET IO --------------------------------------------------------- */ 1.29 + 1.30 + 1.31 +PRInt32 1.32 +_PR_MD_SOCKET(int domain, int type, int flags) 1.33 +{ 1.34 + PRInt32 osfd, err; 1.35 + 1.36 + osfd = socket(domain, type, flags); 1.37 + 1.38 + if (osfd == -1) 1.39 + { 1.40 + err = sock_errno(); 1.41 + _PR_MD_MAP_SOCKET_ERROR(err); 1.42 + } 1.43 + 1.44 + return(osfd); 1.45 +} 1.46 + 1.47 +/* 1.48 +** _MD_CloseSocket() -- Close a socket 1.49 +** 1.50 +*/ 1.51 +PRInt32 1.52 +_MD_CloseSocket(PRInt32 osfd) 1.53 +{ 1.54 + PRInt32 rv, err; 1.55 + 1.56 + rv = soclose(osfd); 1.57 + if (rv == -1) { 1.58 + err = sock_errno(); 1.59 + _PR_MD_MAP_CLOSE_ERROR(err); 1.60 + } 1.61 + return rv; 1.62 +} 1.63 + 1.64 +PRInt32 1.65 +_MD_SocketAvailable(PRFileDesc *fd) 1.66 +{ 1.67 + PRInt32 result; 1.68 + 1.69 + if (so_ioctl(fd->secret->md.osfd, FIONREAD, (char *) &result, sizeof(result)) < 0) { 1.70 + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, sock_errno()); 1.71 + return -1; 1.72 + } 1.73 + return result; 1.74 +} 1.75 + 1.76 +static PRInt32 1.77 +socket_io_wait( PRInt32 osfd, PRInt32 fd_type, PRIntervalTime timeout ) 1.78 +{ 1.79 + PRInt32 rv = -1; 1.80 + PRThread *me = _PR_MD_CURRENT_THREAD(); 1.81 + PRIntervalTime epoch, now, elapsed, remaining; 1.82 + PRBool wait_for_remaining; 1.83 + PRInt32 syserror; 1.84 +#ifdef BSD_SELECT 1.85 + struct timeval tv; 1.86 + fd_set rd_wr; 1.87 +#else 1.88 + int socks[1]; 1.89 + long lTimeout; 1.90 +#endif 1.91 + 1.92 + switch (timeout) { 1.93 + case PR_INTERVAL_NO_WAIT: 1.94 + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); 1.95 + break; 1.96 + case PR_INTERVAL_NO_TIMEOUT: 1.97 + /* 1.98 + * This is a special case of the 'default' case below. 1.99 + * Please see the comments there. 1.100 + */ 1.101 +#ifdef BSD_SELECT 1.102 + tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS; 1.103 + tv.tv_usec = 0; 1.104 + FD_ZERO(&rd_wr); 1.105 + do { 1.106 + FD_SET(osfd, &rd_wr); 1.107 + if (fd_type == READ_FD) 1.108 + rv = bsdselect(osfd + 1, &rd_wr, NULL, NULL, &tv); 1.109 + else 1.110 + rv = bsdselect(osfd + 1, NULL, &rd_wr, NULL, &tv); 1.111 +#else 1.112 + lTimeout = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000; 1.113 + do { 1.114 + socks[0] = osfd; 1.115 + if (fd_type == READ_FD) 1.116 + rv = os2_select(socks, 1, 0, 0, lTimeout); 1.117 + else 1.118 + rv = os2_select(socks, 0, 1, 0, lTimeout); 1.119 +#endif 1.120 + if (rv == -1 && (syserror = sock_errno()) != EINTR) { 1.121 + _PR_MD_MAP_SELECT_ERROR(syserror); 1.122 + break; 1.123 + } 1.124 + if (_PR_PENDING_INTERRUPT(me)) { 1.125 + me->flags &= ~_PR_INTERRUPT; 1.126 + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); 1.127 + rv = -1; 1.128 + break; 1.129 + } 1.130 + } while (rv == 0 || (rv == -1 && syserror == EINTR)); 1.131 + break; 1.132 + default: 1.133 + now = epoch = PR_IntervalNow(); 1.134 + remaining = timeout; 1.135 +#ifdef BSD_SELECT 1.136 + FD_ZERO(&rd_wr); 1.137 +#endif 1.138 + do { 1.139 + /* 1.140 + * We block in select for at most 1.141 + * _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds, 1.142 + * so that there is an upper limit on the delay 1.143 + * before the interrupt bit is checked. 1.144 + */ 1.145 +#ifdef BSD_SELECT 1.146 + wait_for_remaining = PR_TRUE; 1.147 + tv.tv_sec = PR_IntervalToSeconds(remaining); 1.148 + if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) { 1.149 + wait_for_remaining = PR_FALSE; 1.150 + tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS; 1.151 + tv.tv_usec = 0; 1.152 + } else { 1.153 + tv.tv_usec = PR_IntervalToMicroseconds( 1.154 + remaining - 1.155 + PR_SecondsToInterval(tv.tv_sec)); 1.156 + } 1.157 + FD_SET(osfd, &rd_wr); 1.158 + if (fd_type == READ_FD) 1.159 + rv = bsdselect(osfd + 1, &rd_wr, NULL, NULL, &tv); 1.160 + else 1.161 + rv = bsdselect(osfd + 1, NULL, &rd_wr, NULL, &tv); 1.162 +#else 1.163 + wait_for_remaining = PR_TRUE; 1.164 + lTimeout = PR_IntervalToMilliseconds(remaining); 1.165 + if (lTimeout > _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000) { 1.166 + wait_for_remaining = PR_FALSE; 1.167 + lTimeout = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000; 1.168 + } 1.169 + socks[0] = osfd; 1.170 + if (fd_type == READ_FD) 1.171 + rv = os2_select(socks, 1, 0, 0, lTimeout); 1.172 + else 1.173 + rv = os2_select(socks, 0, 1, 0, lTimeout); 1.174 +#endif 1.175 + /* 1.176 + * we don't consider EINTR a real error 1.177 + */ 1.178 + if (rv == -1 && (syserror = sock_errno()) != EINTR) { 1.179 + _PR_MD_MAP_SELECT_ERROR(syserror); 1.180 + break; 1.181 + } 1.182 + if (_PR_PENDING_INTERRUPT(me)) { 1.183 + me->flags &= ~_PR_INTERRUPT; 1.184 + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); 1.185 + rv = -1; 1.186 + break; 1.187 + } 1.188 + /* 1.189 + * We loop again if select timed out or got interrupted 1.190 + * by a signal, and the timeout deadline has not passed yet. 1.191 + */ 1.192 + if (rv == 0 || (rv == -1 && syserror == EINTR)) { 1.193 + /* 1.194 + * If select timed out, we know how much time 1.195 + * we spent in blocking, so we can avoid a 1.196 + * PR_IntervalNow() call. 1.197 + */ 1.198 + if (rv == 0) { 1.199 + if (wait_for_remaining) { 1.200 + now += remaining; 1.201 + } else { 1.202 +#ifdef BSD_SELECT 1.203 + now += PR_SecondsToInterval(tv.tv_sec) 1.204 + + PR_MicrosecondsToInterval(tv.tv_usec); 1.205 +#else 1.206 + now += PR_MillisecondsToInterval(lTimeout); 1.207 +#endif 1.208 + } 1.209 + } else { 1.210 + now = PR_IntervalNow(); 1.211 + } 1.212 + elapsed = (PRIntervalTime) (now - epoch); 1.213 + if (elapsed >= timeout) { 1.214 + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); 1.215 + rv = -1; 1.216 + break; 1.217 + } else { 1.218 + remaining = timeout - elapsed; 1.219 + } 1.220 + } 1.221 + } while (rv == 0 || (rv == -1 && syserror == EINTR)); 1.222 + break; 1.223 + } 1.224 + return(rv); 1.225 +} 1.226 + 1.227 +PRInt32 1.228 +_MD_Accept(PRFileDesc *fd, PRNetAddr *addr, 1.229 + PRUint32 *addrlen, PRIntervalTime timeout) 1.230 +{ 1.231 + PRInt32 osfd = fd->secret->md.osfd; 1.232 + PRInt32 rv, err; 1.233 + PRThread *me = _PR_MD_CURRENT_THREAD(); 1.234 + 1.235 + while ((rv = accept(osfd, (struct sockaddr*) addr, (int*)addrlen)) == -1) 1.236 + { 1.237 + err = sock_errno(); 1.238 + if ((err == EWOULDBLOCK) || (err == ECONNABORTED)) 1.239 + { 1.240 + if (fd->secret->nonblocking) { 1.241 + break; 1.242 + } 1.243 + if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0) 1.244 + goto done; 1.245 + } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ 1.246 + continue; 1.247 + } else { 1.248 + break; 1.249 + } 1.250 + } 1.251 + if (rv < 0) { 1.252 + _PR_MD_MAP_ACCEPT_ERROR(err); 1.253 + } 1.254 +done: 1.255 + return(rv); 1.256 +} 1.257 + 1.258 +PRInt32 1.259 +_PR_MD_CONNECT(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, 1.260 + PRIntervalTime timeout) 1.261 +{ 1.262 + PRInt32 rv, err; 1.263 + PRThread *me = _PR_MD_CURRENT_THREAD(); 1.264 + PRInt32 osfd = fd->secret->md.osfd; 1.265 + PRNetAddr addrCopy = *addr; /* Work around a bug in OS/2 where connect 1.266 + * modifies the sockaddr structure. 1.267 + * See Bugzilla bug 100776. */ 1.268 + 1.269 + /* 1.270 + * We initiate the connection setup by making a nonblocking connect() 1.271 + * call. If the connect() call fails, there are two cases we handle 1.272 + * specially: 1.273 + * 1. The connect() call was interrupted by a signal. In this case 1.274 + * we simply retry connect(). 1.275 + * 2. The NSPR socket is nonblocking and connect() fails with 1.276 + * EINPROGRESS. We first wait until the socket becomes writable. 1.277 + * Then we try to find out whether the connection setup succeeded 1.278 + * or failed. 1.279 + */ 1.280 + 1.281 +retry: 1.282 + if ((rv = connect(osfd, (struct sockaddr *)&addrCopy, addrlen)) == -1) 1.283 + { 1.284 + err = sock_errno(); 1.285 + 1.286 + if (err == EINTR) { 1.287 + if (_PR_PENDING_INTERRUPT(me)) { 1.288 + me->flags &= ~_PR_INTERRUPT; 1.289 + PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); 1.290 + return -1; 1.291 + } 1.292 + goto retry; 1.293 + } 1.294 + 1.295 + if (!fd->secret->nonblocking && (err == EINPROGRESS)) 1.296 + { 1.297 + /* 1.298 + * socket_io_wait() may return -1 or 1. 1.299 + */ 1.300 + 1.301 + rv = socket_io_wait(osfd, WRITE_FD, timeout); 1.302 + if (rv == -1) { 1.303 + return -1; 1.304 + } 1.305 + 1.306 + PR_ASSERT(rv == 1); 1.307 + if (_PR_PENDING_INTERRUPT(me)) { 1.308 + me->flags &= ~_PR_INTERRUPT; 1.309 + PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); 1.310 + return -1; 1.311 + } 1.312 + err = _MD_os2_get_nonblocking_connect_error(osfd); 1.313 + if (err != 0) { 1.314 + _PR_MD_MAP_CONNECT_ERROR(err); 1.315 + return -1; 1.316 + } 1.317 + return 0; 1.318 + } 1.319 + 1.320 + _PR_MD_MAP_CONNECT_ERROR(err); 1.321 + } 1.322 + 1.323 + return rv; 1.324 +} /* _MD_connect */ 1.325 + 1.326 +PRInt32 1.327 +_PR_MD_BIND(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen) 1.328 +{ 1.329 + PRInt32 rv, err; 1.330 + rv = bind(fd->secret->md.osfd, (struct sockaddr *) addr, (int )addrlen); 1.331 + if (rv < 0) { 1.332 + err = sock_errno(); 1.333 + _PR_MD_MAP_BIND_ERROR(err); 1.334 + } 1.335 + return(rv); 1.336 +} 1.337 + 1.338 + 1.339 +PRInt32 1.340 +_PR_MD_LISTEN(PRFileDesc *fd, PRIntn backlog) 1.341 +{ 1.342 + PRInt32 rv, err; 1.343 + rv = listen(fd->secret->md.osfd, backlog); 1.344 + if (rv < 0) { 1.345 + err = sock_errno(); 1.346 + _PR_MD_MAP_DEFAULT_ERROR(err); 1.347 + } 1.348 + return(rv); 1.349 +} 1.350 + 1.351 + 1.352 +PRInt32 1.353 +_PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, 1.354 + PRIntervalTime timeout) 1.355 +{ 1.356 + PRInt32 osfd = fd->secret->md.osfd; 1.357 + PRInt32 rv, err; 1.358 + PRThread *me = _PR_MD_CURRENT_THREAD(); 1.359 + 1.360 + while ((rv = recv(osfd,buf,amount,flags)) == -1) 1.361 + { 1.362 + err = sock_errno(); 1.363 + if ((err == EWOULDBLOCK)) { 1.364 + if (fd->secret->nonblocking) { 1.365 + break; 1.366 + } 1.367 + if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0) 1.368 + goto done; 1.369 + } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ 1.370 + continue; 1.371 + } else { 1.372 + break; 1.373 + } 1.374 + } 1.375 + if (rv < 0) { 1.376 + _PR_MD_MAP_RECV_ERROR(err); 1.377 + } 1.378 +done: 1.379 + return(rv); 1.380 +} 1.381 + 1.382 +PRInt32 1.383 +_PR_MD_SEND(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, 1.384 + PRIntervalTime timeout) 1.385 +{ 1.386 + PRInt32 osfd = fd->secret->md.osfd; 1.387 + PRInt32 rv, err; 1.388 + PRThread *me = _PR_MD_CURRENT_THREAD(); 1.389 + 1.390 + while ((rv = send(osfd,buf,amount,flags)) == -1) 1.391 + { 1.392 + err = sock_errno(); 1.393 + if ((err == EWOULDBLOCK)) { 1.394 + if (fd->secret->nonblocking) { 1.395 + break; 1.396 + } 1.397 + if ((rv = socket_io_wait(osfd, WRITE_FD, timeout)) < 0) 1.398 + goto done; 1.399 + } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ 1.400 + continue; 1.401 + } else { 1.402 + break; 1.403 + } 1.404 + } 1.405 + 1.406 + /* 1.407 + * optimization; if bytes sent is less than "amount" call 1.408 + * select before returning. This is because it is likely that 1.409 + * the next send() call will return EWOULDBLOCK. 1.410 + */ 1.411 + if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount) 1.412 + && (timeout != PR_INTERVAL_NO_WAIT)) 1.413 + { 1.414 + if (socket_io_wait(osfd, WRITE_FD, timeout)< 0) { 1.415 + rv = -1; 1.416 + goto done; 1.417 + } 1.418 + } 1.419 + if (rv < 0) { 1.420 + _PR_MD_MAP_SEND_ERROR(err); 1.421 + } 1.422 +done: 1.423 + return(rv); 1.424 +} 1.425 + 1.426 +PRInt32 1.427 +_PR_MD_SENDTO(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, 1.428 + const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout) 1.429 +{ 1.430 + PRInt32 osfd = fd->secret->md.osfd; 1.431 + PRInt32 rv, err; 1.432 + PRThread *me = _PR_MD_CURRENT_THREAD(); 1.433 + while ((rv = sendto(osfd, buf, amount, flags, 1.434 + (struct sockaddr *) addr, addrlen)) == -1) 1.435 + { 1.436 + err = sock_errno(); 1.437 + if ((err == EWOULDBLOCK)) 1.438 + { 1.439 + if (fd->secret->nonblocking) { 1.440 + break; 1.441 + } 1.442 + if ((rv = socket_io_wait(osfd, WRITE_FD, timeout)) < 0) 1.443 + goto done; 1.444 + } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ 1.445 + continue; 1.446 + } else { 1.447 + break; 1.448 + } 1.449 + } 1.450 + if (rv < 0) { 1.451 + _PR_MD_MAP_SENDTO_ERROR(err); 1.452 + } 1.453 +done: 1.454 + return(rv); 1.455 +} 1.456 + 1.457 +PRInt32 1.458 +_PR_MD_RECVFROM(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, 1.459 + PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout) 1.460 +{ 1.461 + PRInt32 osfd = fd->secret->md.osfd; 1.462 + PRInt32 rv, err; 1.463 + PRThread *me = _PR_MD_CURRENT_THREAD(); 1.464 + 1.465 + while( (*addrlen = PR_NETADDR_SIZE(addr)), 1.466 + ((rv = recvfrom(osfd, buf, amount, flags, 1.467 + (struct sockaddr *) addr, (int *)addrlen)) == -1)) 1.468 + { 1.469 + err = sock_errno(); 1.470 + if ((err == EWOULDBLOCK)) { 1.471 + if (fd->secret->nonblocking) { 1.472 + break; 1.473 + } 1.474 + if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0) 1.475 + goto done; 1.476 + } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ 1.477 + continue; 1.478 + } else { 1.479 + break; 1.480 + } 1.481 + } 1.482 + if (rv < 0) { 1.483 + _PR_MD_MAP_RECVFROM_ERROR(err); 1.484 + } 1.485 +done: 1.486 + return(rv); 1.487 +} 1.488 + 1.489 +PRInt32 1.490 +_PR_MD_WRITEV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, 1.491 + PRIntervalTime timeout) 1.492 +{ 1.493 + PRInt32 rv, err; 1.494 + PRThread *me = _PR_MD_CURRENT_THREAD(); 1.495 + PRInt32 index, amount = 0; 1.496 + PRInt32 osfd = fd->secret->md.osfd; 1.497 + struct iovec osiov[PR_MAX_IOVECTOR_SIZE]; 1.498 + 1.499 + /* Ensured by PR_Writev */ 1.500 + PR_ASSERT(iov_size <= PR_MAX_IOVECTOR_SIZE); 1.501 + 1.502 + /* 1.503 + * We can't pass iov to so_writev because PRIOVec and struct iovec 1.504 + * may not be binary compatible. Make osiov a copy of iov and 1.505 + * pass osiov to so_writev . 1.506 + */ 1.507 + for (index = 0; index < iov_size; index++) { 1.508 + osiov[index].iov_base = iov[index].iov_base; 1.509 + osiov[index].iov_len = iov[index].iov_len; 1.510 + } 1.511 + 1.512 + /* 1.513 + * Calculate the total number of bytes to be sent; needed for 1.514 + * optimization later. 1.515 + * We could avoid this if this number was passed in; but it is 1.516 + * probably not a big deal because iov_size is usually small (less than 1.517 + * 3) 1.518 + */ 1.519 + if (!fd->secret->nonblocking) { 1.520 + for (index=0; index<iov_size; index++) { 1.521 + amount += iov[index].iov_len; 1.522 + } 1.523 + } 1.524 + 1.525 + while ((rv = so_writev(osfd, osiov, iov_size)) == -1) { 1.526 + err = sock_errno(); 1.527 + if ((err == EWOULDBLOCK)) { 1.528 + if (fd->secret->nonblocking) { 1.529 + break; 1.530 + } 1.531 + if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))<0) 1.532 + goto done; 1.533 + } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ 1.534 + continue; 1.535 + } else { 1.536 + break; 1.537 + } 1.538 + } 1.539 + 1.540 + /* 1.541 + * optimization; if bytes sent is less than "amount" call 1.542 + * select before returning. This is because it is likely that 1.543 + * the next writev() call will return EWOULDBLOCK. 1.544 + */ 1.545 + if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount) 1.546 + && (timeout != PR_INTERVAL_NO_WAIT)) { 1.547 + if (socket_io_wait(osfd, WRITE_FD, timeout) < 0) { 1.548 + rv = -1; 1.549 + goto done; 1.550 + } 1.551 + } 1.552 + if (rv < 0) { 1.553 + _PR_MD_MAP_WRITEV_ERROR(err); 1.554 + } 1.555 +done: 1.556 + return(rv); 1.557 +} 1.558 + 1.559 +PRInt32 1.560 +_PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how) 1.561 +{ 1.562 + PRInt32 rv; 1.563 + 1.564 + rv = shutdown(fd->secret->md.osfd, how); 1.565 + if (rv < 0) 1.566 + _PR_MD_MAP_SHUTDOWN_ERROR(sock_errno()); 1.567 + return rv; 1.568 +} 1.569 + 1.570 +PRInt32 1.571 +_PR_MD_SOCKETPAIR(int af, int type, int flags, PRInt32 *osfd) 1.572 +{ 1.573 + PRInt32 rv, err; 1.574 + 1.575 + rv = socketpair(af, type, flags, osfd); 1.576 + if (rv < 0) { 1.577 + err = _MD_ERRNO(); 1.578 + _PR_MD_MAP_SOCKETPAIR_ERROR(err); 1.579 + } 1.580 + return rv; 1.581 +} 1.582 + 1.583 +PRStatus 1.584 +_PR_MD_GETSOCKNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen) 1.585 +{ 1.586 + PRInt32 rv, err; 1.587 + 1.588 + rv = getsockname(fd->secret->md.osfd, 1.589 + (struct sockaddr *) addr, (int *)addrlen); 1.590 + if (rv < 0) { 1.591 + err = sock_errno(); 1.592 + _PR_MD_MAP_GETSOCKNAME_ERROR(err); 1.593 + } 1.594 + return rv==0?PR_SUCCESS:PR_FAILURE; 1.595 +} 1.596 + 1.597 +PRStatus 1.598 +_PR_MD_GETPEERNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen) 1.599 +{ 1.600 + PRInt32 rv, err; 1.601 + 1.602 + rv = getpeername(fd->secret->md.osfd, 1.603 + (struct sockaddr *) addr, (int *)addrlen); 1.604 + if (rv < 0) { 1.605 + err = sock_errno(); 1.606 + _PR_MD_MAP_GETPEERNAME_ERROR(err); 1.607 + } 1.608 + return rv==0?PR_SUCCESS:PR_FAILURE; 1.609 +} 1.610 + 1.611 +PRStatus 1.612 +_PR_MD_GETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, 1.613 + char* optval, PRInt32* optlen) 1.614 +{ 1.615 + PRInt32 rv, err; 1.616 + 1.617 + rv = getsockopt(fd->secret->md.osfd, level, optname, optval, (int *)optlen); 1.618 + if (rv < 0) { 1.619 + err = sock_errno(); 1.620 + _PR_MD_MAP_GETSOCKOPT_ERROR(err); 1.621 + } 1.622 + return rv==0?PR_SUCCESS:PR_FAILURE; 1.623 +} 1.624 + 1.625 +PRStatus 1.626 +_PR_MD_SETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, 1.627 + const char* optval, PRInt32 optlen) 1.628 +{ 1.629 + PRInt32 rv, err; 1.630 + 1.631 + rv = setsockopt(fd->secret->md.osfd, level, optname, optval, optlen); 1.632 + if (rv < 0) { 1.633 + err = sock_errno(); 1.634 + _PR_MD_MAP_SETSOCKOPT_ERROR(err); 1.635 + } 1.636 + return rv==0?PR_SUCCESS:PR_FAILURE; 1.637 +} 1.638 + 1.639 +void 1.640 +_MD_MakeNonblock(PRFileDesc *fd) 1.641 +{ 1.642 + PRInt32 osfd = fd->secret->md.osfd; 1.643 + PRInt32 err; 1.644 + PRUint32 one = 1; 1.645 + 1.646 + if (osfd <= 2) { 1.647 + /* Don't mess around with stdin, stdout or stderr */ 1.648 + return; 1.649 + } 1.650 + 1.651 + err = so_ioctl( osfd, FIONBIO, (char *) &one, sizeof(one)); 1.652 + if ( err != 0 ) 1.653 + { 1.654 + err = sock_errno(); 1.655 + _PR_MD_MAP_SOCKET_ERROR(err); 1.656 + } 1.657 +}