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

LCOV - code coverage report
Current view: top level - ext/standard - streamsfuncs.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 530 698 75.9 %
Date: 2014-08-04 Functions: 39 43 90.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Mon, 04 Aug 2014 15:49:14 +0000 (28 days ago)

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