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 - standard - streamsfuncs.c
Test: PHP Code Coverage
Date: 2009-11-21 Instrumented lines: 655
Code covered: 72.4 % Executed lines: 474
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                 :   | Authors: Wez Furlong <wez@thebrainroom.com>                          |
      16                 :   |          Sara Golemon <pollita@php.net>                              |
      17                 :   +----------------------------------------------------------------------+
      18                 : */
      19                 : 
      20                 : /* $Id: streamsfuncs.c 286744 2009-08-03 15:58:18Z felipe $ */
      21                 : 
      22                 : #include "php.h"
      23                 : #include "php_globals.h"
      24                 : #include "ext/standard/flock_compat.h"
      25                 : #include "ext/standard/file.h"
      26                 : #include "ext/standard/php_filestat.h"
      27                 : #include "php_open_temporary_file.h"
      28                 : #include "ext/standard/basic_functions.h"
      29                 : #include "php_ini.h"
      30                 : #include "streamsfuncs.h"
      31                 : #include "php_network.h"
      32                 : #include "php_string.h"
      33                 : 
      34                 : #ifndef PHP_WIN32
      35                 : #define php_select(m, r, w, e, t)       select(m, r, w, e, t)
      36                 : typedef unsigned long long php_timeout_ull;
      37                 : #else
      38                 : #include "win32/select.h"
      39                 : #include "win32/sockets.h"
      40                 : typedef unsigned __int64 php_timeout_ull;
      41                 : #endif
      42                 : 
      43                 : static php_stream_context *decode_context_param(zval *contextresource TSRMLS_DC);
      44                 : 
      45                 : /* Streams based network functions */
      46                 : 
      47                 : #if HAVE_SOCKETPAIR
      48                 : /* {{{ proto array stream_socket_pair(int domain, int type, int protocol)
      49                 :    Creates a pair of connected, indistinguishable socket streams */
      50                 : PHP_FUNCTION(stream_socket_pair)
      51               6 : {
      52                 :         long domain, type, protocol;
      53                 :         php_stream *s1, *s2;
      54                 :         int pair[2];
      55                 : 
      56               6 :         if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lll",
      57                 :                         &domain, &type, &protocol)) {
      58               0 :                 RETURN_FALSE;
      59                 :         }
      60                 : 
      61               6 :         if (0 != socketpair(domain, type, protocol, pair)) {
      62                 :                 char errbuf[256];
      63               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to create sockets: [%d]: %s",
      64                 :                         php_socket_errno(), php_socket_strerror(php_socket_errno(), errbuf, sizeof(errbuf)));
      65               0 :                 RETURN_FALSE;
      66                 :         }
      67                 : 
      68               6 :         array_init(return_value);
      69                 : 
      70               6 :         s1 = php_stream_sock_open_from_socket(pair[0], 0);
      71               6 :         s2 = php_stream_sock_open_from_socket(pair[1], 0);
      72                 : 
      73                 :         /* set the __exposed flag. 
      74                 :          * php_stream_to_zval() does, add_next_index_resource() does not */
      75                 :         php_stream_auto_cleanup(s1);
      76                 :         php_stream_auto_cleanup(s2);
      77                 : 
      78               6 :         add_next_index_resource(return_value, php_stream_get_resource_id(s1));
      79               6 :         add_next_index_resource(return_value, php_stream_get_resource_id(s2));
      80                 : }
      81                 : /* }}} */
      82                 : #endif
      83                 : 
      84                 : /* {{{ proto resource stream_socket_client(string remoteaddress [, long &errcode [, string &errstring [, double timeout [, long flags [, resource context]]]]])
      85                 :    Open a client connection to a remote address */
      86                 : PHP_FUNCTION(stream_socket_client)
      87              37 : {
      88                 :         char *host;
      89                 :         int host_len;
      90              37 :         zval *zerrno = NULL, *zerrstr = NULL, *zcontext = NULL;
      91              37 :         double timeout = FG(default_socket_timeout);
      92                 :         php_timeout_ull conv;
      93                 :         struct timeval tv;
      94              37 :         char *hashkey = NULL;
      95              37 :         php_stream *stream = NULL;
      96                 :         int err;
      97              37 :         long flags = PHP_STREAM_CLIENT_CONNECT;
      98              37 :         char *errstr = NULL;
      99              37 :         php_stream_context *context = NULL;
     100                 : 
     101              37 :         RETVAL_FALSE;
     102                 :         
     103              37 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|zzdlr", &host, &host_len, &zerrno, &zerrstr, &timeout, &flags, &zcontext) == FAILURE) {
     104               1 :                 RETURN_FALSE;
     105                 :         }
     106                 :         
     107              36 :         context = php_stream_context_from_zval(zcontext, flags & PHP_FILE_NO_DEFAULT_CONTEXT);
     108                 : 
     109              36 :         if (context) {
     110              36 :                 zend_list_addref(context->rsrc_id);
     111                 :         }
     112                 : 
     113              36 :         if (flags & PHP_STREAM_CLIENT_PERSISTENT) {
     114               0 :                 spprintf(&hashkey, 0, "stream_socket_client__%s", host);
     115                 :         }
     116                 :         
     117                 :         /* prepare the timeout value for use */
     118              36 :         conv = (php_timeout_ull) (timeout * 1000000.0);
     119              36 :         tv.tv_sec = conv / 1000000;
     120              36 :         tv.tv_usec = conv % 1000000;
     121                 : 
     122              36 :         if (zerrno)     {
     123              10 :                 zval_dtor(zerrno);
     124              10 :                 ZVAL_LONG(zerrno, 0);
     125                 :         }
     126              36 :         if (zerrstr) {
     127               6 :                 zval_dtor(zerrstr);
     128               6 :                 ZVAL_STRING(zerrstr, "", 1);
     129                 :         }
     130                 : 
     131              36 :         stream = php_stream_xport_create(host, host_len, ENFORCE_SAFE_MODE | REPORT_ERRORS,
     132                 :                         STREAM_XPORT_CLIENT | (flags & PHP_STREAM_CLIENT_CONNECT ? STREAM_XPORT_CONNECT : 0) |
     133                 :                         (flags & PHP_STREAM_CLIENT_ASYNC_CONNECT ? STREAM_XPORT_CONNECT_ASYNC : 0),
     134                 :                         hashkey, &tv, context, &errstr, &err);
     135                 :                 
     136                 : 
     137              36 :         if (stream == NULL) {
     138                 :                 /* host might contain binary characters */
     139               9 :                 char *quoted_host = php_addslashes(host, host_len, NULL, 0 TSRMLS_CC);
     140                 :                 
     141               9 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to connect to %s (%s)", quoted_host, errstr == NULL ? "Unknown error" : errstr);
     142               9 :                 efree(quoted_host);
     143                 :         }
     144                 : 
     145              36 :         if (hashkey) {
     146               0 :                 efree(hashkey);
     147                 :         }
     148                 :         
     149              36 :         if (stream == NULL)     {
     150               9 :                 if (zerrno) {
     151               9 :                         zval_dtor(zerrno);
     152               9 :                         ZVAL_LONG(zerrno, err);
     153                 :                 }
     154              14 :                 if (zerrstr && errstr) {
     155                 :                         /* no need to dup; we need to efree buf anyway */
     156               5 :                         zval_dtor(zerrstr);
     157               5 :                         ZVAL_STRING(zerrstr, errstr, 0);
     158               4 :                 } else if (errstr) {
     159               4 :                         efree(errstr);
     160                 :                 }
     161               9 :                 RETURN_FALSE;
     162                 :         }
     163                 :         
     164              27 :         if (errstr) {
     165               0 :                 efree(errstr);
     166                 :         }
     167                 :         
     168              27 :         php_stream_to_zval(stream, return_value);
     169                 :         
     170                 : }
     171                 : /* }}} */
     172                 : 
     173                 : /* {{{ proto resource stream_socket_server(string localaddress [, long &errcode [, string &errstring [, long flags [, resource context]]]])
     174                 :    Create a server socket bound to localaddress */
     175                 : PHP_FUNCTION(stream_socket_server)
     176              68 : {
     177                 :         char *host;
     178                 :         int host_len;
     179              68 :         zval *zerrno = NULL, *zerrstr = NULL, *zcontext = NULL;
     180              68 :         php_stream *stream = NULL;
     181              68 :         int err = 0;
     182              68 :         long flags = STREAM_XPORT_BIND | STREAM_XPORT_LISTEN;
     183              68 :         char *errstr = NULL;
     184              68 :         php_stream_context *context = NULL;
     185                 : 
     186              68 :         RETVAL_FALSE;
     187                 :         
     188              68 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|zzlr", &host, &host_len, &zerrno, &zerrstr, &flags, &zcontext) == FAILURE) {
     189               0 :                 RETURN_FALSE;
     190                 :         }
     191                 :         
     192              68 :         context = php_stream_context_from_zval(zcontext, flags & PHP_FILE_NO_DEFAULT_CONTEXT);
     193                 :         
     194              68 :         if (context) {
     195              68 :                 zend_list_addref(context->rsrc_id);
     196                 :         }
     197                 : 
     198              68 :         if (zerrno)     {
     199              47 :                 zval_dtor(zerrno);
     200              47 :                 ZVAL_LONG(zerrno, 0);
     201                 :         }
     202              68 :         if (zerrstr) {
     203              47 :                 zval_dtor(zerrstr);
     204              47 :                 ZVAL_STRING(zerrstr, "", 1);
     205                 :         }
     206                 : 
     207              68 :         stream = php_stream_xport_create(host, host_len, ENFORCE_SAFE_MODE | REPORT_ERRORS,
     208                 :                         STREAM_XPORT_SERVER | flags,
     209                 :                         NULL, NULL, context, &errstr, &err);
     210                 :                         
     211              68 :         if (stream == NULL) {
     212               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to connect to %s (%s)", host, errstr == NULL ? "Unknown error" : errstr);
     213                 :         }
     214                 :         
     215              68 :         if (stream == NULL)     {
     216               0 :                 if (zerrno) {
     217               0 :                         zval_dtor(zerrno);
     218               0 :                         ZVAL_LONG(zerrno, err);
     219                 :                 }
     220               0 :                 if (zerrstr && errstr) {
     221                 :                         /* no need to dup; we need to efree buf anyway */
     222               0 :                         zval_dtor(zerrstr);
     223               0 :                         ZVAL_STRING(zerrstr, errstr, 0);
     224               0 :                 } else if (errstr) {
     225               0 :                         efree(errstr);
     226                 :                 }
     227               0 :                 RETURN_FALSE;
     228                 :         }
     229                 :         
     230              68 :         if (errstr) {
     231               0 :                 efree(errstr);
     232                 :         }
     233                 :         
     234              68 :         php_stream_to_zval(stream, return_value);
     235                 : }
     236                 : /* }}} */
     237                 : 
     238                 : /* {{{ proto resource stream_socket_accept(resource serverstream, [ double timeout [, string &peername ]])
     239                 :    Accept a client connection from a server socket */
     240                 : PHP_FUNCTION(stream_socket_accept)
     241              41 : {
     242              41 :         double timeout = FG(default_socket_timeout);
     243              41 :         zval *zpeername = NULL;
     244              41 :         char *peername = NULL;
     245                 :         int peername_len;
     246                 :         php_timeout_ull conv;
     247                 :         struct timeval tv;
     248              41 :         php_stream *stream = NULL, *clistream = NULL;
     249                 :         zval *zstream;
     250                 : 
     251              41 :         char *errstr = NULL;
     252                 :         
     253              41 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|dz", &zstream, &timeout, &zpeername) == FAILURE) {
     254               0 :                 RETURN_FALSE;
     255                 :         }
     256                 :         
     257              41 :         php_stream_from_zval(stream, &zstream);
     258                 :         
     259                 :         /* prepare the timeout value for use */
     260              41 :         conv = (php_timeout_ull) (timeout * 1000000.0);
     261              41 :         tv.tv_sec = conv / 1000000;
     262              41 :         tv.tv_usec = conv % 1000000;
     263                 : 
     264              41 :         if (zpeername) {
     265               0 :                 zval_dtor(zpeername);
     266               0 :                 ZVAL_NULL(zpeername);
     267                 :         }
     268                 : 
     269              82 :         if (0 == php_stream_xport_accept(stream, &clistream,
     270                 :                                 zpeername ? &peername : NULL,
     271                 :                                 zpeername ? &peername_len : NULL,
     272                 :                                 NULL, NULL,
     273                 :                                 &tv, &errstr
     274                 :                                 TSRMLS_CC) && clistream) {
     275                 :                 
     276              41 :                 if (peername) {
     277               0 :                         ZVAL_STRINGL(zpeername, peername, peername_len, 0);
     278                 :                 }
     279              41 :                 php_stream_to_zval(clistream, return_value);
     280                 :         } else {
     281               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "accept failed: %s", errstr ? errstr : "Unknown error");
     282               0 :                 RETVAL_FALSE;
     283                 :         }
     284                 : 
     285              41 :         if (errstr) {
     286              41 :                 efree(errstr);
     287                 :         }
     288                 : }
     289                 : /* }}} */
     290                 : 
     291                 : /* {{{ proto string stream_socket_get_name(resource stream, bool want_peer)
     292                 :    Returns either the locally bound or remote name for a socket stream */
     293                 : PHP_FUNCTION(stream_socket_get_name)
     294               0 : {
     295                 :         php_stream *stream;
     296                 :         zval *zstream;
     297                 :         zend_bool want_peer;
     298               0 :         char *name = NULL;
     299                 :         int name_len;
     300                 :         
     301               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rb", &zstream, &want_peer) == FAILURE) {
     302               0 :                 RETURN_FALSE;
     303                 :         }
     304                 :         
     305               0 :         php_stream_from_zval(stream, &zstream);
     306                 : 
     307               0 :         if (0 != php_stream_xport_get_name(stream, want_peer,
     308                 :                                 &name,
     309                 :                                 &name_len,
     310                 :                                 NULL, NULL
     311                 :                                 TSRMLS_CC)) {
     312               0 :                 RETURN_FALSE;
     313                 :         }
     314                 : 
     315               0 :         RETURN_STRINGL(name, name_len, 0);
     316                 : }
     317                 : /* }}} */
     318                 : 
     319                 : /* {{{ proto long stream_socket_sendto(resouce stream, string data [, long flags [, string target_addr]])
     320                 :    Send data to a socket stream.  If target_addr is specified it must be in dotted quad (or [ipv6]) format */
     321                 : PHP_FUNCTION(stream_socket_sendto)
     322               0 : {
     323                 :         php_stream *stream;
     324                 :         zval *zstream;
     325               0 :         long flags = 0;
     326               0 :         char *data, *target_addr = NULL;
     327               0 :         int datalen, target_addr_len = 0;
     328                 :         php_sockaddr_storage sa;
     329               0 :         socklen_t sl = 0;
     330                 :         
     331               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|ls", &zstream, &data, &datalen, &flags, &target_addr, &target_addr_len) == FAILURE) {
     332               0 :                 RETURN_FALSE;
     333                 :         }
     334               0 :         php_stream_from_zval(stream, &zstream);
     335                 : 
     336               0 :         if (target_addr_len) {
     337                 :                 /* parse the address */
     338               0 :                 if (FAILURE == php_network_parse_network_address_with_port(target_addr, target_addr_len, (struct sockaddr*)&sa, &sl TSRMLS_CC)) {
     339               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse `%s' into a valid network address", target_addr);
     340               0 :                         RETURN_FALSE;
     341                 :                 }
     342                 :         }
     343                 : 
     344               0 :         RETURN_LONG(php_stream_xport_sendto(stream, data, datalen, flags, target_addr ? &sa : NULL, sl TSRMLS_CC));
     345                 : }
     346                 : /* }}} */
     347                 : 
     348                 : /* {{{ proto string stream_socket_recvfrom(resource stream, long amount [, long flags [, string &remote_addr]])
     349                 :    Receives data from a socket stream */
     350                 : PHP_FUNCTION(stream_socket_recvfrom)
     351               0 : {
     352                 :         php_stream *stream;
     353               0 :         zval *zstream, *zremote = NULL;
     354               0 :         char *remote_addr = NULL;
     355                 :         int remote_addr_len;
     356               0 :         long to_read = 0;
     357                 :         char *read_buf;
     358               0 :         long flags = 0;
     359                 :         int recvd;
     360                 :         
     361               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|lz", &zstream, &to_read, &flags, &zremote) == FAILURE) {
     362               0 :                 RETURN_FALSE;
     363                 :         }
     364                 :         
     365               0 :         php_stream_from_zval(stream, &zstream);
     366                 : 
     367               0 :         if (zremote) {
     368               0 :                 zval_dtor(zremote);
     369               0 :                 ZVAL_NULL(zremote);
     370                 :         }
     371                 : 
     372               0 :         if (to_read <= 0) {
     373               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than 0");
     374               0 :                 RETURN_FALSE;
     375                 :         }
     376                 :         
     377               0 :         read_buf = safe_emalloc(1, to_read, 1);
     378                 :         
     379               0 :         recvd = php_stream_xport_recvfrom(stream, read_buf, to_read, flags, NULL, NULL,
     380                 :                         zremote ? &remote_addr : NULL,
     381                 :                         zremote ? &remote_addr_len : NULL
     382                 :                         TSRMLS_CC);
     383                 : 
     384               0 :         if (recvd >= 0) {
     385               0 :                 if (zremote) {
     386               0 :                         ZVAL_STRINGL(zremote, remote_addr, remote_addr_len, 0);
     387                 :                 }
     388               0 :                 read_buf[recvd] = '\0';
     389                 : 
     390               0 :                 if (PG(magic_quotes_runtime)) {
     391               0 :                         Z_TYPE_P(return_value) = IS_STRING;
     392               0 :                         Z_STRVAL_P(return_value) = php_addslashes(Z_STRVAL_P(return_value), Z_STRLEN_P(return_value), &Z_STRLEN_P(return_value), 1 TSRMLS_CC);
     393               0 :                         return;
     394                 :                 } else {
     395               0 :                         RETURN_STRINGL(read_buf, recvd, 0);
     396                 :                 }
     397                 :         }
     398                 : 
     399               0 :         efree(read_buf);
     400               0 :         RETURN_FALSE;
     401                 : }
     402                 : /* }}} */
     403                 : 
     404                 : /* {{{ proto string stream_get_contents(resource source [, long maxlen [, long offset]])
     405                 :    Reads all remaining bytes (or up to maxlen bytes) from a stream and returns them as a string. */
     406                 : PHP_FUNCTION(stream_get_contents)
     407              97 : {
     408                 :         php_stream *stream;
     409                 :         zval *zsrc;
     410              97 :         long maxlen = PHP_STREAM_COPY_ALL, pos = 0;
     411                 :         int len, newlen;
     412              97 :         char *contents = NULL;
     413                 : 
     414              97 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|ll", &zsrc, &maxlen, &pos) == FAILURE) {
     415               2 :                 RETURN_FALSE;
     416                 :         }
     417                 : 
     418              95 :         php_stream_from_zval(stream, &zsrc);
     419                 : 
     420              95 :         if ((pos > 0 || (pos == 0 && ZEND_NUM_ARGS() > 2)) && php_stream_seek(stream, pos, SEEK_SET) < 0) {
     421               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to seek to position %ld in the stream", pos);
     422               0 :                 RETURN_FALSE;
     423                 :         }
     424                 : 
     425              95 :         len = php_stream_copy_to_mem(stream, &contents, maxlen, 0);
     426                 :         
     427              95 :         if (contents) {
     428              71 :                 if (len && PG(magic_quotes_runtime)) {
     429               0 :                         contents = php_addslashes(contents, len, &newlen, 1 TSRMLS_CC); /* 1 = free source string */
     430               0 :                         len = newlen;
     431                 :                 }
     432              71 :                 RETVAL_STRINGL(contents, len, 0);
     433                 :         } else {
     434              24 :                 RETVAL_EMPTY_STRING();
     435                 :         }
     436                 : }
     437                 : /* }}} */
     438                 : 
     439                 : /* {{{ proto long stream_copy_to_stream(resource source, resource dest [, long maxlen [, long pos]])
     440                 :    Reads up to maxlen bytes from source stream and writes them to dest stream. */
     441                 : PHP_FUNCTION(stream_copy_to_stream)
     442              15 : {
     443                 :         php_stream *src, *dest;
     444                 :         zval *zsrc, *zdest;
     445              15 :         long maxlen = PHP_STREAM_COPY_ALL, pos = 0;
     446                 :         size_t len;
     447                 :         int ret;
     448                 : 
     449              15 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr|ll", &zsrc, &zdest, &maxlen, &pos) == FAILURE) {
     450               0 :                 RETURN_FALSE;
     451                 :         }
     452                 : 
     453              15 :         php_stream_from_zval(src, &zsrc);
     454              15 :         php_stream_from_zval(dest, &zdest);
     455                 : 
     456              15 :         if (pos > 0 && php_stream_seek(src, pos, SEEK_SET) < 0) {
     457               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to seek to position %ld in the stream", pos);
     458               0 :                 RETURN_FALSE;
     459                 :         }
     460                 : 
     461              15 :         ret = php_stream_copy_to_stream_ex(src, dest, maxlen, &len);
     462                 : 
     463              15 :         if (ret != SUCCESS) {
     464               2 :                 RETURN_FALSE;
     465                 :         }
     466              13 :         RETURN_LONG(len);
     467                 : }
     468                 : /* }}} */
     469                 : 
     470                 : /* {{{ proto array stream_get_meta_data(resource fp)
     471                 :     Retrieves header/meta data from streams/file pointers */
     472                 : PHP_FUNCTION(stream_get_meta_data)
     473             109 : {
     474                 :         zval *arg1;
     475                 :         php_stream *stream;
     476                 :         zval *newval;
     477                 : 
     478             109 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
     479              10 :                 return;
     480                 :         }
     481              99 :         php_stream_from_zval(stream, &arg1);
     482                 : 
     483              98 :         array_init(return_value);
     484                 :         
     485              98 :         if (stream->wrapperdata) {
     486              37 :                 MAKE_STD_ZVAL(newval);
     487              37 :                 *newval = *(stream->wrapperdata);
     488              37 :                 zval_copy_ctor(newval);
     489              37 :                 INIT_PZVAL(newval);
     490                 : 
     491              37 :                 add_assoc_zval(return_value, "wrapper_data", newval);
     492                 :         }
     493              98 :         if (stream->wrapper) {
     494              80 :                 add_assoc_string(return_value, "wrapper_type", (char *)stream->wrapper->wops->label, 1);
     495                 :         }
     496              98 :         add_assoc_string(return_value, "stream_type", (char *)stream->ops->label, 1);
     497                 : 
     498              98 :         add_assoc_string(return_value, "mode", stream->mode, 1);
     499                 :         
     500                 : #if 0   /* TODO: needs updating for new filter API */
     501                 :         if (stream->filterhead) {
     502                 :                 php_stream_filter *filter;
     503                 :                 
     504                 :                 MAKE_STD_ZVAL(newval);
     505                 :                 array_init(newval);
     506                 :                 
     507                 :                 for (filter = stream->filterhead; filter != NULL; filter = filter->next) {
     508                 :                         add_next_index_string(newval, (char *)filter->fops->label, 1);
     509                 :                 }
     510                 : 
     511                 :                 add_assoc_zval(return_value, "filters", newval);
     512                 :         }
     513                 : #endif
     514                 :         
     515              98 :         add_assoc_long(return_value, "unread_bytes", stream->writepos - stream->readpos);
     516                 : 
     517              98 :         add_assoc_bool(return_value, "seekable", (stream->ops->seek) && (stream->flags & PHP_STREAM_FLAG_NO_SEEK) == 0);
     518              98 :         if (stream->orig_path) {
     519              78 :                 add_assoc_string(return_value, "uri", stream->orig_path, 1);
     520                 :         }
     521                 : 
     522              98 :         if (!php_stream_populate_meta_data(stream, return_value)) {
     523              76 :                 add_assoc_bool(return_value, "timed_out", 0);
     524              76 :                 add_assoc_bool(return_value, "blocked", 1);
     525              76 :                 add_assoc_bool(return_value, "eof", php_stream_eof(stream));
     526                 :         }
     527                 : 
     528                 : }
     529                 : /* }}} */
     530                 : 
     531                 : /* {{{ proto array stream_get_transports()
     532                 :    Retrieves list of registered socket transports */
     533                 : PHP_FUNCTION(stream_get_transports)
     534               2 : {
     535                 :         HashTable *stream_xport_hash;
     536                 :         char *stream_xport;
     537                 :         int stream_xport_len;
     538                 :         ulong num_key;
     539                 : 
     540               2 :         if (zend_parse_parameters_none() == FAILURE) {
     541               0 :                 return;
     542                 :         }
     543                 : 
     544               2 :         if ((stream_xport_hash = php_stream_xport_get_hash())) {
     545                 :                 HashPosition pos;
     546               2 :                 array_init(return_value);
     547               2 :                 zend_hash_internal_pointer_reset_ex(stream_xport_hash, &pos);
     548              20 :                 while (zend_hash_get_current_key_ex(stream_xport_hash,
     549                 :                                         &stream_xport, &stream_xport_len,
     550                 :                                         &num_key, 0, &pos) == HASH_KEY_IS_STRING) {
     551              16 :                         add_next_index_stringl(return_value, stream_xport, stream_xport_len - 1, 1);
     552              16 :                         zend_hash_move_forward_ex(stream_xport_hash, &pos);
     553                 :                 }
     554                 :         } else {
     555               0 :                 RETURN_FALSE;
     556                 :         }
     557                 : }
     558                 : /* }}} */
     559                 : 
     560                 : /* {{{ proto array stream_get_wrappers()
     561                 :     Retrieves list of registered stream wrappers */
     562                 : PHP_FUNCTION(stream_get_wrappers)
     563               4 : {
     564                 :         HashTable *url_stream_wrappers_hash;
     565                 :         char *stream_protocol;
     566               4 :         int key_flags, stream_protocol_len = 0;
     567                 :         ulong num_key;
     568                 : 
     569               4 :         if (zend_parse_parameters_none() == FAILURE) {
     570               0 :                 return;
     571                 :         }
     572                 : 
     573               4 :         if ((url_stream_wrappers_hash = php_stream_get_url_stream_wrappers_hash())) {
     574                 :                 HashPosition pos;
     575               4 :                 array_init(return_value);
     576               4 :                 for (zend_hash_internal_pointer_reset_ex(url_stream_wrappers_hash, &pos);
     577              72 :                         (key_flags = zend_hash_get_current_key_ex(url_stream_wrappers_hash, &stream_protocol, &stream_protocol_len, &num_key, 0, &pos)) != HASH_KEY_NON_EXISTANT;
     578              64 :                         zend_hash_move_forward_ex(url_stream_wrappers_hash, &pos)) {
     579              64 :                                 if (key_flags == HASH_KEY_IS_STRING) {
     580              64 :                                         add_next_index_stringl(return_value, stream_protocol, stream_protocol_len - 1, 1);
     581                 :                                 }
     582                 :                 }
     583                 :         } else {
     584               0 :                 RETURN_FALSE;
     585                 :         }
     586                 : 
     587                 : }
     588                 : /* }}} */
     589                 : 
     590                 : /* {{{ stream_select related functions */
     591                 : static int stream_array_to_fd_set(zval *stream_array, fd_set *fds, php_socket_t *max_fd TSRMLS_DC)
     592          711956 : {
     593                 :         zval **elem;
     594                 :         php_stream *stream;
     595                 :         php_socket_t this_fd;
     596          711956 :         int cnt = 0;
     597                 : 
     598          711956 :         if (Z_TYPE_P(stream_array) != IS_ARRAY) {
     599               0 :                 return 0;
     600                 :         }
     601          711956 :         for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(stream_array));
     602         3559734 :                  zend_hash_get_current_data(Z_ARRVAL_P(stream_array), (void **) &elem) == SUCCESS;
     603         2135822 :                  zend_hash_move_forward(Z_ARRVAL_P(stream_array))) {
     604                 : 
     605         2135822 :                 php_stream_from_zval_no_verify(stream, elem);
     606         2135822 :                 if (stream == NULL) {
     607          711936 :                         continue;
     608                 :                 }
     609                 :                 /* get the fd.
     610                 :                  * NB: Most other code will NOT use the PHP_STREAM_CAST_INTERNAL flag
     611                 :                  * when casting.  It is only used here so that the buffered data warning
     612                 :                  * is not displayed.
     613                 :                  * */
     614         1423886 :                 if (SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)&this_fd, 1) && this_fd >= 0) {
     615                 :                         
     616         1423881 :                         PHP_SAFE_FD_SET(this_fd, fds);
     617                 : 
     618         1423881 :                         if (this_fd > *max_fd) {
     619         1423878 :                                 *max_fd = this_fd;
     620                 :                         }
     621         1423881 :                         cnt++;
     622                 :                 }
     623                 :         }
     624          711956 :         return cnt ? 1 : 0;
     625                 : }
     626                 : 
     627                 : static int stream_array_from_fd_set(zval *stream_array, fd_set *fds TSRMLS_DC)
     628          711949 : {
     629                 :         zval **elem, **dest_elem;
     630                 :         php_stream *stream;
     631                 :         HashTable *new_hash;
     632                 :         php_socket_t this_fd;
     633          711949 :         int ret = 0;
     634                 : 
     635          711949 :         if (Z_TYPE_P(stream_array) != IS_ARRAY) {
     636               0 :                 return 0;
     637                 :         }
     638          711949 :         ALLOC_HASHTABLE(new_hash);
     639          711949 :         zend_hash_init(new_hash, zend_hash_num_elements(Z_ARRVAL_P(stream_array)), NULL, ZVAL_PTR_DTOR, 0);
     640                 :         
     641          711949 :         for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(stream_array));
     642         3559713 :                  zend_hash_get_current_data(Z_ARRVAL_P(stream_array), (void **) &elem) == SUCCESS;
     643         2135815 :                  zend_hash_move_forward(Z_ARRVAL_P(stream_array))) {
     644                 : 
     645         2135815 :                 php_stream_from_zval_no_verify(stream, elem);
     646         2135815 :                 if (stream == NULL) {
     647          711936 :                         continue;
     648                 :                 }
     649                 :                 /* get the fd 
     650                 :                  * NB: Most other code will NOT use the PHP_STREAM_CAST_INTERNAL flag
     651                 :                  * when casting.  It is only used here so that the buffered data warning
     652                 :                  * is not displayed.
     653                 :                  */
     654         1423879 :                 if (SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)&this_fd, 1) && this_fd >= 0) {
     655         1423879 :                         if (PHP_SAFE_FD_ISSET(this_fd, fds)) {
     656          729376 :                                 zend_hash_next_index_insert(new_hash, (void *)elem, sizeof(zval *), (void **)&dest_elem);
     657          729376 :                                 if (dest_elem) {
     658          729376 :                                         zval_add_ref(dest_elem);
     659                 :                                 }
     660          729376 :                                 ret++;
     661          729376 :                                 continue;
     662                 :                         }
     663                 :                 }
     664                 :         }
     665                 : 
     666                 :         /* destroy old array and add new one */
     667          711949 :         zend_hash_destroy(Z_ARRVAL_P(stream_array));
     668          711949 :         efree(Z_ARRVAL_P(stream_array));
     669                 : 
     670          711949 :         zend_hash_internal_pointer_reset(new_hash);
     671          711949 :         Z_ARRVAL_P(stream_array) = new_hash;
     672                 :         
     673          711949 :         return ret;
     674                 : }
     675                 : 
     676                 : static int stream_array_emulate_read_fd_set(zval *stream_array TSRMLS_DC)
     677          711943 : {
     678                 :         zval **elem, **dest_elem;
     679                 :         php_stream *stream;
     680                 :         HashTable *new_hash;
     681          711943 :         int ret = 0;
     682                 : 
     683          711943 :         if (Z_TYPE_P(stream_array) != IS_ARRAY) {
     684               0 :                 return 0;
     685                 :         }
     686          711943 :         ALLOC_HASHTABLE(new_hash);
     687          711943 :         zend_hash_init(new_hash, zend_hash_num_elements(Z_ARRVAL_P(stream_array)), NULL, ZVAL_PTR_DTOR, 0);
     688                 :         
     689          711943 :         for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(stream_array));
     690         3559700 :                  zend_hash_get_current_data(Z_ARRVAL_P(stream_array), (void **) &elem) == SUCCESS;
     691         2135814 :                  zend_hash_move_forward(Z_ARRVAL_P(stream_array))) {
     692                 : 
     693         2135814 :                 php_stream_from_zval_no_verify(stream, elem);
     694         2135814 :                 if (stream == NULL) {
     695          711936 :                         continue;
     696                 :                 }
     697         1423878 :                 if ((stream->writepos - stream->readpos) > 0) {
     698                 :                         /* allow readable non-descriptor based streams to participate in stream_select.
     699                 :                          * Non-descriptor streams will only "work" if they have previously buffered the
     700                 :                          * data.  Not ideal, but better than nothing.
     701                 :                          * This branch of code also allows blocking streams with buffered data to
     702                 :                          * operate correctly in stream_select.
     703                 :                          * */
     704               1 :                         zend_hash_next_index_insert(new_hash, (void *)elem, sizeof(zval *), (void **)&dest_elem);
     705               1 :                         if (dest_elem) {
     706               1 :                                 zval_add_ref(dest_elem);
     707                 :                         }
     708               1 :                         ret++;
     709               1 :                         continue;
     710                 :                 }
     711                 :         }
     712                 : 
     713          711943 :         if (ret > 0) {
     714                 :                 /* destroy old array and add new one */
     715               1 :                 zend_hash_destroy(Z_ARRVAL_P(stream_array));
     716               1 :                 efree(Z_ARRVAL_P(stream_array));
     717                 : 
     718               1 :                 zend_hash_internal_pointer_reset(new_hash);
     719               1 :                 Z_ARRVAL_P(stream_array) = new_hash;
     720                 :         } else {
     721          711942 :                 zend_hash_destroy(new_hash);
     722          711942 :                 FREE_HASHTABLE(new_hash);
     723                 :         }
     724                 :         
     725          711943 :         return ret;
     726                 : }
     727                 : /* }}} */
     728                 : 
     729                 : /* {{{ proto int stream_select(array &read_streams, array &write_streams, array &except_streams, int tv_sec[, int tv_usec])
     730                 :    Runs the select() system call on the sets of streams with a timeout specified by tv_sec and tv_usec */
     731                 : PHP_FUNCTION(stream_select)
     732          711948 : {
     733          711948 :         zval                    *r_array, *w_array, *e_array, **sec = NULL;
     734                 :         struct timeval  tv;
     735          711948 :         struct timeval *tv_p = NULL;
     736                 :         fd_set                  rfds, wfds, efds;
     737          711948 :         php_socket_t    max_fd = 0;
     738          711948 :         int                             retval, sets = 0;
     739          711948 :         long                    usec = 0;
     740          711948 :         int                             set_count, max_set_count = 0;
     741                 : 
     742          711948 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a!a!a!Z!|l", &r_array, &w_array, &e_array, &sec, &usec) == FAILURE)
     743               0 :                 return;
     744                 : 
     745          711948 :         FD_ZERO(&rfds);
     746          711948 :         FD_ZERO(&wfds);
     747          711948 :         FD_ZERO(&efds);
     748                 : 
     749          711948 :         if (r_array != NULL) {
     750          711948 :                 set_count = stream_array_to_fd_set(r_array, &rfds, &max_fd TSRMLS_CC);
     751          711948 :                 if (set_count > max_set_count)
     752          711942 :                         max_set_count = set_count;
     753          711948 :                 sets += set_count;
     754                 :         }
     755                 :         
     756          711948 :         if (w_array != NULL) {
     757               5 :                 set_count = stream_array_to_fd_set(w_array, &wfds, &max_fd TSRMLS_CC);
     758               5 :                 if (set_count > max_set_count)
     759               1 :                         max_set_count = set_count;
     760               5 :                 sets += set_count;
     761                 :         }
     762                 : 
     763          711948 :         if (e_array != NULL) {
     764               3 :                 set_count = stream_array_to_fd_set(e_array, &efds, &max_fd TSRMLS_CC);
     765               3 :                 if (set_count > max_set_count)
     766               0 :                         max_set_count = set_count;
     767               3 :                 sets += set_count;
     768                 :         }
     769                 : 
     770          711948 :         if (!sets) {
     771               5 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No stream arrays were passed");
     772               5 :                 RETURN_FALSE;
     773                 :         }
     774                 : 
     775          711943 :         PHP_SAFE_MAX_FD(max_fd, max_set_count);
     776                 : 
     777                 :         /* If seconds is not set to null, build the timeval, else we wait indefinitely */
     778          711943 :         if (sec != NULL) {
     779          711943 :                 convert_to_long_ex(sec);
     780                 : 
     781          711943 :                 if (Z_LVAL_PP(sec) < 0) {
     782               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "The seconds parameter must be greater than 0");
     783               0 :                         RETURN_FALSE;
     784          711943 :                 } else if (usec < 0) {
     785               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "The microseconds parameter must be greater than 0");
     786               0 :                         RETURN_FALSE;
     787                 :                 }
     788                 : 
     789                 :                 /* Solaris + BSD do not like microsecond values which are >= 1 sec */
     790          711943 :                 if (usec > 999999) {
     791               0 :                         tv.tv_sec = Z_LVAL_PP(sec) + (usec / 1000000);
     792               0 :                         tv.tv_usec = usec % 1000000;                    
     793                 :                 } else {
     794          711943 :                         tv.tv_sec = Z_LVAL_PP(sec);
     795          711943 :                         tv.tv_usec = usec;
     796                 :                 }
     797                 : 
     798          711943 :                 tv_p = &tv;
     799                 :         }
     800                 : 
     801                 :         /* slight hack to support buffered data; if there is data sitting in the
     802                 :          * read buffer of any of the streams in the read array, let's pretend
     803                 :          * that we selected, but return only the readable sockets */
     804          711943 :         if (r_array != NULL) {
     805                 : 
     806          711943 :                 retval = stream_array_emulate_read_fd_set(r_array TSRMLS_CC);
     807          711943 :                 if (retval > 0) {
     808               1 :                         if (w_array != NULL) {
     809               1 :                                 zend_hash_clean(Z_ARRVAL_P(w_array));
     810                 :                         }
     811               1 :                         if (e_array != NULL) {
     812               0 :                                 zend_hash_clean(Z_ARRVAL_P(e_array));
     813                 :                         }
     814               1 :                         RETURN_LONG(retval);
     815                 :                 }
     816                 :         }
     817                 :         
     818          711942 :         retval = php_select(max_fd+1, &rfds, &wfds, &efds, tv_p);
     819                 : 
     820          711942 :         if (retval == -1) {
     821               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to select [%d]: %s (max_fd=%d)",
     822                 :                                 errno, strerror(errno), max_fd);
     823               0 :                 RETURN_FALSE;
     824                 :         }
     825                 : 
     826          711942 :         if (r_array != NULL) stream_array_from_fd_set(r_array, &rfds TSRMLS_CC);
     827          711942 :         if (w_array != NULL) stream_array_from_fd_set(w_array, &wfds TSRMLS_CC);
     828          711942 :         if (e_array != NULL) stream_array_from_fd_set(e_array, &efds TSRMLS_CC);
     829                 : 
     830          711942 :         RETURN_LONG(retval);
     831                 : }
     832                 : /* }}} */
     833                 : 
     834                 : /* {{{ stream_context related functions */
     835                 : static void user_space_stream_notifier(php_stream_context *context, int notifycode, int severity,
     836                 :                 char *xmsg, int xcode, size_t bytes_sofar, size_t bytes_max, void * ptr TSRMLS_DC)
     837               0 : {
     838               0 :         zval *callback = (zval*)context->notifier->ptr;
     839               0 :         zval *retval = NULL;
     840                 :         zval zvs[6];
     841                 :         zval *ps[6];
     842                 :         zval **ptps[6];
     843                 :         int i;
     844                 :         
     845               0 :         for (i = 0; i < 6; i++) {
     846               0 :                 INIT_ZVAL(zvs[i]);
     847               0 :                 ps[i] = &zvs[i];
     848               0 :                 ptps[i] = &ps[i];
     849               0 :                 MAKE_STD_ZVAL(ps[i]);
     850                 :         }
     851                 :                 
     852               0 :         ZVAL_LONG(ps[0], notifycode);
     853               0 :         ZVAL_LONG(ps[1], severity);
     854               0 :         if (xmsg) {
     855               0 :                 ZVAL_STRING(ps[2], xmsg, 1);
     856                 :         } else {
     857               0 :                 ZVAL_NULL(ps[2]);
     858                 :         }
     859               0 :         ZVAL_LONG(ps[3], xcode);
     860               0 :         ZVAL_LONG(ps[4], bytes_sofar);
     861               0 :         ZVAL_LONG(ps[5], bytes_max);
     862                 : 
     863               0 :         if (FAILURE == call_user_function_ex(EG(function_table), NULL, callback, &retval, 6, ptps, 0, NULL TSRMLS_CC)) {
     864               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to call user notifier");
     865                 :         }
     866               0 :         for (i = 0; i < 6; i++) {
     867               0 :                 zval_ptr_dtor(&ps[i]);
     868                 :         }
     869               0 :         if (retval) {
     870               0 :                 zval_ptr_dtor(&retval);
     871                 :         }
     872               0 : }
     873                 : 
     874                 : static void user_space_stream_notifier_dtor(php_stream_notifier *notifier)
     875               2 : {
     876               2 :         if (notifier && notifier->ptr) {
     877               2 :                 zval_ptr_dtor((zval **)&(notifier->ptr));
     878               2 :                 notifier->ptr = NULL;
     879                 :         }
     880               2 : }
     881                 : 
     882                 : static int parse_context_options(php_stream_context *context, zval *options TSRMLS_DC)
     883              49 : {
     884                 :         HashPosition pos, opos;
     885                 :         zval **wval, **oval;
     886                 :         char *wkey, *okey;
     887                 :         int wkey_len, okey_len;
     888              49 :         int ret = SUCCESS;
     889                 :         ulong num_key;
     890                 :         
     891              49 :         zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(options), &pos);
     892             147 :         while (SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_P(options), (void**)&wval, &pos)) {
     893              97 :                 if (HASH_KEY_IS_STRING == zend_hash_get_current_key_ex(Z_ARRVAL_P(options), &wkey, &wkey_len, &num_key, 0, &pos)
     894                 :                                 && Z_TYPE_PP(wval) == IS_ARRAY) {
     895                 : 
     896              48 :                         zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(wval), &opos);
     897             182 :                         while (SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_PP(wval), (void**)&oval, &opos)) {
     898                 : 
     899              86 :                                 if (HASH_KEY_IS_STRING == zend_hash_get_current_key_ex(Z_ARRVAL_PP(wval), &okey, &okey_len, &num_key, 0, &opos)) {
     900              86 :                                         php_stream_context_set_option(context, wkey, okey, *oval);
     901                 :                                 }
     902              86 :                                 zend_hash_move_forward_ex(Z_ARRVAL_PP(wval), &opos);
     903                 :                         }
     904                 : 
     905                 :                 } else {
     906               1 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "options should have the form [\"wrappername\"][\"optionname\"] = $value");
     907                 :                 }
     908              49 :                 zend_hash_move_forward_ex(Z_ARRVAL_P(options), &pos);
     909                 :         }
     910                 : 
     911              49 :         return ret;
     912                 : }
     913                 : 
     914                 : static int parse_context_params(php_stream_context *context, zval *params TSRMLS_DC)
     915               3 : {
     916               3 :         int ret = SUCCESS;
     917                 :         zval **tmp;
     918                 : 
     919               3 :         if (SUCCESS == zend_hash_find(Z_ARRVAL_P(params), "notification", sizeof("notification"), (void**)&tmp)) {
     920                 :                 
     921               2 :                 if (context->notifier) {
     922               1 :                         php_stream_notification_free(context->notifier);
     923               1 :                         context->notifier = NULL;
     924                 :                 }
     925                 : 
     926               2 :                 context->notifier = php_stream_notification_alloc();
     927               2 :                 context->notifier->func = user_space_stream_notifier;
     928               2 :                 context->notifier->ptr = *tmp;
     929               2 :                 Z_ADDREF_P(*tmp);
     930               2 :                 context->notifier->dtor = user_space_stream_notifier_dtor;
     931                 :         }
     932               3 :         if (SUCCESS == zend_hash_find(Z_ARRVAL_P(params), "options", sizeof("options"), (void**)&tmp)) {
     933               1 :                 if (Z_TYPE_PP(tmp) == IS_ARRAY) {
     934               0 :                         parse_context_options(context, *tmp TSRMLS_CC);
     935                 :                 } else {
     936               1 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid stream/context parameter");
     937                 :                 }
     938                 :         }
     939                 :         
     940               3 :         return ret;
     941                 : }
     942                 : 
     943                 : /* given a zval which is either a stream or a context, return the underlying
     944                 :  * stream_context.  If it is a stream that does not have a context assigned, it
     945                 :  * will create and assign a context and return that.  */
     946                 : static php_stream_context *decode_context_param(zval *contextresource TSRMLS_DC)
     947              12 : {
     948              12 :         php_stream_context *context = NULL;
     949                 : 
     950              12 :         context = zend_fetch_resource(&contextresource TSRMLS_CC, -1, NULL, NULL, 1, php_le_stream_context());
     951              12 :         if (context == NULL) {
     952                 :                 php_stream *stream;
     953                 : 
     954               0 :                 stream = zend_fetch_resource(&contextresource TSRMLS_CC, -1, NULL, NULL, 2, php_file_le_stream(), php_file_le_pstream);
     955                 : 
     956               0 :                 if (stream) {
     957               0 :                         context = stream->context;
     958               0 :                         if (context == NULL) {
     959                 :                                 /* Only way this happens is if file is opened with NO_DEFAULT_CONTEXT
     960                 :                                    param, but then something is called which requires a context.
     961                 :                                    Don't give them the default one though since they already said they
     962                 :                                    didn't want it. */
     963               0 :                                 context = stream->context = php_stream_context_alloc();
     964                 :                         }
     965                 :                 }
     966                 :         }
     967                 : 
     968              12 :         return context;
     969                 : }
     970                 : /* }}} */
     971                 : 
     972                 : /* {{{ proto array stream_context_get_options(resource context|resource stream)
     973                 :    Retrieve options for a stream/wrapper/context */
     974                 : PHP_FUNCTION(stream_context_get_options)
     975               2 : {
     976                 :         zval *zcontext;
     977                 :         php_stream_context *context;
     978                 : 
     979               2 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zcontext) == FAILURE) {
     980               0 :                 RETURN_FALSE;
     981                 :         }
     982               2 :         context = decode_context_param(zcontext TSRMLS_CC);
     983               2 :         if (!context) {
     984               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid stream/context parameter");
     985               0 :                 RETURN_FALSE;
     986                 :         }
     987                 : 
     988               2 :         RETURN_ZVAL(context->options, 1, 0);
     989                 : }
     990                 : /* }}} */
     991                 : 
     992                 : /* {{{ proto bool stream_context_set_option(resource context|resource stream, string wrappername, string optionname, mixed value)
     993                 :    Set an option for a wrapper */
     994                 : PHP_FUNCTION(stream_context_set_option)
     995               1 : {
     996               1 :         zval *options = NULL, *zcontext = NULL, *zvalue = NULL;
     997                 :         php_stream_context *context;
     998                 :         char *wrappername, *optionname;
     999                 :         int wrapperlen, optionlen;
    1000                 : 
    1001               1 :         if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC,
    1002                 :                                 "rssz", &zcontext, &wrappername, &wrapperlen,
    1003                 :                                 &optionname, &optionlen, &zvalue) == FAILURE) {
    1004               0 :                 if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC,
    1005                 :                                         "ra", &zcontext, &options) == FAILURE) {
    1006               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "called with wrong number or type of parameters; please RTM");
    1007               0 :                         RETURN_FALSE;
    1008                 :                 }
    1009                 :         }
    1010                 : 
    1011                 :         /* figure out where the context is coming from exactly */
    1012               1 :         context = decode_context_param(zcontext TSRMLS_CC);
    1013               1 :         if (!context) {
    1014               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid stream/context parameter");
    1015               0 :                 RETURN_FALSE;
    1016                 :         }
    1017                 : 
    1018               1 :         if (options) {
    1019                 :                 /* handle the array syntax */
    1020               0 :                 RETVAL_BOOL(parse_context_options(context, options TSRMLS_CC) == SUCCESS);
    1021                 :         } else {
    1022               1 :                 php_stream_context_set_option(context, wrappername, optionname, zvalue);
    1023               1 :                 RETVAL_TRUE;
    1024                 :         }
    1025                 : }
    1026                 : /* }}} */
    1027                 : 
    1028                 : /* {{{ proto bool stream_context_set_params(resource context|resource stream, array options)
    1029                 :    Set parameters for a file context */
    1030                 : PHP_FUNCTION(stream_context_set_params)
    1031               3 : {
    1032                 :         zval *params, *zcontext;
    1033                 :         php_stream_context *context;
    1034                 : 
    1035               3 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra", &zcontext, &params) == FAILURE) {
    1036               0 :                 RETURN_FALSE;
    1037                 :         }
    1038                 : 
    1039               3 :         context = decode_context_param(zcontext TSRMLS_CC);
    1040               3 :         if (!context) {
    1041               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid stream/context parameter");
    1042               0 :                 RETURN_FALSE;
    1043                 :         }
    1044                 : 
    1045               3 :         RETVAL_BOOL(parse_context_params(context, params TSRMLS_CC) == SUCCESS);
    1046                 : }
    1047                 : /* }}} */
    1048                 : 
    1049                 : /* {{{ proto array stream_context_get_params(resource context|resource stream)
    1050                 :    Get parameters of a file context */
    1051                 : PHP_FUNCTION(stream_context_get_params)
    1052               6 : {
    1053                 :         zval *zcontext, *options;
    1054                 :         php_stream_context *context;
    1055                 : 
    1056               6 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zcontext) == FAILURE) {
    1057               0 :                 RETURN_FALSE;
    1058                 :         }
    1059                 : 
    1060               6 :         context = decode_context_param(zcontext TSRMLS_CC);
    1061               6 :         if (!context) {
    1062               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid stream/context parameter");
    1063               0 :                 RETURN_FALSE;
    1064                 :         }
    1065                 : 
    1066               6 :         array_init(return_value);
    1067               6 :         if (context->notifier && context->notifier->ptr && context->notifier->func == user_space_stream_notifier) {
    1068               4 :                 add_assoc_zval_ex(return_value, ZEND_STRS("notification"), context->notifier->ptr);
    1069               4 :                 Z_ADDREF_P(context->notifier->ptr);
    1070                 :         }
    1071               6 :         ALLOC_INIT_ZVAL(options);
    1072               6 :         ZVAL_ZVAL(options, context->options, 1, 0);
    1073               6 :         add_assoc_zval_ex(return_value, ZEND_STRS("options"), options);
    1074                 : }
    1075                 : /* }}} */
    1076                 : 
    1077                 : /* {{{ proto resource stream_context_get_default([array options])
    1078                 :    Get a handle on the default file/stream context and optionally set parameters */
    1079                 : PHP_FUNCTION(stream_context_get_default)
    1080               2 : {
    1081               2 :         zval *params = NULL;
    1082                 :         php_stream_context *context;
    1083                 : 
    1084               2 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a", &params) == FAILURE) {
    1085               0 :                 RETURN_FALSE;
    1086                 :         }
    1087                 :         
    1088               2 :         if (FG(default_context) == NULL) {
    1089               2 :                 FG(default_context) = php_stream_context_alloc();
    1090                 :         }
    1091               2 :         context = FG(default_context);
    1092                 : 
    1093               2 :         if (params) {
    1094               0 :                 parse_context_options(context, params TSRMLS_CC);
    1095                 :         }
    1096                 :         
    1097               2 :         php_stream_context_to_zval(context, return_value);
    1098                 : }
    1099                 : /* }}} */
    1100                 : 
    1101                 : /* {{{ proto resource stream_context_set_default(array options)
    1102                 :    Set default file/stream context, returns the context as a resource */
    1103                 : PHP_FUNCTION(stream_context_set_default)
    1104               0 : {
    1105               0 :         zval *options = NULL;
    1106                 :         php_stream_context *context;
    1107                 : 
    1108               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &options) == FAILURE) {
    1109               0 :                 return;
    1110                 :         }
    1111                 : 
    1112               0 :         if (FG(default_context) == NULL) {
    1113               0 :                 FG(default_context) = php_stream_context_alloc();
    1114                 :         }
    1115               0 :         context = FG(default_context);
    1116                 : 
    1117               0 :         parse_context_options(context, options TSRMLS_CC);
    1118                 : 
    1119               0 :         php_stream_context_to_zval(context, return_value);
    1120                 : }
    1121                 : /* }}} */
    1122                 : 
    1123                 : /* {{{ proto resource stream_context_create([array options[, array params]])
    1124                 :    Create a file context and optionally set parameters */
    1125                 : PHP_FUNCTION(stream_context_create)
    1126              77 : {
    1127              77 :         zval *options = NULL, *params = NULL;
    1128                 :         php_stream_context *context;
    1129                 : 
    1130              77 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!a!", &options, &params) == FAILURE) {
    1131               0 :                 RETURN_FALSE;
    1132                 :         }
    1133                 :         
    1134              77 :         context = php_stream_context_alloc();
    1135                 :         
    1136              77 :         if (options) {
    1137              49 :                 parse_context_options(context, options TSRMLS_CC);
    1138                 :         }
    1139                 : 
    1140              77 :         if (params) {
    1141               0 :                 parse_context_params(context, params TSRMLS_CC);
    1142                 :         }
    1143                 :         
    1144              77 :         RETURN_RESOURCE(context->rsrc_id);
    1145                 : }
    1146                 : /* }}} */
    1147                 : 
    1148                 : /* {{{ streams filter functions */
    1149                 : static void apply_filter_to_stream(int append, INTERNAL_FUNCTION_PARAMETERS)
    1150              79 : {
    1151                 :         zval *zstream;
    1152                 :         php_stream *stream;
    1153                 :         char *filtername;
    1154                 :         int filternamelen;
    1155              79 :         long read_write = 0;
    1156              79 :         zval *filterparams = NULL;
    1157              79 :         php_stream_filter *filter = NULL;
    1158                 :         int ret;
    1159                 : 
    1160              79 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|lz", &zstream,
    1161                 :                                 &filtername, &filternamelen, &read_write, &filterparams) == FAILURE) {
    1162               0 :                 RETURN_FALSE;
    1163                 :         }
    1164                 : 
    1165              79 :         php_stream_from_zval(stream, &zstream);
    1166                 : 
    1167              79 :         if ((read_write & PHP_STREAM_FILTER_ALL) == 0) {
    1168                 :                 /* Chain not specified.
    1169                 :                  * Examine stream->mode to determine which filters are needed
    1170                 :                  * There's no harm in attaching a filter to an unused chain,
    1171                 :                  * but why waste the memory and clock cycles? 
    1172                 :                  */
    1173              50 :                 if (strchr(stream->mode, 'r') || strchr(stream->mode, '+')) {
    1174              45 :                         read_write |= PHP_STREAM_FILTER_READ;
    1175                 :                 }
    1176              50 :                 if (strchr(stream->mode, 'w') || strchr(stream->mode, '+') || strchr(stream->mode, 'a')) {
    1177              43 :                         read_write |= PHP_STREAM_FILTER_WRITE;
    1178                 :                 }
    1179                 :         }
    1180                 : 
    1181              79 :         if (read_write & PHP_STREAM_FILTER_READ) {
    1182              63 :                 filter = php_stream_filter_create(filtername, filterparams, php_stream_is_persistent(stream) TSRMLS_CC);
    1183              63 :                 if (filter == NULL) {
    1184               1 :                         RETURN_FALSE;
    1185                 :                 }
    1186                 : 
    1187              62 :                 if (append) { 
    1188              57 :                         ret = php_stream_filter_append_ex(&stream->readfilters, filter TSRMLS_CC);
    1189                 :                 } else {
    1190               5 :                         ret = php_stream_filter_prepend_ex(&stream->readfilters, filter TSRMLS_CC);
    1191                 :                 }
    1192              62 :                 if (ret != SUCCESS) {
    1193               7 :                         php_stream_filter_remove(filter, 1 TSRMLS_CC);
    1194               7 :                         RETURN_FALSE;
    1195                 :                 }
    1196                 :         }
    1197                 : 
    1198              71 :         if (read_write & PHP_STREAM_FILTER_WRITE) {
    1199              48 :                 filter = php_stream_filter_create(filtername, filterparams, php_stream_is_persistent(stream) TSRMLS_CC);
    1200              48 :                 if (filter == NULL) {
    1201               0 :                         RETURN_FALSE;
    1202                 :                 }
    1203                 : 
    1204              48 :                 if (append) { 
    1205              43 :                         ret = php_stream_filter_append_ex(&stream->writefilters, filter TSRMLS_CC);
    1206                 :                 } else {
    1207               5 :                         ret = php_stream_filter_prepend_ex(&stream->writefilters, filter TSRMLS_CC);
    1208                 :                 }
    1209              48 :                 if (ret != SUCCESS) {
    1210               0 :                         php_stream_filter_remove(filter, 1 TSRMLS_CC);
    1211               0 :                         RETURN_FALSE;
    1212                 :                 }
    1213                 :         }
    1214                 : 
    1215              71 :         if (filter) {
    1216              71 :                 RETURN_RESOURCE(filter->rsrc_id = ZEND_REGISTER_RESOURCE(NULL, filter, php_file_le_stream_filter()));
    1217                 :         } else {
    1218               0 :                 RETURN_FALSE;
    1219                 :         }
    1220                 : }
    1221                 : /* }}} */
    1222                 : 
    1223                 : /* {{{ proto resource stream_filter_prepend(resource stream, string filtername[, int read_write[, string filterparams]])
    1224                 :    Prepend a filter to a stream */
    1225                 : PHP_FUNCTION(stream_filter_prepend)
    1226               5 : {
    1227               5 :         apply_filter_to_stream(0, INTERNAL_FUNCTION_PARAM_PASSTHRU);
    1228               5 : }
    1229                 : /* }}} */
    1230                 : 
    1231                 : /* {{{ proto resource stream_filter_append(resource stream, string filtername[, int read_write[, string filterparams]])
    1232                 :    Append a filter to a stream */
    1233                 : PHP_FUNCTION(stream_filter_append)
    1234              74 : {
    1235              74 :         apply_filter_to_stream(1, INTERNAL_FUNCTION_PARAM_PASSTHRU);
    1236              74 : }
    1237                 : /* }}} */
    1238                 : 
    1239                 : /* {{{ proto bool stream_filter_remove(resource stream_filter)
    1240                 :         Flushes any data in the filter's internal buffer, removes it from the chain, and frees the resource */
    1241                 : PHP_FUNCTION(stream_filter_remove)
    1242              18 : {
    1243                 :         zval *zfilter;
    1244                 :         php_stream_filter *filter;
    1245                 : 
    1246              18 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zfilter) == FAILURE) {
    1247               3 :                 RETURN_FALSE;
    1248                 :         }
    1249                 : 
    1250              15 :         filter = zend_fetch_resource(&zfilter TSRMLS_CC, -1, NULL, NULL, 1, php_file_le_stream_filter());
    1251              15 :         if (!filter) {
    1252               2 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid resource given, not a stream filter");
    1253               2 :                 RETURN_FALSE;
    1254                 :         }
    1255                 : 
    1256              13 :         if (php_stream_filter_flush(filter, 1) == FAILURE) {
    1257              10 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to flush filter, not removing");
    1258              10 :                 RETURN_FALSE;
    1259                 :         }
    1260                 : 
    1261               3 :         if (zend_list_delete(Z_LVAL_P(zfilter)) == FAILURE) {
    1262               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not invalidate filter, not removing");
    1263               0 :                 RETURN_FALSE;
    1264                 :         } else {
    1265               3 :                 php_stream_filter_remove(filter, 1 TSRMLS_CC);
    1266               3 :                 RETURN_TRUE;
    1267                 :         }
    1268                 : }
    1269                 : /* }}} */
    1270                 : 
    1271                 : /* {{{ proto string stream_get_line(resource stream, int maxlen [, string ending])
    1272                 :    Read up to maxlen bytes from a stream or until the ending string is found */
    1273                 : PHP_FUNCTION(stream_get_line)
    1274              37 : {
    1275              37 :         char *str = NULL;
    1276              37 :         int str_len = 0;
    1277                 :         long max_length;
    1278                 :         zval *zstream;
    1279                 :         char *buf;
    1280                 :         size_t buf_size;
    1281                 :         php_stream *stream;
    1282                 :         
    1283              37 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|s", &zstream, &max_length, &str, &str_len) == FAILURE) {
    1284               0 :                 RETURN_FALSE;
    1285                 :         }
    1286                 : 
    1287              37 :         if (max_length < 0) {
    1288               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "The maximum allowed length must be greater than or equal to zero");
    1289               0 :                 RETURN_FALSE;
    1290                 :         }
    1291              37 :         if (!max_length) {
    1292               3 :                 max_length = PHP_SOCK_CHUNK_SIZE;
    1293                 :         }
    1294                 : 
    1295              37 :         php_stream_from_zval(stream, &zstream);
    1296                 : 
    1297              37 :         if ((buf = php_stream_get_record(stream, max_length, &buf_size, str, str_len TSRMLS_CC))) {
    1298              31 :                 RETURN_STRINGL(buf, buf_size, 0);
    1299                 :         } else {
    1300               6 :                 RETURN_FALSE;
    1301                 :         }
    1302                 : }
    1303                 : 
    1304                 : /* }}} */
    1305                 : 
    1306                 : /* {{{ proto bool stream_set_blocking(resource socket, int mode)
    1307                 :    Set blocking/non-blocking mode on a socket or stream */
    1308                 : PHP_FUNCTION(stream_set_blocking)
    1309               9 : {
    1310                 :         zval *arg1;
    1311                 :         int block;
    1312                 :         long arg2;
    1313                 :         php_stream *stream;
    1314                 : 
    1315               9 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &arg1, &arg2) == FAILURE) {
    1316               0 :                 return;
    1317                 :         }
    1318                 : 
    1319               9 :         php_stream_from_zval(stream, &arg1);
    1320                 : 
    1321               9 :         block = arg2;
    1322                 : 
    1323               9 :         if (php_stream_set_option(stream, PHP_STREAM_OPTION_BLOCKING, block == 0 ? 0 : 1, NULL) == -1) {
    1324               2 :                 RETURN_FALSE;
    1325                 :         }
    1326                 : 
    1327               7 :         RETURN_TRUE;
    1328                 : }
    1329                 : 
    1330                 : /* }}} */
    1331                 : 
    1332                 : /* {{{ proto bool stream_set_timeout(resource stream, int seconds [, int microseconds])
    1333                 :    Set timeout on stream read to seconds + microseonds */
    1334                 : #if HAVE_SYS_TIME_H || defined(PHP_WIN32)
    1335                 : PHP_FUNCTION(stream_set_timeout)
    1336              10 : {
    1337                 :         zval *socket;
    1338              10 :         long seconds, microseconds = 0;
    1339                 :         struct timeval t;
    1340                 :         php_stream *stream;
    1341              10 :         int argc = ZEND_NUM_ARGS();
    1342                 : 
    1343              10 :         if (zend_parse_parameters(argc TSRMLS_CC, "rl|l", &socket, &seconds, &microseconds) == FAILURE) {
    1344               3 :                 return;
    1345                 :         }
    1346                 : 
    1347               7 :         php_stream_from_zval(stream, &socket);
    1348                 : 
    1349               6 :         t.tv_sec = seconds;
    1350                 : 
    1351               6 :         if (argc == 3) {
    1352               3 :                 t.tv_usec = microseconds % 1000000;
    1353               3 :                 t.tv_sec += microseconds / 1000000;
    1354                 :         } else {
    1355               3 :                 t.tv_usec = 0;
    1356                 :         }
    1357                 : 
    1358               6 :         if (PHP_STREAM_OPTION_RETURN_OK == php_stream_set_option(stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &t)) {
    1359               4 :                 RETURN_TRUE;
    1360                 :         }
    1361                 : 
    1362               2 :         RETURN_FALSE;
    1363                 : }
    1364                 : #endif /* HAVE_SYS_TIME_H || defined(PHP_WIN32) */
    1365                 : /* }}} */
    1366                 : 
    1367                 : /* {{{ proto int stream_set_write_buffer(resource fp, int buffer)
    1368                 :    Set file write buffer */
    1369                 : PHP_FUNCTION(stream_set_write_buffer)
    1370               3 : {
    1371                 :         zval *arg1;
    1372                 :         int ret;
    1373                 :         long arg2;
    1374                 :         size_t buff;
    1375                 :         php_stream *stream;
    1376                 : 
    1377               3 :         switch (ZEND_NUM_ARGS()) {
    1378                 :         case 2:
    1379               3 :                 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &arg1, &arg2) == FAILURE) {
    1380               0 :                         RETURN_FALSE;
    1381                 :                 }
    1382                 :                 break;
    1383                 :         default:
    1384               0 :                 WRONG_PARAM_COUNT;
    1385                 :                 /* NOTREACHED */
    1386                 :                 break;
    1387                 :         }
    1388                 :         
    1389               3 :         php_stream_from_zval(stream, &arg1);
    1390                 : 
    1391               3 :         buff = arg2;
    1392                 : 
    1393                 :         /* if buff is 0 then set to non-buffered */
    1394               3 :         if (buff == 0) {
    1395               1 :                 ret = php_stream_set_option(stream, PHP_STREAM_OPTION_WRITE_BUFFER, PHP_STREAM_BUFFER_NONE, NULL);
    1396                 :         } else {
    1397               2 :                 ret = php_stream_set_option(stream, PHP_STREAM_OPTION_WRITE_BUFFER, PHP_STREAM_BUFFER_FULL, &buff);
    1398                 :         }
    1399                 : 
    1400               3 :         RETURN_LONG(ret == 0 ? 0 : EOF);
    1401                 : }
    1402                 : /* }}} */
    1403                 : 
    1404                 : /* {{{ proto int stream_socket_enable_crypto(resource stream, bool enable [, int cryptokind [, resource sessionstream]])
    1405                 :    Enable or disable a specific kind of crypto on the stream */
    1406                 : PHP_FUNCTION(stream_socket_enable_crypto)
    1407               1 : {
    1408               1 :         long cryptokind = 0;
    1409               1 :         zval *zstream, *zsessstream = NULL;
    1410               1 :         php_stream *stream, *sessstream = NULL;
    1411                 :         zend_bool enable;
    1412                 :         int ret;
    1413                 :         
    1414               1 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rb|lr", &zstream, &enable, &cryptokind, &zsessstream) == FAILURE) {
    1415               0 :                 RETURN_FALSE;
    1416                 :         }
    1417                 :         
    1418               1 :         php_stream_from_zval(stream, &zstream);
    1419                 : 
    1420               1 :         if (ZEND_NUM_ARGS() >= 3) {
    1421               1 :                 if (zsessstream) {
    1422               0 :                         php_stream_from_zval(sessstream, &zsessstream);
    1423                 :                 }
    1424                 :                 
    1425               1 :                 if (php_stream_xport_crypto_setup(stream, cryptokind, sessstream TSRMLS_CC) < 0) {
    1426               0 :                         RETURN_FALSE;
    1427                 :                 }
    1428               0 :         } else if (enable) {
    1429               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "When enabling encryption you must specify the crypto type");
    1430               0 :                 RETURN_FALSE;
    1431                 :         }
    1432                 : 
    1433               1 :         ret = php_stream_xport_crypto_enable(stream, enable TSRMLS_CC);
    1434               1 :         switch (ret) {
    1435                 :                 case -1:
    1436               0 :                         RETURN_FALSE;
    1437                 : 
    1438                 :                 case 0:
    1439               0 :                         RETURN_LONG(0);
    1440                 :                 
    1441                 :                 default:
    1442               1 :                         RETURN_TRUE;
    1443                 :         }
    1444                 : }
    1445                 : /* }}} */
    1446                 : 
    1447                 : /* {{{ proto bool stream_is_local(resource stream|string url) U
    1448                 : */
    1449                 : PHP_FUNCTION(stream_is_local)
    1450               3 : {
    1451                 :         zval **zstream;
    1452               3 :         php_stream *stream = NULL;
    1453               3 :         php_stream_wrapper *wrapper = NULL;
    1454                 : 
    1455               3 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &zstream) == FAILURE) {
    1456               0 :                 RETURN_FALSE;
    1457                 :         }
    1458                 : 
    1459               3 :         if (Z_TYPE_PP(zstream) == IS_RESOURCE) {
    1460               1 :                 php_stream_from_zval(stream, zstream);
    1461               1 :                 if (stream == NULL) {
    1462               0 :                         RETURN_FALSE;
    1463                 :                 }
    1464               1 :                 wrapper = stream->wrapper;
    1465                 :         } else {
    1466               2 :                 convert_to_string_ex(zstream);
    1467                 :                 
    1468               2 :                 wrapper = php_stream_locate_url_wrapper(Z_STRVAL_PP(zstream), NULL, 0 TSRMLS_CC);
    1469                 :         }
    1470                 : 
    1471               3 :         if (!wrapper) {
    1472               0 :                 RETURN_FALSE;
    1473                 :         }
    1474                 : 
    1475               3 :         RETURN_BOOL(wrapper->is_url==0);
    1476                 : }
    1477                 : /* }}} */
    1478                 : 
    1479                 : /* {{{ proto bool stream_supports_lock(resource stream)
    1480                 :    Tells wether the stream supports locking through flock(). */
    1481                 : PHP_FUNCTION(stream_supports_lock)
    1482               5 : {
    1483                 :         php_stream *stream;
    1484                 :         zval *zsrc;
    1485                 : 
    1486               5 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zsrc) == FAILURE) {
    1487               0 :                 RETURN_FALSE;
    1488                 :         }
    1489                 : 
    1490               5 :         php_stream_from_zval(stream, &zsrc);
    1491                 : 
    1492               4 :         if (!php_stream_supports_lock(stream)) {
    1493               2 :                 RETURN_FALSE;
    1494                 :         }
    1495                 : 
    1496               2 :         RETURN_TRUE;
    1497                 : }
    1498                 : 
    1499                 : #ifdef HAVE_SHUTDOWN
    1500                 : /* {{{ proto int stream_socket_shutdown(resource stream, int how)
    1501                 :         causes all or part of a full-duplex connection on the socket associated
    1502                 :         with stream to be shut down.  If how is SHUT_RD,  further receptions will
    1503                 :         be disallowed. If how is SHUT_WR, further transmissions will be disallowed.
    1504                 :         If how is SHUT_RDWR,  further  receptions and transmissions will be
    1505                 :         disallowed. */
    1506                 : PHP_FUNCTION(stream_socket_shutdown)
    1507               3 : {
    1508                 :         long how;
    1509                 :         zval *zstream;
    1510                 :         php_stream *stream;
    1511                 :         
    1512               3 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zstream, &how) == FAILURE) {
    1513               0 :                 RETURN_FALSE;
    1514                 :         }
    1515                 :         
    1516               3 :         if (how != STREAM_SHUT_RD &&
    1517                 :             how != STREAM_SHUT_WR &&
    1518                 :             how != STREAM_SHUT_RDWR) {
    1519               0 :                 RETURN_FALSE;
    1520                 :         }
    1521                 : 
    1522               3 :         php_stream_from_zval(stream, &zstream);
    1523                 : 
    1524               3 :         RETURN_BOOL(php_stream_xport_shutdown(stream, (stream_shutdown_t)how TSRMLS_CC) == 0);
    1525                 : }
    1526                 : /* }}} */
    1527                 : #endif
    1528                 : 
    1529                 : /*
    1530                 :  * Local variables:
    1531                 :  * tab-width: 4
    1532                 :  * c-basic-offset: 4
    1533                 :  * End:
    1534                 :  * vim600: noet sw=4 ts=4 fdm=marker
    1535                 :  * vim<600: noet sw=4 ts=4
    1536                 :  */
    1537                 : 

Generated by: LTP GCOV extension version 1.5

Generated at Sat, 21 Nov 2009 12:27:11 +0000 (3 days ago)

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