PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - var/php_gcov/PHP_5_2/main - network.c
Test: PHP Code Coverage
Date: 2009-11-19 Instrumented lines: 358
Code covered: 53.4 % Executed lines: 191
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 5                                                        |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1997-2009 The PHP Group                                |
       6                 :    +----------------------------------------------------------------------+
       7                 :    | This source file is subject to version 3.01 of the PHP license,      |
       8                 :    | that is bundled with this package in the file LICENSE, and is        |
       9                 :    | available through the world-wide-web at the following url:           |
      10                 :    | http://www.php.net/license/3_01.txt                                  |
      11                 :    | If you did not receive a copy of the PHP license and are unable to   |
      12                 :    | obtain it through the world-wide-web, please send a note to          |
      13                 :    | license@php.net so we can mail you a copy immediately.               |
      14                 :    +----------------------------------------------------------------------+
      15                 :    | Author: Stig Venaas <venaas@uninett.no>                              |
      16                 :    | Streams work by Wez Furlong <wez@thebrainroom.com>                   |
      17                 :    +----------------------------------------------------------------------+
      18                 :  */
      19                 : 
      20                 : /* $Id: network.c 289019 2009-09-30 20:48:41Z iliaa $ */
      21                 : 
      22                 : /*#define DEBUG_MAIN_NETWORK 1*/
      23                 : 
      24                 : #include "php.h"
      25                 : 
      26                 : #include <stddef.h>
      27                 : 
      28                 : #ifdef PHP_WIN32
      29                 : #define O_RDONLY _O_RDONLY
      30                 : #include "win32/param.h"
      31                 : #elif defined(NETWARE)
      32                 : #include <sys/timeval.h>
      33                 : #include <sys/param.h>
      34                 : #else
      35                 : #include <sys/param.h>
      36                 : #endif
      37                 : 
      38                 : #include <sys/types.h>
      39                 : #if HAVE_SYS_SOCKET_H
      40                 : #include <sys/socket.h>
      41                 : #endif
      42                 : 
      43                 : #ifndef _FCNTL_H
      44                 : #include <fcntl.h>
      45                 : #endif
      46                 : 
      47                 : #ifdef HAVE_SYS_SELECT_H
      48                 : #include <sys/select.h>
      49                 : #endif
      50                 : #if HAVE_SYS_POLL_H
      51                 : #include <sys/poll.h>
      52                 : #endif
      53                 : 
      54                 : #if defined(NETWARE)
      55                 : #ifdef USE_WINSOCK
      56                 : #include <novsock2.h>
      57                 : #else
      58                 : #include <arpa/inet.h>
      59                 : #include <netinet/in.h>
      60                 : #include <netdb.h>
      61                 : #include <sys/select.h>
      62                 : #include <sys/socket.h>
      63                 : #endif
      64                 : #elif !defined(PHP_WIN32)
      65                 : #include <netinet/in.h>
      66                 : #include <netdb.h>
      67                 : #if HAVE_ARPA_INET_H
      68                 : #include <arpa/inet.h>
      69                 : #endif
      70                 : #endif
      71                 : 
      72                 : #ifndef HAVE_INET_ATON
      73                 : int inet_aton(const char *, struct in_addr *);
      74                 : #endif
      75                 : 
      76                 : #include "php_network.h"
      77                 : 
      78                 : #if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)
      79                 : #undef AF_UNIX
      80                 : #endif
      81                 : 
      82                 : #if defined(AF_UNIX)
      83                 : #include <sys/un.h>
      84                 : #endif
      85                 : 
      86                 : #include "ext/standard/file.h"
      87                 : 
      88                 : #ifdef PHP_WIN32
      89                 : # include "win32/time.h"
      90                 : # define SOCK_ERR INVALID_SOCKET
      91                 : # define SOCK_CONN_ERR SOCKET_ERROR
      92                 : # define PHP_TIMEOUT_ERROR_VALUE                WSAETIMEDOUT
      93                 : #else
      94                 : # define SOCK_ERR -1
      95                 : # define SOCK_CONN_ERR -1
      96                 : # define PHP_TIMEOUT_ERROR_VALUE                ETIMEDOUT
      97                 : #endif
      98                 : 
      99                 : #if HAVE_GETADDRINFO
     100                 : #ifdef HAVE_GAI_STRERROR
     101                 : #  define PHP_GAI_STRERROR(x) (gai_strerror(x))
     102                 : #else
     103                 : #  define PHP_GAI_STRERROR(x) (php_gai_strerror(x))
     104                 : /* {{{ php_gai_strerror
     105                 :  */
     106                 : static const char *php_gai_strerror(int code)
     107                 : {
     108                 :         static struct {
     109                 :                 int code;
     110                 :                 const char *msg;
     111                 :         } values[] = {
     112                 : #  ifdef EAI_ADDRFAMILY
     113                 :                 {EAI_ADDRFAMILY, "Address family for hostname not supported"},
     114                 : #  endif
     115                 :                 {EAI_AGAIN, "Temporary failure in name resolution"},
     116                 :                 {EAI_BADFLAGS, "Bad value for ai_flags"},
     117                 :                 {EAI_FAIL, "Non-recoverable failure in name resolution"},
     118                 :                 {EAI_FAMILY, "ai_family not supported"},
     119                 :                 {EAI_MEMORY, "Memory allocation failure"},
     120                 : #  ifdef EAI_NODATA
     121                 :                 {EAI_NODATA, "No address associated with hostname"},
     122                 : #  endif    
     123                 :                 {EAI_NONAME, "Name or service not known"},
     124                 :                 {EAI_SERVICE, "Servname not supported for ai_socktype"},
     125                 :                 {EAI_SOCKTYPE, "ai_socktype not supported"},
     126                 :                 {EAI_SYSTEM, "System error"},
     127                 :                 {0, NULL}
     128                 :         };
     129                 :         int i;
     130                 : 
     131                 :         for (i = 0; values[i].msg != NULL; i++) {
     132                 :                 if (values[i].code == code) {
     133                 :                         return (char *)values[i].msg;
     134                 :                 }
     135                 :         }
     136                 :         
     137                 :         return "Unknown error";
     138                 : }
     139                 : /* }}} */
     140                 : #endif
     141                 : #endif
     142                 : 
     143                 : /* {{{ php_network_freeaddresses
     144                 :  */
     145                 : static void php_network_freeaddresses(struct sockaddr **sal)
     146             138 : {
     147                 :         struct sockaddr **sap;
     148                 : 
     149             138 :         if (sal == NULL)
     150               0 :                 return;
     151             276 :         for (sap = sal; *sap != NULL; sap++)
     152             138 :                 efree(*sap);
     153             138 :         efree(sal);
     154                 : }
     155                 : /* }}} */
     156                 : 
     157                 : /* {{{ php_network_getaddresses
     158                 :  * Returns number of addresses, 0 for none/error
     159                 :  */
     160                 : static int php_network_getaddresses(const char *host, int socktype, struct sockaddr ***sal, char **error_string TSRMLS_DC)
     161             139 : {
     162                 :         struct sockaddr **sap;
     163                 :         int n;
     164                 : #if HAVE_GETADDRINFO
     165                 : # if HAVE_IPV6
     166                 :         static int ipv6_borked = -1; /* the way this is used *is* thread safe */
     167                 : # endif
     168                 :         struct addrinfo hints, *res, *sai;
     169                 : #else
     170                 :         struct hostent *host_info;
     171                 :         struct in_addr in;
     172                 : #endif
     173                 : 
     174             139 :         if (host == NULL) {
     175               0 :                 return 0;
     176                 :         }
     177                 : #if HAVE_GETADDRINFO
     178             139 :         memset(&hints, '\0', sizeof(hints));
     179                 :                 
     180             139 :         hints.ai_family = AF_INET; /* default to regular inet (see below) */
     181             139 :         hints.ai_socktype = socktype;
     182                 :                 
     183                 : # if HAVE_IPV6
     184                 :         /* probe for a working IPv6 stack; even if detected as having v6 at compile
     185                 :          * time, at runtime some stacks are slow to resolve or have other issues
     186                 :          * if they are not correctly configured.
     187                 :          * static variable use is safe here since simple store or fetch operations
     188                 :          * are atomic and because the actual probe process is not in danger of
     189                 :          * collisions or race conditions. */
     190             139 :         if (ipv6_borked == -1) {
     191                 :                 int s;
     192                 : 
     193              64 :                 s = socket(PF_INET6, SOCK_DGRAM, 0);
     194              64 :                 if (s == SOCK_ERR) {
     195               0 :                         ipv6_borked = 1;
     196                 :                 } else {
     197              64 :                         ipv6_borked = 0;
     198              64 :                         closesocket(s);
     199                 :                 }
     200                 :         }
     201             139 :         hints.ai_family = ipv6_borked ? AF_INET : AF_UNSPEC;
     202                 : # endif
     203                 :                 
     204             139 :         if ((n = getaddrinfo(host, NULL, &hints, &res))) {
     205               1 :                 if (error_string) {
     206               0 :                         spprintf(error_string, 0, "php_network_getaddresses: getaddrinfo failed: %s", PHP_GAI_STRERROR(n));
     207               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", *error_string);
     208                 :                 } else {
     209               1 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "php_network_getaddresses: getaddrinfo failed: %s", PHP_GAI_STRERROR(n));
     210                 :                 }
     211               1 :                 return 0;
     212             138 :         } else if (res == NULL) {
     213               0 :                 if (error_string) {
     214               0 :                         spprintf(error_string, 0, "php_network_getaddresses: getaddrinfo failed (null result pointer) errno=%d", errno);
     215               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", *error_string);
     216                 :                 } else {
     217               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "php_network_getaddresses: getaddrinfo failed (null result pointer)");
     218                 :                 }
     219               0 :                 return 0;
     220                 :         }
     221                 : 
     222             138 :         sai = res;
     223             138 :         for (n = 1; (sai = sai->ai_next) != NULL; n++)
     224                 :                 ;
     225                 :         
     226             138 :         *sal = safe_emalloc((n + 1), sizeof(*sal), 0);
     227             138 :         sai = res;
     228             138 :         sap = *sal;
     229                 :         
     230                 :         do {
     231             138 :                 *sap = emalloc(sai->ai_addrlen);
     232             138 :                 memcpy(*sap, sai->ai_addr, sai->ai_addrlen);
     233             138 :                 sap++;
     234             138 :         } while ((sai = sai->ai_next) != NULL);
     235                 :         
     236             138 :         freeaddrinfo(res);
     237                 : #else
     238                 :         if (!inet_aton(host, &in)) {
     239                 :                 /* XXX NOT THREAD SAFE (is safe under win32) */
     240                 :                 host_info = gethostbyname(host);
     241                 :                 if (host_info == NULL) {
     242                 :                         if (error_string) {
     243                 :                                 spprintf(error_string, 0, "php_network_getaddresses: gethostbyname failed. errno=%d", errno);
     244                 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", *error_string);
     245                 :                         } else {
     246                 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "php_network_getaddresses: gethostbyname failed");
     247                 :                         }
     248                 :                         return 0;
     249                 :                 }
     250                 :                 in = *((struct in_addr *) host_info->h_addr);
     251                 :         }
     252                 : 
     253                 :         *sal = safe_emalloc(2, sizeof(*sal), 0);
     254                 :         sap = *sal;
     255                 :         *sap = emalloc(sizeof(struct sockaddr_in));
     256                 :         (*sap)->sa_family = AF_INET;
     257                 :         ((struct sockaddr_in *)*sap)->sin_addr = in;
     258                 :         sap++;
     259                 :         n = 1;
     260                 : #endif
     261                 : 
     262             138 :         *sap = NULL;
     263             138 :         return n;
     264                 : }
     265                 : /* }}} */
     266                 : 
     267                 : #ifndef O_NONBLOCK
     268                 : #define O_NONBLOCK O_NDELAY
     269                 : #endif
     270                 : 
     271                 : #if !defined(__BEOS__)
     272                 : # define HAVE_NON_BLOCKING_CONNECT 1
     273                 : # ifdef PHP_WIN32
     274                 : typedef u_long php_non_blocking_flags_t;
     275                 : #  define SET_SOCKET_BLOCKING_MODE(sock, save) \
     276                 :      save = TRUE; ioctlsocket(sock, FIONBIO, &save)
     277                 : #  define RESTORE_SOCKET_BLOCKING_MODE(sock, save) \
     278                 :          ioctlsocket(sock, FIONBIO, &save)
     279                 : # else
     280                 : typedef int php_non_blocking_flags_t;
     281                 : #  define SET_SOCKET_BLOCKING_MODE(sock, save) \
     282                 :          save = fcntl(sock, F_GETFL, 0); \
     283                 :          fcntl(sock, F_SETFL, save | O_NONBLOCK)
     284                 : #  define RESTORE_SOCKET_BLOCKING_MODE(sock, save) \
     285                 :          fcntl(sock, F_SETFL, save)
     286                 : # endif
     287                 : #endif
     288                 : 
     289                 : /* Connect to a socket using an interruptible connect with optional timeout.
     290                 :  * Optionally, the connect can be made asynchronously, which will implicitly
     291                 :  * enable non-blocking mode on the socket.
     292                 :  * */
     293                 : /* {{{ php_network_connect_socket */
     294                 : PHPAPI int php_network_connect_socket(php_socket_t sockfd,
     295                 :                 const struct sockaddr *addr,
     296                 :                 socklen_t addrlen,
     297                 :                 int asynchronous,
     298                 :                 struct timeval *timeout,
     299                 :                 char **error_string,
     300                 :                 int *error_code)
     301              76 : {
     302                 : #if HAVE_NON_BLOCKING_CONNECT
     303                 :         php_non_blocking_flags_t orig_flags;
     304                 :         int n;
     305              76 :         int error = 0;
     306                 :         socklen_t len;
     307              76 :         int ret = 0;
     308                 : 
     309              76 :         SET_SOCKET_BLOCKING_MODE(sockfd, orig_flags);
     310                 :         
     311              76 :         if ((n = connect(sockfd, addr, addrlen)) != 0) {
     312              68 :                 error = php_socket_errno();
     313                 : 
     314              68 :                 if (error_code) {
     315              40 :                         *error_code = error;
     316                 :                 }
     317                 : 
     318              68 :                 if (error != EINPROGRESS) {
     319               0 :                         if (error_string) {
     320               0 :                                 *error_string = php_socket_strerror(error, NULL, 0);
     321                 :                         }
     322                 : 
     323               0 :                         return -1;
     324                 :                 }
     325              68 :                 if (asynchronous && error == EINPROGRESS) {
     326                 :                         /* this is fine by us */
     327               1 :                         return 0;
     328                 :                 }
     329                 :         }
     330                 : 
     331              75 :         if (n == 0) {
     332               8 :                 goto ok;
     333                 :         }
     334                 : 
     335              67 :         if ((n = php_pollfd_for(sockfd, PHP_POLLREADABLE|POLLOUT, timeout)) == 0) {
     336               0 :                 error = PHP_TIMEOUT_ERROR_VALUE;
     337                 :         }
     338                 : 
     339              67 :         if (n > 0) {
     340              67 :                 len = sizeof(error);
     341                 :                 /*
     342                 :                    BSD-derived systems set errno correctly
     343                 :                    Solaris returns -1 from getsockopt in case of error
     344                 :                    */
     345              67 :                 if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char*)&error, &len) != 0) {
     346               0 :                         ret = -1;
     347                 :                 }
     348                 :         } else {
     349                 :                 /* whoops: sockfd has disappeared */
     350               0 :                 ret = -1;
     351                 :         }
     352                 : 
     353              75 : ok:
     354              75 :         if (!asynchronous) {
     355                 :                 /* back to blocking mode */
     356              75 :                 RESTORE_SOCKET_BLOCKING_MODE(sockfd, orig_flags);
     357                 :         }
     358                 : 
     359              75 :         if (error_code) {
     360              47 :                 *error_code = error;
     361                 :         }
     362                 : 
     363              75 :         if (error && error_string) {
     364               5 :                 *error_string = php_socket_strerror(error, NULL, 0);
     365               5 :                 ret = -1;
     366                 :         }
     367              75 :         return ret;
     368                 : #else
     369                 :         if (asynchronous) {
     370                 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Asynchronous connect() not supported on this platform");
     371                 :         }
     372                 :         return (connect(sockfd, addr, addrlen) == 0) ? 0 : -1;
     373                 : #endif
     374                 : }
     375                 : /* }}} */
     376                 : 
     377                 : /* {{{ sub_times */
     378                 : static inline void sub_times(struct timeval a, struct timeval b, struct timeval *result)
     379               5 : {
     380               5 :         result->tv_usec = a.tv_usec - b.tv_usec;
     381               5 :         if (result->tv_usec < 0L) {
     382               5 :                 a.tv_sec--;
     383               5 :                 result->tv_usec += 1000000L;
     384                 :         }
     385               5 :         result->tv_sec = a.tv_sec - b.tv_sec;
     386               5 :         if (result->tv_sec < 0L) {
     387               0 :                 result->tv_sec++;
     388               0 :                 result->tv_usec -= 1000000L;
     389                 :         }
     390               5 : }
     391                 : /* }}} */
     392                 : 
     393                 : /* Bind to a local IP address.
     394                 :  * Returns the bound socket, or -1 on failure.
     395                 :  * */
     396                 : /* {{{ php_network_bind_socket_to_local_addr */
     397                 : php_socket_t php_network_bind_socket_to_local_addr(const char *host, unsigned port,
     398                 :                 int socktype, char **error_string, int *error_code
     399                 :                 TSRMLS_DC)
     400              65 : {
     401              65 :         int num_addrs, n, err = 0;
     402                 :         php_socket_t sock;
     403                 :         struct sockaddr **sal, **psal, *sa;
     404                 :         socklen_t socklen;
     405                 : 
     406              65 :         num_addrs = php_network_getaddresses(host, socktype, &psal, error_string TSRMLS_CC);
     407                 : 
     408              65 :         if (num_addrs == 0) {
     409                 :                 /* could not resolve address(es) */
     410               0 :                 return -1;
     411                 :         }
     412                 : 
     413              65 :         for (sal = psal; *sal != NULL; sal++) {
     414              65 :                 sa = *sal;
     415                 : 
     416                 :                 /* create a socket for this address */
     417              65 :                 sock = socket(sa->sa_family, socktype, 0);
     418                 : 
     419              65 :                 if (sock == SOCK_ERR) {
     420               0 :                         continue;
     421                 :                 }
     422                 : 
     423              65 :                 switch (sa->sa_family) {
     424                 : #if HAVE_GETADDRINFO && HAVE_IPV6
     425                 :                         case AF_INET6:
     426               2 :                                 ((struct sockaddr_in6 *)sa)->sin6_family = sa->sa_family;
     427               2 :                                 ((struct sockaddr_in6 *)sa)->sin6_port = htons(port);
     428               2 :                                 socklen = sizeof(struct sockaddr_in6);
     429               2 :                                 break;
     430                 : #endif
     431                 :                         case AF_INET:
     432              63 :                                 ((struct sockaddr_in *)sa)->sin_family = sa->sa_family;
     433              63 :                                 ((struct sockaddr_in *)sa)->sin_port = htons(port);
     434              63 :                                 socklen = sizeof(struct sockaddr_in);
     435              63 :                                 break;
     436                 :                         default:
     437                 :                                 /* Unknown family */
     438               0 :                                 socklen = 0;
     439               0 :                                 sa = NULL;
     440                 :                 }
     441                 : 
     442              65 :                 if (sa) {
     443                 :                         /* attempt to bind */
     444                 :                 
     445                 : #ifdef SO_REUSEADDR
     446                 :                         {
     447              65 :                                 int val = 1;
     448              65 :                                 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&val, sizeof(val));
     449                 :                         }
     450                 : #endif
     451                 :                         
     452              65 :                         n = bind(sock, sa, socklen);
     453                 : 
     454              65 :                         if (n != SOCK_CONN_ERR) {
     455              65 :                                 goto bound;
     456                 :                         }
     457                 : 
     458               0 :                         err = php_socket_errno();
     459                 :                 }
     460                 : 
     461               0 :                 closesocket(sock);
     462                 :         }
     463               0 :         sock = -1;
     464                 : 
     465               0 :         if (error_code) {
     466               0 :                 *error_code = err;
     467                 :         }
     468               0 :         if (error_string) {
     469               0 :                 *error_string = php_socket_strerror(err, NULL, 0);
     470                 :         }
     471                 :         
     472              65 : bound:
     473                 : 
     474              65 :         php_network_freeaddresses(psal);
     475                 :         
     476              65 :         return sock;
     477                 :         
     478                 : }
     479                 : /* }}} */
     480                 : 
     481                 : PHPAPI int php_network_parse_network_address_with_port(const char *addr, long addrlen, struct sockaddr *sa, socklen_t *sl TSRMLS_DC)
     482               0 : {
     483                 :         char *colon;
     484                 :         char *tmp;
     485               0 :         int ret = FAILURE;
     486                 :         short port;
     487               0 :         struct sockaddr_in *in4 = (struct sockaddr_in*)sa;
     488                 :         struct sockaddr **psal;
     489                 :         int n;
     490               0 :         char *errstr = NULL;
     491                 : #if HAVE_IPV6
     492               0 :         struct sockaddr_in6 *in6 = (struct sockaddr_in6*)sa;
     493                 : #endif
     494                 : 
     495               0 :         if (*addr == '[') {
     496               0 :                 colon = memchr(addr + 1, ']', addrlen-1);
     497               0 :                 if (!colon || colon[1] != ':') {
     498               0 :                         return FAILURE;
     499                 :                 }
     500               0 :                 port = atoi(colon + 2);
     501               0 :                 addr++;
     502                 :         } else {
     503               0 :                 colon = memchr(addr, ':', addrlen);
     504               0 :                 if (!colon) {
     505               0 :                         return FAILURE;
     506                 :                 }
     507               0 :                 port = atoi(colon + 1);
     508                 :         }
     509                 : 
     510               0 :         tmp = estrndup(addr, colon - addr);
     511                 : 
     512                 :         /* first, try interpreting the address as a numeric address */
     513                 : 
     514                 : #if HAVE_IPV6 && HAVE_INET_PTON
     515               0 :         if (inet_pton(AF_INET6, tmp, &in6->sin6_addr) > 0) {
     516               0 :                 in6->sin6_port = htons(port);
     517               0 :                 in6->sin6_family = AF_INET6;
     518               0 :                 *sl = sizeof(struct sockaddr_in6);
     519               0 :                 ret = SUCCESS;
     520               0 :                 goto out;
     521                 :         }
     522                 : #endif
     523               0 :         if (inet_aton(tmp, &in4->sin_addr) > 0) {
     524               0 :                 in4->sin_port = htons(port);
     525               0 :                 in4->sin_family = AF_INET;
     526               0 :                 *sl = sizeof(struct sockaddr_in);
     527               0 :                 ret = SUCCESS;
     528               0 :                 goto out;
     529                 :         }
     530                 : 
     531                 :         /* looks like we'll need to resolve it */
     532               0 :         n = php_network_getaddresses(tmp, SOCK_DGRAM, &psal, &errstr TSRMLS_CC);
     533                 : 
     534               0 :         if (n == 0) {
     535               0 :                 if (errstr) {
     536               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to resolve `%s': %s", tmp, errstr);
     537               0 :                         STR_FREE(errstr);
     538                 :                 }
     539               0 :                 goto out;
     540                 :         }
     541                 : 
     542                 :         /* copy the details from the first item */
     543               0 :         switch ((*psal)->sa_family) {
     544                 : #if HAVE_GETADDRINFO && HAVE_IPV6
     545                 :                 case AF_INET6:
     546               0 :                         *in6 = **(struct sockaddr_in6**)psal;
     547               0 :                         in6->sin6_port = htons(port);
     548               0 :                         *sl = sizeof(struct sockaddr_in6);
     549               0 :                         ret = SUCCESS;
     550               0 :                         break;
     551                 : #endif
     552                 :                 case AF_INET:
     553               0 :                         *in4 = **(struct sockaddr_in**)psal;
     554               0 :                         in4->sin_port = htons(port);
     555               0 :                         *sl = sizeof(struct sockaddr_in);
     556               0 :                         ret = SUCCESS;
     557                 :                         break;
     558                 :         }
     559                 : 
     560               0 :         php_network_freeaddresses(psal);
     561                 : 
     562               0 : out:
     563               0 :         STR_FREE(tmp);
     564               0 :         return ret;
     565                 : }
     566                 : 
     567                 : 
     568                 : PHPAPI void php_network_populate_name_from_sockaddr(
     569                 :                 /* input address */
     570                 :                 struct sockaddr *sa, socklen_t sl,
     571                 :                 /* output readable address */
     572                 :                 char **textaddr, long *textaddrlen,
     573                 :                 /* output address */
     574                 :                 struct sockaddr **addr,
     575                 :                 socklen_t *addrlen
     576                 :                 TSRMLS_DC)
     577              41 : {
     578              41 :         if (addr) {
     579               0 :                 *addr = emalloc(sl);
     580               0 :                 memcpy(*addr, sa, sl);
     581               0 :                 *addrlen = sl;
     582                 :         }
     583                 : 
     584              41 :         if (textaddr) {
     585                 : #if HAVE_IPV6 && HAVE_INET_NTOP
     586                 :                 char abuf[256];
     587                 : #endif
     588               0 :                 char *buf = NULL;
     589                 : 
     590               0 :                 switch (sa->sa_family) {
     591                 :                         case AF_INET:
     592                 :                                 /* generally not thread safe, but it *is* thread safe under win32 */
     593               0 :                                 buf = inet_ntoa(((struct sockaddr_in*)sa)->sin_addr);
     594               0 :                                 if (buf) {
     595               0 :                                         *textaddrlen = spprintf(textaddr, 0, "%s:%d", 
     596                 :                                                 buf, ntohs(((struct sockaddr_in*)sa)->sin_port));
     597                 :                                 }
     598                 : 
     599               0 :                                 break;
     600                 : 
     601                 : #if HAVE_IPV6 && HAVE_INET_NTOP
     602                 :                         case AF_INET6:
     603               0 :                                 buf = (char*)inet_ntop(sa->sa_family, &((struct sockaddr_in6*)sa)->sin6_addr, (char *)&abuf, sizeof(abuf));
     604               0 :                                 if (buf) {
     605               0 :                                         *textaddrlen = spprintf(textaddr, 0, "%s:%d", 
     606                 :                                                 buf, ntohs(((struct sockaddr_in6*)sa)->sin6_port));
     607                 :                                 }
     608                 : 
     609               0 :                                 break;
     610                 : #endif
     611                 : #ifdef AF_UNIX
     612                 :                         case AF_UNIX:
     613                 :                                 {
     614               0 :                                         struct sockaddr_un *ua = (struct sockaddr_un*)sa;
     615                 : 
     616               0 :                                         if (ua->sun_path[0] == '\0') {
     617                 :                                                 /* abstract name */
     618               0 :                                                 int len = strlen(ua->sun_path + 1) + 1;
     619               0 :                                                 *textaddrlen = len;
     620               0 :                                                 *textaddr = emalloc(len + 1);
     621               0 :                                                 memcpy(*textaddr, ua->sun_path, len);
     622               0 :                                                 (*textaddr)[len] = '\0';
     623                 :                                         } else {
     624               0 :                                                 *textaddrlen = strlen(ua->sun_path);
     625               0 :                                                 *textaddr = estrndup(ua->sun_path, *textaddrlen);
     626                 :                                         }
     627                 :                                 }
     628                 :                                 break;
     629                 : #endif
     630                 : 
     631                 :                 }
     632                 : 
     633                 :         }
     634              41 : }
     635                 : 
     636                 : PHPAPI int php_network_get_peer_name(php_socket_t sock, 
     637                 :                 char **textaddr, long *textaddrlen,
     638                 :                 struct sockaddr **addr,
     639                 :                 socklen_t *addrlen
     640                 :                 TSRMLS_DC)
     641               0 : {
     642                 :         php_sockaddr_storage sa;
     643               0 :         socklen_t sl = sizeof(sa);
     644               0 :         memset(&sa, 0, sizeof(sa));
     645                 :         
     646               0 :         if (getpeername(sock, (struct sockaddr*)&sa, &sl) == 0) {
     647               0 :                 php_network_populate_name_from_sockaddr((struct sockaddr*)&sa, sl,
     648                 :                                 textaddr, textaddrlen,
     649                 :                                 addr, addrlen
     650                 :                                 TSRMLS_CC);
     651               0 :                 return 0;
     652                 :         }
     653               0 :         return -1;
     654                 : }
     655                 : 
     656                 : PHPAPI int php_network_get_sock_name(php_socket_t sock, 
     657                 :                 char **textaddr, long *textaddrlen,
     658                 :                 struct sockaddr **addr,
     659                 :                 socklen_t *addrlen
     660                 :                 TSRMLS_DC)
     661               0 : {
     662                 :         php_sockaddr_storage sa;
     663               0 :         socklen_t sl = sizeof(sa);
     664               0 :         memset(&sa, 0, sizeof(sa));
     665                 :         
     666               0 :         if (getsockname(sock, (struct sockaddr*)&sa, &sl) == 0) {
     667               0 :                 php_network_populate_name_from_sockaddr((struct sockaddr*)&sa, sl,
     668                 :                                 textaddr, textaddrlen,
     669                 :                                 addr, addrlen
     670                 :                                 TSRMLS_CC);
     671               0 :                 return 0;
     672                 :         }
     673               0 :         return -1;
     674                 : 
     675                 : }
     676                 : 
     677                 : 
     678                 : /* Accept a client connection from a server socket,
     679                 :  * using an optional timeout.
     680                 :  * Returns the peer address in addr/addrlen (it will emalloc
     681                 :  * these, so be sure to efree the result).
     682                 :  * If you specify textaddr/textaddrlen, a text-printable
     683                 :  * version of the address will be emalloc'd and returned.
     684                 :  * */
     685                 : 
     686                 : /* {{{ php_network_accept_incoming */
     687                 : PHPAPI php_socket_t php_network_accept_incoming(php_socket_t srvsock,
     688                 :                 char **textaddr, long *textaddrlen,
     689                 :                 struct sockaddr **addr,
     690                 :                 socklen_t *addrlen,
     691                 :                 struct timeval *timeout,
     692                 :                 char **error_string,
     693                 :                 int *error_code
     694                 :                 TSRMLS_DC)
     695              41 : {
     696              41 :         php_socket_t clisock = -1;
     697              41 :         int error = 0, n;
     698                 :         php_sockaddr_storage sa;
     699                 :         socklen_t sl;
     700                 :                 
     701              41 :         n = php_pollfd_for(srvsock, PHP_POLLREADABLE, timeout);
     702                 : 
     703              41 :         if (n == 0) {
     704               0 :                 error = PHP_TIMEOUT_ERROR_VALUE;
     705              41 :         } else if (n == -1) {
     706               0 :                 error = php_socket_errno();
     707                 :         } else {
     708              41 :                 sl = sizeof(sa);
     709                 : 
     710              41 :                 clisock = accept(srvsock, (struct sockaddr*)&sa, &sl);
     711                 : 
     712              41 :                 if (clisock != SOCK_ERR) {
     713              41 :                         php_network_populate_name_from_sockaddr((struct sockaddr*)&sa, sl,
     714                 :                                         textaddr, textaddrlen,
     715                 :                                         addr, addrlen
     716                 :                                         TSRMLS_CC);
     717                 :                 } else {
     718               0 :                         error = php_socket_errno();
     719                 :                 }
     720                 :         }
     721                 :         
     722              41 :         if (error_code) {
     723              41 :                 *error_code = error;
     724                 :         }
     725              41 :         if (error_string) {
     726              41 :                 *error_string = php_socket_strerror(error, NULL, 0);
     727                 :         }
     728                 :         
     729              41 :         return clisock;
     730                 : }
     731                 : /* }}} */
     732                 :         
     733                 : 
     734                 : 
     735                 : /* Connect to a remote host using an interruptible connect with optional timeout.
     736                 :  * Optionally, the connect can be made asynchronously, which will implicitly
     737                 :  * enable non-blocking mode on the socket.
     738                 :  * Returns the connected (or connecting) socket, or -1 on failure.
     739                 :  * */
     740                 : 
     741                 : /* {{{ php_network_connect_socket_to_host */
     742                 : php_socket_t php_network_connect_socket_to_host(const char *host, unsigned short port,
     743                 :                 int socktype, int asynchronous, struct timeval *timeout, char **error_string,
     744                 :                 int *error_code, char *bindto, unsigned short bindport 
     745                 :                 TSRMLS_DC)
     746              74 : {
     747              74 :         int num_addrs, n, fatal = 0;
     748                 :         php_socket_t sock;
     749                 :         struct sockaddr **sal, **psal, *sa;
     750                 :         struct timeval working_timeout;
     751                 :         socklen_t socklen;
     752                 : #if HAVE_GETTIMEOFDAY
     753                 :         struct timeval limit_time, time_now;
     754                 : #endif
     755                 : 
     756              74 :         num_addrs = php_network_getaddresses(host, socktype, &psal, error_string TSRMLS_CC);
     757                 : 
     758              74 :         if (num_addrs == 0) {
     759                 :                 /* could not resolve address(es) */
     760               1 :                 return -1;
     761                 :         }
     762                 : 
     763              73 :         if (timeout) {
     764              73 :                 memcpy(&working_timeout, timeout, sizeof(working_timeout));
     765                 : #if HAVE_GETTIMEOFDAY
     766              73 :                 gettimeofday(&limit_time, NULL);
     767              73 :                 limit_time.tv_sec += working_timeout.tv_sec;
     768              73 :                 limit_time.tv_usec += working_timeout.tv_usec;
     769              73 :                 if (limit_time.tv_usec >= 1000000) {
     770               2 :                         limit_time.tv_usec -= 1000000;
     771               2 :                         limit_time.tv_sec++;
     772                 :                 }
     773                 : #endif
     774                 :         }
     775                 : 
     776              78 :         for (sal = psal; !fatal && *sal != NULL; sal++) {
     777              73 :                 sa = *sal;
     778                 : 
     779                 :                 /* create a socket for this address */
     780              73 :                 sock = socket(sa->sa_family, socktype, 0);
     781                 : 
     782              73 :                 if (sock == SOCK_ERR) {
     783               0 :                         continue;
     784                 :                 }
     785                 : 
     786              73 :                 switch (sa->sa_family) {
     787                 : #if HAVE_GETADDRINFO && HAVE_IPV6
     788                 :                         case AF_INET6:
     789              12 :                                 if (!bindto || strchr(bindto, ':')) {
     790               6 :                                         ((struct sockaddr_in6 *)sa)->sin6_family = sa->sa_family;
     791               6 :                                         ((struct sockaddr_in6 *)sa)->sin6_port = htons(port);
     792               6 :                                         socklen = sizeof(struct sockaddr_in6);
     793                 :                                 } else {
     794               0 :                                         socklen = 0;
     795               0 :                                         sa = NULL;
     796                 :                                 }
     797               6 :                                 break;
     798                 : #endif
     799                 :                         case AF_INET:
     800              67 :                                 ((struct sockaddr_in *)sa)->sin_family = sa->sa_family;
     801              67 :                                 ((struct sockaddr_in *)sa)->sin_port = htons(port);
     802              67 :                                 socklen = sizeof(struct sockaddr_in);
     803              67 :                                 break;
     804                 :                         default:
     805                 :                                 /* Unknown family */
     806               0 :                                 socklen = 0;
     807               0 :                                 sa = NULL;
     808                 :                 }
     809                 : 
     810              73 :                 if (sa) {
     811                 :                         /* make a connection attempt */
     812                 : 
     813              73 :                         if (bindto) {
     814               0 :                                 struct sockaddr *local_address = NULL;
     815               0 :                                 int local_address_len = 0;
     816                 : 
     817               0 :                                 if (sa->sa_family == AF_INET) {
     818               0 :                                         struct sockaddr_in *in4 = emalloc(sizeof(struct sockaddr_in));
     819                 : 
     820               0 :                                         local_address = (struct sockaddr*)in4;
     821               0 :                                         local_address_len = sizeof(struct sockaddr_in);
     822                 :                                 
     823               0 :                                         in4->sin_family = sa->sa_family;
     824               0 :                                         in4->sin_port = htons(bindport);
     825               0 :                                         if (!inet_aton(bindto, &in4->sin_addr)) {
     826               0 :                                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid IP Address: %s", bindto);
     827               0 :                                                 goto skip_bind;
     828                 :                                         }
     829               0 :                                         memset(&(in4->sin_zero), 0, sizeof(in4->sin_zero));
     830                 :                                 }
     831                 : #if HAVE_IPV6 && HAVE_INET_PTON
     832                 :                                  else { /* IPV6 */
     833               0 :                                         struct sockaddr_in6 *in6 = emalloc(sizeof(struct sockaddr_in6));
     834                 : 
     835               0 :                                         local_address = (struct sockaddr*)in6;
     836               0 :                                         local_address_len = sizeof(struct sockaddr_in6);
     837                 :                                 
     838               0 :                                         in6->sin6_family = sa->sa_family;
     839               0 :                                         in6->sin6_port = htons(bindport);
     840               0 :                                         if (inet_pton(AF_INET6, bindto, &in6->sin6_addr) < 1) {
     841               0 :                                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid IP Address: %s", bindto);
     842               0 :                                                 goto skip_bind;
     843                 :                                         }
     844                 :                                 }
     845                 : #endif
     846               0 :                                 if (!local_address || bind(sock, local_address, local_address_len)) {
     847               0 :                                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to bind to '%s:%d', system said: %s", bindto, bindport, strerror(errno));
     848                 :                                 }
     849               0 : skip_bind:
     850               0 :                                 if (local_address) {
     851               0 :                                         efree(local_address);
     852                 :                                 }
     853                 :                         }
     854                 :                         /* free error string recieved during previous iteration (if any) */
     855              73 :                         if (error_string && *error_string) {
     856               0 :                                 efree(*error_string);
     857               0 :                                 *error_string = NULL;
     858                 :                         }
     859                 :                         
     860              73 :                         n = php_network_connect_socket(sock, sa, socklen, asynchronous,
     861                 :                                         timeout ? &working_timeout : NULL,
     862                 :                                         error_string, error_code);
     863                 : 
     864              73 :                         if (n != -1) {
     865              68 :                                 goto connected;
     866                 :                         }
     867                 : 
     868                 :                         /* adjust timeout for next attempt */
     869                 : #if HAVE_GETTIMEOFDAY
     870               5 :                         if (timeout) {
     871               5 :                                 gettimeofday(&time_now, NULL);
     872                 : 
     873               5 :                                 if (timercmp(&time_now, &limit_time, >=)) {
     874                 :                                         /* time limit expired; don't attempt any further connections */
     875               0 :                                         fatal = 1;
     876                 :                                 } else {
     877                 :                                         /* work out remaining time */
     878               5 :                                         sub_times(limit_time, time_now, &working_timeout);
     879                 :                                 }
     880                 :                         }
     881                 : #else
     882                 :                         if (error_code && *error_code == PHP_TIMEOUT_ERROR_VALUE) {
     883                 :                                 /* Don't even bother trying to connect to the next alternative;
     884                 :                                  * we have no way to determine how long we have already taken
     885                 :                                  * and it is quite likely that the next attempt will fail too. */
     886                 :                                 fatal = 1;
     887                 :                         } else {
     888                 :                                 /* re-use the same initial timeout.
     889                 :                                  * Not the best thing, but in practice it should be good-enough */
     890                 :                                 if (timeout) {
     891                 :                                         memcpy(&working_timeout, timeout, sizeof(working_timeout));
     892                 :                                 }
     893                 :                         }
     894                 : #endif
     895                 :                 }
     896                 : 
     897               5 :                 closesocket(sock);
     898                 :         }
     899               5 :         sock = -1;
     900                 : 
     901              73 : connected:
     902                 : 
     903              73 :         php_network_freeaddresses(psal);
     904                 :         
     905              73 :         return sock;
     906                 : }
     907                 : /* }}} */
     908                 : 
     909                 : /* {{{ php_any_addr
     910                 :  * Fills the any (wildcard) address into php_sockaddr_storage
     911                 :  */
     912                 : PHPAPI void php_any_addr(int family, php_sockaddr_storage *addr, unsigned short port)
     913              21 : {
     914              21 :         memset(addr, 0, sizeof(php_sockaddr_storage));
     915              21 :         switch (family) {
     916                 : #if HAVE_IPV6
     917                 :         case AF_INET6: {
     918               0 :                 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) addr;
     919               0 :                 sin6->sin6_family = AF_INET6;
     920               0 :                 sin6->sin6_port = htons(port);
     921               0 :                 sin6->sin6_addr = in6addr_any;
     922               0 :                 break;
     923                 :         }
     924                 : #endif
     925                 :         case AF_INET: {
     926              21 :                 struct sockaddr_in *sin = (struct sockaddr_in *) addr;
     927              21 :                 sin->sin_family = AF_INET;
     928              21 :                 sin->sin_port = htons(port);
     929              21 :                 sin->sin_addr.s_addr = htonl(INADDR_ANY);
     930                 :                 break;
     931                 :         }
     932                 :         }
     933              21 : }
     934                 : /* }}} */
     935                 : 
     936                 : /* {{{ php_sockaddr_size
     937                 :  * Returns the size of struct sockaddr_xx for the family
     938                 :  */
     939                 : PHPAPI int php_sockaddr_size(php_sockaddr_storage *addr)
     940              21 : {
     941              21 :         switch (((struct sockaddr *)addr)->sa_family) {
     942                 :         case AF_INET:
     943              21 :                 return sizeof(struct sockaddr_in);
     944                 : #if HAVE_IPV6
     945                 :         case AF_INET6:
     946               0 :                 return sizeof(struct sockaddr_in6);
     947                 : #endif
     948                 : #ifdef AF_UNIX
     949                 :         case AF_UNIX:
     950               0 :                 return sizeof(struct sockaddr_un);
     951                 : #endif
     952                 :         default:
     953               0 :                 return 0;
     954                 :         }
     955                 : }
     956                 : /* }}} */
     957                 : 
     958                 : /* Given a socket error code, if buf == NULL:
     959                 :  *   emallocs storage for the error message and returns
     960                 :  * else
     961                 :  *   sprintf message into provided buffer and returns buf
     962                 :  */
     963                 : /* {{{ php_socket_strerror */
     964                 : PHPAPI char *php_socket_strerror(long err, char *buf, size_t bufsize)
     965              48 : {
     966                 : #ifndef PHP_WIN32
     967                 :         char *errstr;
     968                 : 
     969              48 :         errstr = strerror(err);
     970              48 :         if (buf == NULL) {
     971              48 :                 buf = estrdup(errstr);
     972                 :         } else {
     973               0 :                 strncpy(buf, errstr, bufsize);
     974                 :         }
     975              48 :         return buf;
     976                 : #else
     977                 :         char *sysbuf;
     978                 :         int free_it = 1;
     979                 : 
     980                 :         if (!FormatMessage(
     981                 :                                 FORMAT_MESSAGE_ALLOCATE_BUFFER | 
     982                 :                                 FORMAT_MESSAGE_FROM_SYSTEM |
     983                 :                                 FORMAT_MESSAGE_IGNORE_INSERTS,
     984                 :                                 NULL,
     985                 :                                 err,
     986                 :                                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
     987                 :                                 (LPTSTR)&sysbuf,
     988                 :                                 0,
     989                 :                                 NULL)) {
     990                 :                 free_it = 0;
     991                 :                 sysbuf = "Unknown Error";
     992                 :         }
     993                 : 
     994                 :         if (buf == NULL) {
     995                 :                 buf = estrdup(sysbuf);
     996                 :         } else {
     997                 :                 strncpy(buf, sysbuf, bufsize);
     998                 :         }
     999                 : 
    1000                 :         if (free_it) {
    1001                 :                 LocalFree(sysbuf);
    1002                 :         }
    1003                 : 
    1004                 :         return buf;
    1005                 : #endif
    1006                 : }
    1007                 : /* }}} */
    1008                 : 
    1009                 : /* deprecated */
    1010                 : PHPAPI php_stream *_php_stream_sock_open_from_socket(php_socket_t socket, const char *persistent_id STREAMS_DC TSRMLS_DC)
    1011              12 : {
    1012                 :         php_stream *stream;
    1013                 :         php_netstream_data_t *sock;
    1014                 : 
    1015              12 :         sock = pemalloc(sizeof(php_netstream_data_t), persistent_id ? 1 : 0);
    1016              12 :         memset(sock, 0, sizeof(php_netstream_data_t));
    1017                 : 
    1018              12 :         sock->is_blocked = 1;
    1019              12 :         sock->timeout.tv_sec = FG(default_socket_timeout);
    1020              12 :         sock->timeout.tv_usec = 0;
    1021              12 :         sock->socket = socket;
    1022                 : 
    1023              12 :         stream = php_stream_alloc_rel(&php_stream_generic_socket_ops, sock, persistent_id, "r+");
    1024                 : 
    1025              12 :         if (stream == NULL) {
    1026               0 :                 pefree(sock, persistent_id ? 1 : 0);
    1027                 :         } else {
    1028              12 :                 stream->flags |= PHP_STREAM_FLAG_AVOID_BLOCKING;
    1029                 :         }
    1030                 : 
    1031              12 :         return stream;
    1032                 : }
    1033                 : 
    1034                 : PHPAPI php_stream *_php_stream_sock_open_host(const char *host, unsigned short port,
    1035                 :                 int socktype, struct timeval *timeout, const char *persistent_id STREAMS_DC TSRMLS_DC)
    1036               0 : {
    1037                 :         char *res;
    1038                 :         long reslen;
    1039                 :         php_stream *stream;
    1040                 : 
    1041               0 :         reslen = spprintf(&res, 0, "tcp://%s:%d", host, port);
    1042                 : 
    1043               0 :         stream = php_stream_xport_create(res, reslen, ENFORCE_SAFE_MODE | REPORT_ERRORS,
    1044                 :                         STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT, persistent_id, timeout, NULL, NULL, NULL);
    1045                 : 
    1046               0 :         efree(res);
    1047                 : 
    1048               0 :         return stream;
    1049                 : }
    1050                 : 
    1051                 : PHPAPI int php_set_sock_blocking(int socketd, int block TSRMLS_DC)
    1052              16 : {
    1053              16 :         int ret = SUCCESS;
    1054                 :         int flags;
    1055              16 :         int myflag = 0;
    1056                 : 
    1057                 : #ifdef PHP_WIN32
    1058                 :         /* with ioctlsocket, a non-zero sets nonblocking, a zero sets blocking */
    1059                 :         flags = !block;
    1060                 :         if (ioctlsocket(socketd, FIONBIO, &flags) == SOCKET_ERROR) {
    1061                 :                 char *error_string;
    1062                 :                 
    1063                 :                 error_string = php_socket_strerror(WSAGetLastError(), NULL, 0);
    1064                 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", error_string);
    1065                 :                 efree(error_string);
    1066                 :                 ret = FAILURE;
    1067                 :         }
    1068                 : #else
    1069              16 :         flags = fcntl(socketd, F_GETFL);
    1070                 : #ifdef O_NONBLOCK
    1071              16 :         myflag = O_NONBLOCK; /* POSIX version */
    1072                 : #elif defined(O_NDELAY)
    1073                 :         myflag = O_NDELAY;   /* old non-POSIX version */
    1074                 : #endif
    1075              16 :         if (!block) {
    1076              10 :                 flags |= myflag;
    1077                 :         } else {
    1078               6 :                 flags &= ~myflag;
    1079                 :         }
    1080              16 :         fcntl(socketd, F_SETFL, flags);
    1081                 : #endif
    1082              16 :         return ret;
    1083                 : }
    1084                 : 
    1085                 : PHPAPI void _php_emit_fd_setsize_warning(int max_fd)
    1086               0 : {
    1087                 :         TSRMLS_FETCH();
    1088                 : 
    1089                 : #ifdef PHP_WIN32
    1090                 :         php_error_docref(NULL TSRMLS_CC, E_WARNING,
    1091                 :                 "PHP needs to be recompiled with a larger value of FD_SETSIZE.\n"
    1092                 :                 "If this binary is from an official www.php.net package, file a bug report\n"
    1093                 :                 "at http://bugs.php.net, including the following information:\n"
    1094                 :                 "FD_SETSIZE=%d, but you are using %d.\n"
    1095                 :                 " --enable-fd-setsize=%d is recommended, but you may want to set it\n"
    1096                 :                 "to match to maximum number of sockets each script will work with at\n"
    1097                 :                 "one time, in order to avoid seeing this error again at a later date.",
    1098                 :                 FD_SETSIZE, max_fd, (max_fd + 128) & ~127);
    1099                 : #else
    1100               0 :         php_error_docref(NULL TSRMLS_CC, E_WARNING,
    1101                 :                 "You MUST recompile PHP with a larger value of FD_SETSIZE.\n"
    1102                 :                 "It is set to %d, but you have descriptors numbered at least as high as %d.\n"
    1103                 :                 " --enable-fd-setsize=%d is recommended, but you may want to set it\n"
    1104                 :                 "to equal the maximum number of open files supported by your system,\n"
    1105                 :                 "in order to avoid seeing this error again at a later date.",
    1106                 :                 FD_SETSIZE, max_fd, (max_fd + 1024) & ~1023);
    1107                 : #endif
    1108               0 : }
    1109                 : 
    1110                 : #if defined(PHP_USE_POLL_2_EMULATION)
    1111                 : 
    1112                 : /* emulate poll(2) using select(2), safely. */
    1113                 : 
    1114                 : PHPAPI int php_poll2(php_pollfd *ufds, unsigned int nfds, int timeout)
    1115                 : {
    1116                 :         fd_set rset, wset, eset;
    1117                 :         php_socket_t max_fd = SOCK_ERR;
    1118                 :         unsigned int i, n;
    1119                 :         struct timeval tv;
    1120                 : 
    1121                 :         /* check the highest numbered descriptor */
    1122                 :         for (i = 0; i < nfds; i++) {
    1123                 :                 if (ufds[i].fd > max_fd)
    1124                 :                         max_fd = ufds[i].fd;
    1125                 :         }
    1126                 : 
    1127                 :         PHP_SAFE_MAX_FD(max_fd, nfds + 1);
    1128                 : 
    1129                 :         FD_ZERO(&rset);
    1130                 :         FD_ZERO(&wset);
    1131                 :         FD_ZERO(&eset);
    1132                 : 
    1133                 :         for (i = 0; i < nfds; i++) {
    1134                 :                 if (ufds[i].events & PHP_POLLREADABLE) {
    1135                 :                         PHP_SAFE_FD_SET(ufds[i].fd, &rset);
    1136                 :                 }
    1137                 :                 if (ufds[i].events & POLLOUT) {
    1138                 :                         PHP_SAFE_FD_SET(ufds[i].fd, &wset);
    1139                 :                 }
    1140                 :                 if (ufds[i].events & POLLPRI) {
    1141                 :                         PHP_SAFE_FD_SET(ufds[i].fd, &eset);
    1142                 :                 }
    1143                 :         }
    1144                 : 
    1145                 :         if (timeout >= 0) {
    1146                 :                 tv.tv_sec = timeout / 1000;
    1147                 :                 tv.tv_usec = (timeout - (tv.tv_sec * 1000)) * 1000;
    1148                 :         }
    1149                 : /* Reseting/initializing */
    1150                 : #ifdef PHP_WIN32
    1151                 :         WSASetLastError(0);
    1152                 : #else
    1153                 :         errno = 0;
    1154                 : #endif
    1155                 :         n = select(max_fd + 1, &rset, &wset, &eset, timeout >= 0 ? &tv : NULL);
    1156                 : 
    1157                 :         if (n >= 0) {
    1158                 :                 for (i = 0; i < nfds; i++) {
    1159                 :                         ufds[i].revents = 0;
    1160                 : 
    1161                 :                         if (PHP_SAFE_FD_ISSET(ufds[i].fd, &rset)) {
    1162                 :                                 /* could be POLLERR or POLLHUP but can't tell without probing */
    1163                 :                                 ufds[i].revents |= POLLIN;
    1164                 :                         }
    1165                 :                         if (PHP_SAFE_FD_ISSET(ufds[i].fd, &wset)) {
    1166                 :                                 ufds[i].revents |= POLLOUT;
    1167                 :                         }
    1168                 :                         if (PHP_SAFE_FD_ISSET(ufds[i].fd, &eset)) {
    1169                 :                                 ufds[i].revents |= POLLPRI;
    1170                 :                         }
    1171                 :                 }
    1172                 :         }
    1173                 :         return n;
    1174                 : }
    1175                 : 
    1176                 : #endif
    1177                 : 
    1178                 : 
    1179                 : /*
    1180                 :  * Local variables:
    1181                 :  * tab-width: 8
    1182                 :  * c-basic-offset: 8
    1183                 :  * End:
    1184                 :  * vim600: sw=4 ts=4 fdm=marker
    1185                 :  * vim<600: sw=4 ts=4
    1186                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Thu, 19 Nov 2009 08:20:28 +0000 (5 days ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.