php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
streamsfuncs.c
Go to the documentation of this file.
1/*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | https://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Authors: Wez Furlong <wez@thebrainroom.com> |
14 | Sara Golemon <pollita@php.net> |
15 +----------------------------------------------------------------------+
16*/
17
18#include "php.h"
20#include "ext/standard/file.h"
22#include "php_ini.h"
23#include "streamsfuncs.h"
24#include "php_network.h"
25#include "php_string.h"
26#ifdef HAVE_UNISTD_H
27#include <unistd.h>
28#endif
29
30#ifndef PHP_WIN32
31#define php_select(m, r, w, e, t) select(m, r, w, e, t)
32typedef unsigned long long php_timeout_ull;
33#else
34#include "win32/select.h"
35#include "win32/sockets.h"
36#include "win32/console.h"
37typedef unsigned __int64 php_timeout_ull;
38#endif
39
40#define GET_CTX_OPT(stream, wrapper, name, val) (PHP_STREAM_CONTEXT(stream) && NULL != (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), wrapper, name)))
41
42static php_stream_context *decode_context_param(zval *contextresource);
43
44/* Streams based network functions */
45
46#ifdef HAVE_SOCKETPAIR
47/* {{{ Creates a pair of connected, indistinguishable socket streams */
49{
50 zend_long domain, type, protocol;
51 php_stream *s1, *s2;
52 php_socket_t pair[2];
53
55 Z_PARAM_LONG(domain)
57 Z_PARAM_LONG(protocol)
59
60 if (0 != socketpair((int)domain, (int)type, (int)protocol, pair)) {
61 char errbuf[256];
62 php_error_docref(NULL, E_WARNING, "Failed to create sockets: [%d]: %s",
63 php_socket_errno(), php_socket_strerror(php_socket_errno(), errbuf, sizeof(errbuf)));
65 }
66
67 s1 = php_stream_sock_open_from_socket(pair[0], 0);
68 if (s1 == NULL) {
69 close(pair[0]);
70 close(pair[1]);
71 php_error_docref(NULL, E_WARNING, "Failed to open stream from socketpair");
73 }
74 s2 = php_stream_sock_open_from_socket(pair[1], 0);
75 if (s2 == NULL) {
77 close(pair[1]);
78 php_error_docref(NULL, E_WARNING, "Failed to open stream from socketpair");
80 }
81
83
84 /* set the __exposed flag.
85 * php_stream_to_zval() does, add_next_index_resource() does not */
88
91}
92/* }}} */
93#endif
94
95/* {{{ Open a client connection to a remote address */
97{
98 zend_string *host;
99 zval *zerrno = NULL, *zerrstr = NULL, *zcontext = NULL;
100 double timeout;
101 bool timeout_is_null = 1;
102 php_timeout_ull conv;
103 struct timeval tv;
104 char *hashkey = NULL;
105 php_stream *stream = NULL;
106 int err;
108 zend_string *errstr = NULL;
110
112 Z_PARAM_STR(host)
114 Z_PARAM_ZVAL(zerrno)
115 Z_PARAM_ZVAL(zerrstr)
116 Z_PARAM_DOUBLE_OR_NULL(timeout, timeout_is_null)
120
122
123 if (timeout_is_null) {
124 timeout = (double)FG(default_socket_timeout);
125 } else if (!zend_finite(timeout)) {
126 zend_argument_value_error(4, "must be a finite value");
128 }
129
131
133 spprintf(&hashkey, 0, "stream_socket_client__%s", ZSTR_VAL(host));
134 }
135
136 /* prepare the timeout value for use */
137 struct timeval *tv_pointer;
138 if (timeout < 0.0 || timeout >= (double) PHP_TIMEOUT_ULL_MAX / 1000000.0) {
139 tv_pointer = NULL;
140 } else {
141 conv = (php_timeout_ull) (timeout * 1000000.0);
142#ifdef PHP_WIN32
143 tv.tv_sec = (long)(conv / 1000000);
144 tv.tv_usec = (long)(conv % 1000000);
145#else
146 tv.tv_sec = conv / 1000000;
147 tv.tv_usec = conv % 1000000;
148#endif
149 tv_pointer = &tv;
150 }
151
152 if (zerrno) {
153 ZEND_TRY_ASSIGN_REF_LONG(zerrno, 0);
154 }
155 if (zerrstr) {
157 }
158
162 hashkey, tv_pointer, context, &errstr, &err);
163
164
165 if (stream == NULL) {
166 /* host might contain binary characters */
167 zend_string *quoted_host = php_addslashes(host);
168
169 php_error_docref(NULL, E_WARNING, "Unable to connect to %s (%s)", ZSTR_VAL(quoted_host), errstr == NULL ? "Unknown error" : ZSTR_VAL(errstr));
170 zend_string_release_ex(quoted_host, 0);
171 }
172
173 if (hashkey) {
174 efree(hashkey);
175 }
176
177 if (stream == NULL) {
178 if (zerrno) {
180 }
181 if (zerrstr && errstr) {
182 ZEND_TRY_ASSIGN_REF_STR(zerrstr, errstr);
183 } else if (errstr) {
184 zend_string_release_ex(errstr, 0);
185 }
187 }
188
189 if (errstr) {
190 zend_string_release_ex(errstr, 0);
191 }
192
194
195}
196/* }}} */
197
198/* {{{ Create a server socket bound to localaddress */
200{
201 char *host;
202 size_t host_len;
203 zval *zerrno = NULL, *zerrstr = NULL, *zcontext = NULL;
204 php_stream *stream = NULL;
205 int err = 0;
207 zend_string *errstr = NULL;
209
211
213 Z_PARAM_STRING(host, host_len)
215 Z_PARAM_ZVAL(zerrno)
216 Z_PARAM_ZVAL(zerrstr)
220
222
223 if (zerrno) {
224 ZEND_TRY_ASSIGN_REF_LONG(zerrno, 0);
225 }
226 if (zerrstr) {
228 }
229
230 stream = php_stream_xport_create(host, host_len, REPORT_ERRORS,
232 NULL, NULL, context, &errstr, &err);
233
234 if (stream == NULL) {
235 php_error_docref(NULL, E_WARNING, "Unable to connect to %s (%s)", host, errstr == NULL ? "Unknown error" : ZSTR_VAL(errstr));
236 }
237
238 if (stream == NULL) {
239 if (zerrno) {
241 }
242 if (zerrstr && errstr) {
243 ZEND_TRY_ASSIGN_REF_STR(zerrstr, errstr);
244 } else if (errstr) {
245 zend_string_release_ex(errstr, 0);
246 }
248 }
249
250 if (errstr) {
251 zend_string_release_ex(errstr, 0);
252 }
253
255}
256/* }}} */
257
258/* {{{ Accept a client connection from a server socket */
260{
261 double timeout;
262 bool timeout_is_null = 1;
263 zval *zpeername = NULL;
264 zend_string *peername = NULL;
265 php_timeout_ull conv;
266 struct timeval tv;
267 php_stream *stream = NULL, *clistream = NULL;
268 zval *zstream;
269 zend_string *errstr = NULL;
270
272 Z_PARAM_RESOURCE(zstream)
274 Z_PARAM_DOUBLE_OR_NULL(timeout, timeout_is_null)
275 Z_PARAM_ZVAL(zpeername)
277
278 if (timeout_is_null) {
279 timeout = (double)FG(default_socket_timeout);
280 } else if (!zend_finite(timeout)) {
281 zend_argument_value_error(2, "must be a finite value");
283 }
284
285 php_stream_from_zval(stream, zstream);
286
287 /* prepare the timeout value for use */
288 struct timeval *tv_pointer;
289 if (timeout < 0.0 || timeout >= (double) PHP_TIMEOUT_ULL_MAX / 1000000.0) {
290 tv_pointer = NULL;
291 } else {
292 conv = (php_timeout_ull) (timeout * 1000000.0);
293#ifdef PHP_WIN32
294 tv.tv_sec = (long)(conv / 1000000);
295 tv.tv_usec = (long)(conv % 1000000);
296#else
297 tv.tv_sec = conv / 1000000;
298 tv.tv_usec = conv % 1000000;
299#endif
300 tv_pointer = &tv;
301 }
302
303 if (0 == php_stream_xport_accept(stream, &clistream,
304 zpeername ? &peername : NULL,
305 NULL, NULL,
306 tv_pointer, &errstr
307 ) && clistream) {
308
309 if (peername) {
310 ZEND_TRY_ASSIGN_REF_STR(zpeername, peername);
311 }
313 } else {
314 if (peername) {
315 zend_string_release(peername);
316 }
317 php_error_docref(NULL, E_WARNING, "Accept failed: %s", errstr ? ZSTR_VAL(errstr) : "Unknown error");
319 }
320
321 if (errstr) {
322 zend_string_release_ex(errstr, 0);
323 }
324}
325/* }}} */
326
327/* {{{ Returns either the locally bound or remote name for a socket stream */
329{
330 php_stream *stream;
331 zval *zstream;
332 bool want_peer;
334
336 Z_PARAM_RESOURCE(zstream)
337 Z_PARAM_BOOL(want_peer)
339
340 php_stream_from_zval(stream, zstream);
341
342 if (0 != php_stream_xport_get_name(stream, want_peer,
343 &name,
344 NULL, NULL
345 ) || !name) {
347 }
348
349 if ((ZSTR_LEN(name) == 0) || (ZSTR_VAL(name)[0] == 0)) {
352 }
353
355}
356/* }}} */
357
358/* {{{ Send data to a socket stream. If target_addr is specified it must be in dotted quad (or [ipv6]) format */
360{
361 php_stream *stream;
362 zval *zstream;
363 zend_long flags = 0;
364 char *data, *target_addr = NULL;
365 size_t datalen, target_addr_len = 0;
367 socklen_t sl = 0;
368
370 Z_PARAM_RESOURCE(zstream)
371 Z_PARAM_STRING(data, datalen)
374 Z_PARAM_STRING(target_addr, target_addr_len)
376 php_stream_from_zval(stream, zstream);
377
378 if (target_addr_len) {
379 /* parse the address */
380 if (FAILURE == php_network_parse_network_address_with_port(target_addr, target_addr_len, (struct sockaddr*)&sa, &sl)) {
381 php_error_docref(NULL, E_WARNING, "Failed to parse `%s' into a valid network address", target_addr);
383 }
384 }
385
386 RETURN_LONG(php_stream_xport_sendto(stream, data, datalen, (int)flags, target_addr_len ? &sa : NULL, sl));
387}
388/* }}} */
389
390/* {{{ Receives data from a socket stream */
392{
393 php_stream *stream;
394 zval *zstream, *zremote = NULL;
395 zend_string *remote_addr = NULL;
396 zend_long to_read = 0;
397 zend_string *read_buf;
398 zend_long flags = 0;
399 int recvd;
400
402 Z_PARAM_RESOURCE(zstream)
403 Z_PARAM_LONG(to_read)
406 Z_PARAM_ZVAL(zremote)
408
409 php_stream_from_zval(stream, zstream);
410
411 if (zremote) {
413 }
414
415 if (to_read <= 0) {
416 zend_argument_value_error(2, "must be greater than 0");
418 }
419
420 read_buf = zend_string_alloc(to_read, 0);
421
422 recvd = php_stream_xport_recvfrom(stream, ZSTR_VAL(read_buf), to_read, (int)flags, NULL, NULL,
423 zremote ? &remote_addr : NULL
424 );
425
426 if (recvd >= 0) {
427 if (zremote && remote_addr) {
428 ZEND_TRY_ASSIGN_REF_STR(zremote, remote_addr);
429 }
430 ZSTR_VAL(read_buf)[recvd] = '\0';
431 ZSTR_LEN(read_buf) = recvd;
432 RETURN_NEW_STR(read_buf);
433 }
434
435 zend_string_efree(read_buf);
437}
438/* }}} */
439
440/* {{{ Reads all remaining bytes (or up to maxlen bytes) from a stream and returns them as a string. */
442{
443 php_stream *stream;
444 zval *zsrc;
445 zend_long maxlen, desiredpos = -1L;
446 bool maxlen_is_null = 1;
448
450 Z_PARAM_RESOURCE(zsrc)
453 Z_PARAM_LONG(desiredpos)
455
456 if (maxlen_is_null) {
457 maxlen = (ssize_t) PHP_STREAM_COPY_ALL;
458 } else if (maxlen < 0 && maxlen != (ssize_t)PHP_STREAM_COPY_ALL) {
459 zend_argument_value_error(2, "must be greater than or equal to -1");
461 }
462
463 php_stream_from_zval(stream, zsrc);
464
465 if (desiredpos >= 0) {
466 int seek_res = 0;
467 zend_off_t position;
468
469 position = php_stream_tell(stream);
470 if (position >= 0 && desiredpos > position) {
471 /* use SEEK_CUR to allow emulation in streams that don't support seeking */
472 seek_res = php_stream_seek(stream, desiredpos - position, SEEK_CUR);
473 } else if (desiredpos < position) {
474 /* desired position before position or error on tell */
475 seek_res = php_stream_seek(stream, desiredpos, SEEK_SET);
476 }
477
478 if (seek_res != 0) {
480 "Failed to seek to position " ZEND_LONG_FMT " in the stream", desiredpos);
482 }
483 }
484
485 if ((contents = php_stream_copy_to_mem(stream, maxlen, 0))) {
487 } else {
489 }
490}
491/* }}} */
492
493/* {{{ Reads up to maxlen bytes from source stream and writes them to dest stream. */
495{
496 php_stream *src, *dest;
497 zval *zsrc, *zdest;
498 zend_long maxlen, pos = 0;
499 bool maxlen_is_null = 1;
500 size_t len;
501 int ret;
502
504 Z_PARAM_RESOURCE(zsrc)
505 Z_PARAM_RESOURCE(zdest)
510
511 if (maxlen_is_null) {
513 }
514
515 php_stream_from_zval(src, zsrc);
516 php_stream_from_zval(dest, zdest);
517
518 if (pos > 0 && php_stream_seek(src, pos, SEEK_SET) < 0) {
519 php_error_docref(NULL, E_WARNING, "Failed to seek to position " ZEND_LONG_FMT " in the stream", pos);
521 }
522
524
525 if (ret != SUCCESS) {
527 }
529}
530/* }}} */
531
532/* {{{ Retrieves header/meta data from streams/file pointers */
534{
535 zval *zstream;
536 php_stream *stream;
537
539 Z_PARAM_RESOURCE(zstream)
541
542 php_stream_from_zval(stream, zstream);
543
545
547 add_assoc_bool(return_value, "timed_out", 0);
548 add_assoc_bool(return_value, "blocked", 1);
549 add_assoc_bool(return_value, "eof", php_stream_eof(stream));
550 }
551
552 if (!Z_ISUNDEF(stream->wrapperdata)) {
553 Z_ADDREF_P(&stream->wrapperdata);
554 add_assoc_zval(return_value, "wrapper_data", &stream->wrapperdata);
555 }
556 if (stream->wrapper) {
557 add_assoc_string(return_value, "wrapper_type", (char *)stream->wrapper->wops->label);
558 }
559 add_assoc_string(return_value, "stream_type", (char *)stream->ops->label);
560
561 add_assoc_string(return_value, "mode", stream->mode);
562
563#if 0 /* TODO: needs updating for new filter API */
564 if (stream->filterhead) {
565 php_stream_filter *filter;
566
567 MAKE_STD_ZVAL(newval);
568 array_init(newval);
569
570 for (filter = stream->filterhead; filter != NULL; filter = filter->next) {
571 add_next_index_string(newval, (char *)filter->fops->label);
572 }
573
574 add_assoc_zval(return_value, "filters", newval);
575 }
576#endif
577
578 add_assoc_long(return_value, "unread_bytes", stream->writepos - stream->readpos);
579
580 add_assoc_bool(return_value, "seekable", (stream->ops->seek) && (stream->flags & PHP_STREAM_FLAG_NO_SEEK) == 0);
581 if (stream->orig_path) {
582 add_assoc_string(return_value, "uri", stream->orig_path);
583 }
584
585}
586/* }}} */
587
588/* {{{ Retrieves list of registered socket transports */
590{
591 HashTable *stream_xport_hash;
592 zend_string *stream_xport;
593
595
596 stream_xport_hash = php_stream_xport_get_hash();
598 ZEND_HASH_MAP_FOREACH_STR_KEY(stream_xport_hash, stream_xport) {
599 add_next_index_str(return_value, zend_string_copy(stream_xport));
601}
602/* }}} */
603
604/* {{{ Retrieves list of registered stream wrappers */
606{
607 HashTable *url_stream_wrappers_hash;
608 zend_string *stream_protocol;
609
611
612 url_stream_wrappers_hash = php_stream_get_url_stream_wrappers_hash();
614 ZEND_HASH_MAP_FOREACH_STR_KEY(url_stream_wrappers_hash, stream_protocol) {
615 if (stream_protocol) {
616 add_next_index_str(return_value, zend_string_copy(stream_protocol));
617 }
619
620}
621/* }}} */
622
623/* {{{ stream_select related functions */
624static int stream_array_to_fd_set(zval *stream_array, fd_set *fds, php_socket_t *max_fd)
625{
626 zval *elem;
627 php_stream *stream;
628 int cnt = 0;
629
630 if (Z_TYPE_P(stream_array) != IS_ARRAY) {
631 return 0;
632 }
633
634 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(stream_array), elem) {
635 /* Temporary int fd is needed for the STREAM data type on windows, passing this_fd directly to php_stream_cast()
636 would eventually bring a wrong result on x64. php_stream_cast() casts to int internally, and this will leave
637 the higher bits of a SOCKET variable uninitialized on systems with little endian. */
638 php_socket_t this_fd;
639
640 ZVAL_DEREF(elem);
641 php_stream_from_zval_no_verify(stream, elem);
642 if (stream == NULL) {
643 continue;
644 }
645 /* get the fd.
646 * NB: Most other code will NOT use the PHP_STREAM_CAST_INTERNAL flag
647 * when casting. It is only used here so that the buffered data warning
648 * is not displayed.
649 * */
650 if (SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)&this_fd, 1) && this_fd != -1) {
651
652 PHP_SAFE_FD_SET(this_fd, fds);
653
654 if (this_fd > *max_fd) {
655 *max_fd = this_fd;
656 }
657 cnt++;
658 }
660 return cnt ? 1 : 0;
661}
662
663static int stream_array_from_fd_set(zval *stream_array, fd_set *fds)
664{
665 zval *elem, *dest_elem;
666 HashTable *ht;
667 php_stream *stream;
668 int ret = 0;
670 zend_ulong num_ind;
671
672 if (Z_TYPE_P(stream_array) != IS_ARRAY) {
673 return 0;
674 }
675 ht = zend_new_array(zend_hash_num_elements(Z_ARRVAL_P(stream_array)));
676
677 ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(stream_array), num_ind, key, elem) {
678 php_socket_t this_fd;
679
680 ZVAL_DEREF(elem);
681 php_stream_from_zval_no_verify(stream, elem);
682 if (stream == NULL) {
683 continue;
684 }
685 /* get the fd
686 * NB: Most other code will NOT use the PHP_STREAM_CAST_INTERNAL flag
687 * when casting. It is only used here so that the buffered data warning
688 * is not displayed.
689 */
690 if (SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)&this_fd, 1) && this_fd != SOCK_ERR) {
691 if (PHP_SAFE_FD_ISSET(this_fd, fds)) {
692 if (!key) {
693 dest_elem = zend_hash_index_update(ht, num_ind, elem);
694 } else {
695 dest_elem = zend_hash_update(ht, key, elem);
696 }
697
698 zval_add_ref(dest_elem);
699 ret++;
700 continue;
701 }
702 }
704
705 /* destroy old array and add new one */
706 zval_ptr_dtor(stream_array);
707 ZVAL_ARR(stream_array, ht);
708
709 return ret;
710}
711
712static int stream_array_emulate_read_fd_set(zval *stream_array)
713{
714 zval *elem, *dest_elem;
715 HashTable *ht;
716 php_stream *stream;
717 int ret = 0;
718 zend_ulong num_ind;
720
721 if (Z_TYPE_P(stream_array) != IS_ARRAY) {
722 return 0;
723 }
724 ht = zend_new_array(zend_hash_num_elements(Z_ARRVAL_P(stream_array)));
725
726 ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(stream_array), num_ind, key, elem) {
727 ZVAL_DEREF(elem);
728 php_stream_from_zval_no_verify(stream, elem);
729 if (stream == NULL) {
730 continue;
731 }
732 if ((stream->writepos - stream->readpos) > 0) {
733 /* allow readable non-descriptor based streams to participate in stream_select.
734 * Non-descriptor streams will only "work" if they have previously buffered the
735 * data. Not ideal, but better than nothing.
736 * This branch of code also allows blocking streams with buffered data to
737 * operate correctly in stream_select.
738 * */
739 if (!key) {
740 dest_elem = zend_hash_index_update(ht, num_ind, elem);
741 } else {
742 dest_elem = zend_hash_update(ht, key, elem);
743 }
744 zval_add_ref(dest_elem);
745 ret++;
746 continue;
747 }
749
750 if (ret > 0) {
751 /* destroy old array and add new one */
752 zval_ptr_dtor(stream_array);
753 ZVAL_ARR(stream_array, ht);
754 } else {
756 }
757
758 return ret;
759}
760/* }}} */
761
762/* {{{ Runs the select() system call on the sets of streams with a timeout specified by tv_sec and tv_usec */
764{
765 zval *r_array, *w_array, *e_array;
766 struct timeval tv, *tv_p = NULL;
767 fd_set rfds, wfds, efds;
768 php_socket_t max_fd = 0;
769 int retval, sets = 0;
770 zend_long sec, usec = 0;
771 bool secnull;
772 bool usecnull = 1;
773 int set_count, max_set_count = 0;
774
776 Z_PARAM_ARRAY_EX2(r_array, 1, 1, 0)
777 Z_PARAM_ARRAY_EX2(w_array, 1, 1, 0)
778 Z_PARAM_ARRAY_EX2(e_array, 1, 1, 0)
779 Z_PARAM_LONG_OR_NULL(sec, secnull)
781 Z_PARAM_LONG_OR_NULL(usec, usecnull)
783
784 FD_ZERO(&rfds);
785 FD_ZERO(&wfds);
786 FD_ZERO(&efds);
787
788 if (r_array != NULL) {
789 set_count = stream_array_to_fd_set(r_array, &rfds, &max_fd);
790 if (set_count > max_set_count)
791 max_set_count = set_count;
792 sets += set_count;
793 }
794
795 if (w_array != NULL) {
796 set_count = stream_array_to_fd_set(w_array, &wfds, &max_fd);
797 if (set_count > max_set_count)
798 max_set_count = set_count;
799 sets += set_count;
800 }
801
802 if (e_array != NULL) {
803 set_count = stream_array_to_fd_set(e_array, &efds, &max_fd);
804 if (set_count > max_set_count)
805 max_set_count = set_count;
806 sets += set_count;
807 }
808
809 if (!sets) {
810 zend_value_error("No stream arrays were passed");
812 }
813
814 if (!PHP_SAFE_MAX_FD(max_fd, max_set_count)) {
816 }
817
818 if (secnull && !usecnull) {
819 if (usec != 0) {
820 zend_argument_value_error(5, "must be null when argument #4 ($seconds) is null");
822 }
823 }
824
825 /* If seconds is not set to null, build the timeval, else we wait indefinitely */
826 if (!secnull) {
827 if (sec < 0) {
828 zend_argument_value_error(4, "must be greater than or equal to 0");
830 } else if (usec < 0) {
831 zend_argument_value_error(5, "must be greater than or equal to 0");
833 }
834
835 /* Windows, Solaris and BSD do not like microsecond values which are >= 1 sec */
836 tv.tv_sec = (long)(sec + (usec / 1000000));
837 tv.tv_usec = (long)(usec % 1000000);
838 tv_p = &tv;
839 }
840
841 /* slight hack to support buffered data; if there is data sitting in the
842 * read buffer of any of the streams in the read array, let's pretend
843 * that we selected, but return only the readable sockets */
844 if (r_array != NULL) {
845 retval = stream_array_emulate_read_fd_set(r_array);
846 if (retval > 0) {
847 if (w_array != NULL) {
848 zval_ptr_dtor(w_array);
849 ZVAL_EMPTY_ARRAY(w_array);
850 }
851 if (e_array != NULL) {
852 zval_ptr_dtor(e_array);
853 ZVAL_EMPTY_ARRAY(e_array);
854 }
856 }
857 }
858
859 retval = php_select(max_fd+1, &rfds, &wfds, &efds, tv_p);
860
861 if (retval == -1) {
862 php_error_docref(NULL, E_WARNING, "Unable to select [%d]: %s (max_fd=%d)",
863 errno, strerror(errno), max_fd);
865 }
866
867 if (r_array != NULL) stream_array_from_fd_set(r_array, &rfds);
868 if (w_array != NULL) stream_array_from_fd_set(w_array, &wfds);
869 if (e_array != NULL) stream_array_from_fd_set(e_array, &efds);
870
872}
873/* }}} */
874
875/* {{{ stream_context related functions */
876static void user_space_stream_notifier(php_stream_context *context, int notifycode, int severity,
877 char *xmsg, int xcode, size_t bytes_sofar, size_t bytes_max, void * ptr)
878{
879 zval *callback = &context->notifier->ptr;
880 zval retval;
881 zval zvs[6];
882 int i;
883
884 ZVAL_LONG(&zvs[0], notifycode);
885 ZVAL_LONG(&zvs[1], severity);
886 if (xmsg) {
887 ZVAL_STRING(&zvs[2], xmsg);
888 } else {
889 ZVAL_NULL(&zvs[2]);
890 }
891 ZVAL_LONG(&zvs[3], xcode);
892 ZVAL_LONG(&zvs[4], bytes_sofar);
893 ZVAL_LONG(&zvs[5], bytes_max);
894
895 if (FAILURE == call_user_function(NULL, NULL, callback, &retval, 6, zvs)) {
896 php_error_docref(NULL, E_WARNING, "Failed to call user notifier");
897 }
898 for (i = 0; i < 6; i++) {
899 zval_ptr_dtor(&zvs[i]);
900 }
902}
903
904static void user_space_stream_notifier_dtor(php_stream_notifier *notifier)
905{
906 if (notifier && Z_TYPE(notifier->ptr) != IS_UNDEF) {
907 zval_ptr_dtor(&notifier->ptr);
908 ZVAL_UNDEF(&notifier->ptr);
909 }
910}
911
912static zend_result parse_context_options(php_stream_context *context, HashTable *options)
913{
914 zval *wval, *oval;
915 zend_string *wkey, *okey;
916
918 ZVAL_DEREF(wval);
919 if (wkey && Z_TYPE_P(wval) == IS_ARRAY) {
920 if (!HT_IS_PACKED(Z_ARRVAL_P(wval))) {
922 if (okey) {
924 }
926 }
927 } else {
928 zend_value_error("Options should have the form [\"wrappername\"][\"optionname\"] = $value");
929 return FAILURE;
930 }
932
933 return SUCCESS;
934}
935
936static zend_result parse_context_params(php_stream_context *context, HashTable *params)
937{
938 zval *tmp;
939
940 if (NULL != (tmp = zend_hash_str_find(params, "notification", sizeof("notification")-1))) {
941
942 if (context->notifier) {
944 context->notifier = NULL;
945 }
946
948 context->notifier->func = user_space_stream_notifier;
949 ZVAL_COPY(&context->notifier->ptr, tmp);
950 context->notifier->dtor = user_space_stream_notifier_dtor;
951 }
952 if (NULL != (tmp = zend_hash_str_find(params, "options", sizeof("options")-1))) {
953 if (Z_TYPE_P(tmp) == IS_ARRAY) {
954 return parse_context_options(context, Z_ARRVAL_P(tmp));
955 } else {
956 zend_type_error("Invalid stream/context parameter");
957 return FAILURE;
958 }
959 }
960
961 return SUCCESS;
962}
963
964/* given a zval which is either a stream or a context, return the underlying
965 * stream_context. If it is a stream that does not have a context assigned, it
966 * will create and assign a context and return that. */
967static php_stream_context *decode_context_param(zval *contextresource)
968{
970
972 if (context == NULL) {
973 php_stream *stream;
974
976
977 if (stream) {
978 context = PHP_STREAM_CONTEXT(stream);
979 if (context == NULL) {
980 /* Only way this happens is if file is opened with NO_DEFAULT_CONTEXT
981 param, but then something is called which requires a context.
982 Don't give them the default one though since they already said they
983 didn't want it. */
985 stream->ctx = context->res;
986 }
987 }
988 }
989
990 return context;
991}
992/* }}} */
993
994/* {{{ Retrieve options for a stream/wrapper/context */
996{
997 zval *zcontext;
999
1003
1004 context = decode_context_param(zcontext);
1005 if (!context) {
1006 zend_argument_type_error(1, "must be a valid stream/context");
1007 RETURN_THROWS();
1008 }
1009
1010 ZVAL_COPY(return_value, &context->options);
1011}
1012/* }}} */
1013
1014/* {{{ Set an option for a wrapper */
1016{
1017 zval *zcontext = NULL;
1019 zend_string *wrappername;
1021 char *optionname = NULL;
1022 size_t optionname_len;
1023 zval *zvalue = NULL;
1024
1025 if (ZEND_NUM_ARGS() == 2) {
1026 zend_error(E_DEPRECATED, "Calling stream_context_set_option() with 2 arguments is deprecated, "
1027 "use stream_context_set_options() instead"
1028 );
1029 if (UNEXPECTED(EG(exception))) {
1030 RETURN_THROWS();
1031 }
1032 }
1033
1036 Z_PARAM_ARRAY_HT_OR_STR(options, wrappername)
1038 Z_PARAM_STRING_OR_NULL(optionname, optionname_len)
1039 Z_PARAM_ZVAL(zvalue)
1041
1042 /* figure out where the context is coming from exactly */
1043 if (!(context = decode_context_param(zcontext))) {
1044 zend_argument_type_error(1, "must be a valid stream/context");
1045 RETURN_THROWS();
1046 }
1047
1048 if (options) {
1049 if (optionname) {
1050 zend_argument_value_error(3, "must be null when argument #2 ($wrapper_or_options) is an array");
1051 RETURN_THROWS();
1052 }
1053
1054 if (zvalue) {
1055 zend_argument_value_error(4, "cannot be provided when argument #2 ($wrapper_or_options) is an array");
1056 RETURN_THROWS();
1057 }
1058
1059 if (parse_context_options(context, options) == FAILURE) {
1060 RETURN_THROWS();
1061 }
1062
1064 } else {
1065 if (!optionname) {
1066 zend_argument_value_error(3, "cannot be null when argument #2 ($wrapper_or_options) is a string");
1067 RETURN_THROWS();
1068 }
1069 if (!zvalue) {
1070 zend_argument_value_error(4, "must be provided when argument #2 ($wrapper_or_options) is a string");
1071 RETURN_THROWS();
1072 }
1073 php_stream_context_set_option(context, ZSTR_VAL(wrappername), optionname, zvalue);
1075 }
1076}
1077/* }}} */
1078
1080{
1081 zval *zcontext = NULL;
1084
1089
1090 /* figure out where the context is coming from exactly */
1091 if (!(context = decode_context_param(zcontext))) {
1092 zend_argument_type_error(1, "must be a valid stream/context");
1093 RETURN_THROWS();
1094 }
1095
1096 if (parse_context_options(context, options) == FAILURE) {
1097 RETURN_THROWS();
1098 }
1099
1101}
1102
1103/* {{{ Set parameters for a file context */
1105{
1106 HashTable *params;
1107 zval *zcontext;
1109
1112 Z_PARAM_ARRAY_HT(params)
1114
1115 context = decode_context_param(zcontext);
1116 if (!context) {
1117 zend_argument_type_error(1, "must be a valid stream/context");
1118 RETURN_THROWS();
1119 }
1120
1121 if (parse_context_params(context, params) == FAILURE) {
1122 RETURN_THROWS();
1123 }
1124
1126}
1127/* }}} */
1128
1129/* {{{ Get parameters of a file context */
1131{
1132 zval *zcontext;
1134
1138
1139 context = decode_context_param(zcontext);
1140 if (!context) {
1141 zend_argument_type_error(1, "must be a valid stream/context");
1142 RETURN_THROWS();
1143 }
1144
1146 if (context->notifier && Z_TYPE(context->notifier->ptr) != IS_UNDEF && context->notifier->func == user_space_stream_notifier) {
1147 Z_TRY_ADDREF(context->notifier->ptr);
1148 add_assoc_zval_ex(return_value, "notification", sizeof("notification")-1, &context->notifier->ptr);
1149 }
1150 Z_TRY_ADDREF(context->options);
1151 add_assoc_zval_ex(return_value, "options", sizeof("options")-1, &context->options);
1152}
1153/* }}} */
1154
1155/* {{{ Get a handle on the default file/stream context and optionally set parameters */
1157{
1158 HashTable *params = NULL;
1160
1165
1166 if (FG(default_context) == NULL) {
1167 FG(default_context) = php_stream_context_alloc();
1168 }
1169 context = FG(default_context);
1170
1171 if (params) {
1172 if (parse_context_options(context, params) == FAILURE) {
1173 RETURN_THROWS();
1174 }
1175 }
1176
1178}
1179/* }}} */
1180
1181/* {{{ Set default file/stream context, returns the context as a resource */
1183{
1186
1190
1191 if (FG(default_context) == NULL) {
1192 FG(default_context) = php_stream_context_alloc();
1193 }
1194 context = FG(default_context);
1195
1196 if (parse_context_options(context, options) == FAILURE) {
1197 RETURN_THROWS();
1198 }
1199
1201}
1202/* }}} */
1203
1204/* {{{ Create a file context and optionally set parameters */
1206{
1208 HashTable *params = NULL;
1210
1216
1218
1219 if (options) {
1220 if (parse_context_options(context, options) == FAILURE) {
1221 RETURN_THROWS();
1222 }
1223 }
1224
1225 if (params) {
1226 if (parse_context_params(context, params) == FAILURE) {
1227 RETURN_THROWS();
1228 }
1229 }
1230
1231 RETURN_RES(context->res);
1232}
1233/* }}} */
1234
1235/* {{{ streams filter functions */
1236static void apply_filter_to_stream(int append, INTERNAL_FUNCTION_PARAMETERS)
1237{
1238 zval *zstream;
1239 php_stream *stream;
1240 char *filtername;
1241 size_t filternamelen;
1242 zend_long read_write = 0;
1243 zval *filterparams = NULL;
1244 php_stream_filter *filter = NULL;
1245 int ret;
1246
1248 Z_PARAM_RESOURCE(zstream)
1249 Z_PARAM_STRING(filtername, filternamelen)
1251 Z_PARAM_LONG(read_write)
1252 Z_PARAM_ZVAL(filterparams)
1254
1255 php_stream_from_zval(stream, zstream);
1256
1257 if ((read_write & PHP_STREAM_FILTER_ALL) == 0) {
1258 /* Chain not specified.
1259 * Examine stream->mode to determine which filters are needed
1260 * There's no harm in attaching a filter to an unused chain,
1261 * but why waste the memory and clock cycles?
1262 */
1263 if (strchr(stream->mode, 'r') || strchr(stream->mode, '+')) {
1264 read_write |= PHP_STREAM_FILTER_READ;
1265 }
1266 if (strchr(stream->mode, 'w') || strchr(stream->mode, '+') || strchr(stream->mode, 'a')) {
1267 read_write |= PHP_STREAM_FILTER_WRITE;
1268 }
1269 }
1270
1271 if (read_write & PHP_STREAM_FILTER_READ) {
1272 filter = php_stream_filter_create(filtername, filterparams, php_stream_is_persistent(stream));
1273 if (filter == NULL) {
1275 }
1276
1277 if (append) {
1278 ret = php_stream_filter_append_ex(&stream->readfilters, filter);
1279 } else {
1280 ret = php_stream_filter_prepend_ex(&stream->readfilters, filter);
1281 }
1282 if (ret != SUCCESS) {
1283 php_stream_filter_remove(filter, 1);
1285 }
1286 }
1287
1288 if (read_write & PHP_STREAM_FILTER_WRITE) {
1289 filter = php_stream_filter_create(filtername, filterparams, php_stream_is_persistent(stream));
1290 if (filter == NULL) {
1292 }
1293
1294 if (append) {
1295 ret = php_stream_filter_append_ex(&stream->writefilters, filter);
1296 } else {
1297 ret = php_stream_filter_prepend_ex(&stream->writefilters, filter);
1298 }
1299 if (ret != SUCCESS) {
1300 php_stream_filter_remove(filter, 1);
1302 }
1303 }
1304
1305 if (filter) {
1307 GC_ADDREF(filter->res);
1308 RETURN_RES(filter->res);
1309 } else {
1311 }
1312}
1313/* }}} */
1314
1315/* {{{ Prepend a filter to a stream */
1317{
1318 apply_filter_to_stream(0, INTERNAL_FUNCTION_PARAM_PASSTHRU);
1319}
1320/* }}} */
1321
1322/* {{{ Append a filter to a stream */
1324{
1325 apply_filter_to_stream(1, INTERNAL_FUNCTION_PARAM_PASSTHRU);
1326}
1327/* }}} */
1328
1329/* {{{ Flushes any data in the filter's internal buffer, removes it from the chain, and frees the resource */
1331{
1332 zval *zfilter;
1333 php_stream_filter *filter;
1334
1336 Z_PARAM_RESOURCE(zfilter)
1338
1339 filter = zend_fetch_resource(Z_RES_P(zfilter), "stream filter", php_file_le_stream_filter());
1340 if (!filter) {
1341 RETURN_THROWS();
1342 }
1343
1344 if (php_stream_filter_flush(filter, 1) == FAILURE) {
1345 php_error_docref(NULL, E_WARNING, "Unable to flush filter, not removing");
1347 }
1348
1349 zend_list_close(Z_RES_P(zfilter));
1350 php_stream_filter_remove(filter, 1);
1352}
1353/* }}} */
1354
1355/* {{{ Read up to maxlen bytes from a stream or until the ending string is found */
1357{
1358 char *str = NULL;
1359 size_t str_len = 0;
1360 zend_long max_length;
1361 zval *zstream;
1363 php_stream *stream;
1364
1366 Z_PARAM_RESOURCE(zstream)
1367 Z_PARAM_LONG(max_length)
1369 Z_PARAM_STRING(str, str_len)
1371
1372 if (max_length < 0) {
1373 zend_argument_value_error(2, "must be greater than or equal to 0");
1374 RETURN_THROWS();
1375 }
1376 if (!max_length) {
1377 max_length = PHP_SOCK_CHUNK_SIZE;
1378 }
1379
1380 php_stream_from_zval(stream, zstream);
1381
1382 if ((buf = php_stream_get_record(stream, max_length, str, str_len))) {
1383 RETURN_STR(buf);
1384 } else {
1386 }
1387}
1388
1389/* }}} */
1390
1391/* {{{ Set blocking/non-blocking mode on a socket or stream */
1393{
1394 zval *zstream;
1395 bool block;
1396 php_stream *stream;
1397
1399 Z_PARAM_RESOURCE(zstream)
1400 Z_PARAM_BOOL(block)
1402
1403 php_stream_from_zval(stream, zstream);
1404
1405 if (php_stream_set_option(stream, PHP_STREAM_OPTION_BLOCKING, block, NULL) == -1) {
1407 }
1408
1410}
1411
1412/* }}} */
1413
1414/* {{{ Set timeout on stream read to seconds + microseonds */
1415#if defined(HAVE_SYS_TIME_H) || defined(PHP_WIN32)
1417{
1418 zval *socket;
1419 zend_long seconds, microseconds = 0;
1420 struct timeval t;
1421 php_stream *stream;
1422 int argc = ZEND_NUM_ARGS();
1423
1425 Z_PARAM_RESOURCE(socket)
1426 Z_PARAM_LONG(seconds)
1428 Z_PARAM_LONG(microseconds)
1430
1431 php_stream_from_zval(stream, socket);
1432
1433#ifdef PHP_WIN32
1434 t.tv_sec = (long)seconds;
1435
1436 if (argc == 3) {
1437 t.tv_usec = (long)(microseconds % 1000000);
1438 t.tv_sec +=(long)(microseconds / 1000000);
1439 } else {
1440 t.tv_usec = 0;
1441 }
1442#else
1443 t.tv_sec = seconds;
1444
1445 if (argc == 3) {
1446 t.tv_usec = microseconds % 1000000;
1447 t.tv_sec += microseconds / 1000000;
1448 } else {
1449 t.tv_usec = 0;
1450 }
1451#endif
1452
1455 }
1456
1458}
1459#endif /* HAVE_SYS_TIME_H || defined(PHP_WIN32) */
1460/* }}} */
1461
1462/* {{{ Set file write buffer */
1464{
1465 zval *arg1;
1466 int ret;
1468 size_t buff;
1469 php_stream *stream;
1470
1475
1476 php_stream_from_zval(stream, arg1);
1477
1478 buff = arg2;
1479
1480 /* if buff is 0 then set to non-buffered */
1481 if (buff == 0) {
1483 } else {
1485 }
1486
1487 RETURN_LONG(ret == 0 ? 0 : EOF);
1488}
1489/* }}} */
1490
1491/* {{{ Set the stream chunk size */
1493{
1494 int ret;
1495 zend_long csize;
1496 zval *zstream;
1497 php_stream *stream;
1498
1500 Z_PARAM_RESOURCE(zstream)
1501 Z_PARAM_LONG(csize)
1503
1504 if (csize <= 0) {
1505 zend_argument_value_error(2, "must be greater than 0");
1506 RETURN_THROWS();
1507 }
1508 /* stream.chunk_size is actually a size_t, but php_stream_set_option
1509 * can only use an int to accept the new value and return the old one.
1510 * In any case, values larger than INT_MAX for a chunk size make no sense.
1511 */
1512 if (csize > INT_MAX) {
1513 zend_argument_value_error(2, "is too large");
1514 RETURN_THROWS();
1515 }
1516
1517 php_stream_from_zval(stream, zstream);
1518
1520
1521 RETURN_LONG(ret > 0 ? (zend_long)ret : (zend_long)EOF);
1522}
1523/* }}} */
1524
1525/* {{{ Set file read buffer */
1527{
1528 zval *arg1;
1529 int ret;
1531 size_t buff;
1532 php_stream *stream;
1533
1538
1539 php_stream_from_zval(stream, arg1);
1540
1541 buff = arg2;
1542
1543 /* if buff is 0 then set to non-buffered */
1544 if (buff == 0) {
1546 } else {
1548 }
1549
1550 RETURN_LONG(ret == 0 ? 0 : EOF);
1551}
1552/* }}} */
1553
1554/* {{{ Enable or disable a specific kind of crypto on the stream */
1556{
1557 zend_long cryptokind = 0;
1558 zval *zstream, *zsessstream = NULL;
1559 php_stream *stream, *sessstream = NULL;
1560 bool enable, cryptokindnull = 1;
1561 int ret;
1562
1564 Z_PARAM_RESOURCE(zstream)
1565 Z_PARAM_BOOL(enable)
1567 Z_PARAM_LONG_OR_NULL(cryptokind, cryptokindnull)
1568 Z_PARAM_RESOURCE_OR_NULL(zsessstream)
1570
1571 php_stream_from_zval(stream, zstream);
1572
1573 if (enable) {
1574 if (cryptokindnull) {
1575 zval *val;
1576
1577 if (!GET_CTX_OPT(stream, "ssl", "crypto_method", val)) {
1578 zend_argument_value_error(3, "must be specified when enabling encryption");
1579 RETURN_THROWS();
1580 }
1581
1582 cryptokind = Z_LVAL_P(val);
1583 }
1584
1585 if (zsessstream) {
1586 php_stream_from_zval(sessstream, zsessstream);
1587 }
1588
1589 if (php_stream_xport_crypto_setup(stream, cryptokind, sessstream) < 0) {
1591 }
1592 }
1593
1594 ret = php_stream_xport_crypto_enable(stream, enable);
1595 switch (ret) {
1596 case -1:
1598
1599 case 0:
1600 RETURN_LONG(0);
1601
1602 default:
1604 }
1605}
1606/* }}} */
1607
1608/* {{{ Determine what file will be opened by calls to fopen() with a relative path */
1610{
1611 zend_string *filename;
1612 zend_string *resolved_path;
1613
1615 Z_PARAM_PATH_STR(filename)
1617
1618 resolved_path = zend_resolve_path(filename);
1619
1620 if (resolved_path) {
1621 RETURN_STR(resolved_path);
1622 }
1624}
1625/* }}} */
1626
1627/* {{{ */
1629{
1630 zval *zstream;
1631 php_stream *stream = NULL;
1632 php_stream_wrapper *wrapper = NULL;
1633
1635 Z_PARAM_ZVAL(zstream)
1637
1638 if (Z_TYPE_P(zstream) == IS_RESOURCE) {
1639 php_stream_from_zval(stream, zstream);
1640 wrapper = stream->wrapper;
1641 } else {
1642 if (!try_convert_to_string(zstream)) {
1643 RETURN_THROWS();
1644 }
1645
1646 wrapper = php_stream_locate_url_wrapper(Z_STRVAL_P(zstream), NULL, 0);
1647 }
1648
1649 if (!wrapper) {
1651 }
1652
1653 RETURN_BOOL(wrapper->is_url==0);
1654}
1655/* }}} */
1656
1657/* {{{ Tells whether the stream supports locking through flock(). */
1659{
1660 php_stream *stream;
1661 zval *zsrc;
1662
1664 Z_PARAM_RESOURCE(zsrc)
1666
1667 php_stream_from_zval(stream, zsrc);
1668
1669 if (!php_stream_supports_lock(stream)) {
1671 }
1672
1674}
1675
1676/* {{{ Check if a stream is a TTY. */
1678{
1679 zval *zsrc;
1680 php_stream *stream;
1681 php_socket_t fileno;
1682
1684 Z_PARAM_RESOURCE(zsrc)
1686
1687 php_stream_from_zval(stream, zsrc);
1688
1689 /* get the fd.
1690 * NB: Most other code will NOT use the PHP_STREAM_CAST_INTERNAL flag when casting.
1691 * It is only used here so that the buffered data warning is not displayed.
1692 */
1696 php_stream_cast(stream, PHP_STREAM_AS_FD | PHP_STREAM_CAST_INTERNAL, (void*)&fileno, 0);
1697 } else {
1699 }
1700
1701#ifdef PHP_WIN32
1702 /* Check if the Windows standard handle is redirected to file */
1704#elif defined(HAVE_UNISTD_H)
1705 /* Check if the file descriptor identifier is a terminal */
1706 RETVAL_BOOL(isatty(fileno));
1707#else
1708 {
1709 zend_stat_t stat = {0};
1710 RETVAL_BOOL(zend_fstat(fileno, &stat) == 0 && (stat.st_mode & /*S_IFMT*/0170000) == /*S_IFCHR*/0020000);
1711 }
1712#endif
1713}
1714
1715#ifdef PHP_WIN32
1716/* {{{ Get or set VT100 support for the specified stream associated to an
1717 output buffer of a Windows console.
1718*/
1720{
1721 zval *zsrc;
1722 php_stream *stream;
1723 bool enable, enable_is_null = 1;
1724 zend_long fileno;
1725
1727 Z_PARAM_RESOURCE(zsrc)
1729 Z_PARAM_BOOL_OR_NULL(enable, enable_is_null)
1731
1732 php_stream_from_zval(stream, zsrc);
1733
1734 /* get the fd.
1735 * NB: Most other code will NOT use the PHP_STREAM_CAST_INTERNAL flag when casting.
1736 * It is only used here so that the buffered data warning is not displayed.
1737 */
1741 php_stream_cast(stream, PHP_STREAM_AS_FD | PHP_STREAM_CAST_INTERNAL, (void*)&fileno, 0);
1742 } else {
1743 if (!enable_is_null) {
1745 NULL,
1746 E_WARNING,
1747 "not able to analyze the specified stream"
1748 );
1749 }
1751 }
1752
1753 /* Check if the file descriptor is a console */
1756 }
1757
1758 if (enable_is_null) {
1759 /* Check if the Windows standard handle has VT100 control codes enabled */
1762 }
1763 else {
1765 }
1766 }
1767 else {
1768 /* Enable/disable VT100 control codes support for the specified Windows standard handle */
1769 if (php_win32_console_fileno_set_vt100(fileno, enable ? TRUE : FALSE)) {
1771 }
1772 else {
1774 }
1775 }
1776}
1777#endif
1778
1779#ifdef HAVE_SHUTDOWN
1780/* {{{ causes all or part of a full-duplex connection on the socket associated
1781 with stream to be shut down. If how is SHUT_RD, further receptions will
1782 be disallowed. If how is SHUT_WR, further transmissions will be disallowed.
1783 If how is SHUT_RDWR, further receptions and transmissions will be
1784 disallowed. */
1786{
1787 zend_long how;
1788 zval *zstream;
1789 php_stream *stream;
1790
1792 Z_PARAM_RESOURCE(zstream)
1793 Z_PARAM_LONG(how)
1795
1796 if (how != STREAM_SHUT_RD &&
1797 how != STREAM_SHUT_WR &&
1798 how != STREAM_SHUT_RDWR) {
1799 zend_argument_value_error(2, "must be one of STREAM_SHUT_RD, STREAM_SHUT_WR, or STREAM_SHUT_RDWR");
1800 RETURN_THROWS();
1801 }
1802
1803 php_stream_from_zval(stream, zstream);
1804
1806}
1807/* }}} */
1808#endif
size_t len
Definition apprentice.c:174
bool exception
Definition assert.c:30
zval callback
Definition assert.c:25
stream_socket_get_name($socket, bool $remote)
stream_socket_recvfrom($socket, int $length, int $flags=0, &$address=null)
stream_socket_server(string $address, &$error_code=null, &$error_message=null, int $flags=STREAM_SERVER_BIND|STREAM_SERVER_LISTEN, $context=null)
stream_socket_client(string $address, &$error_code=null, &$error_message=null, ?float $timeout=null, int $flags=STREAM_CLIENT_CONNECT, $context=null)
stream_context_create(?array $options=null, ?array $params=null)
stream_socket_shutdown($stream, int $mode)
stream_socket_enable_crypto($stream, bool $enable, ?int $crypto_method=null, $session_stream=null)
stream_socket_accept($socket, ?float $timeout=null, &$peer_name=null)
stream_filter_prepend($stream, string $filter_name, int $mode=0, mixed $params=UNKNOWN)
stream_isatty($stream)
stream_context_get_default(?array $options=null)
stream_get_meta_data($stream)
stream_copy_to_stream($from, $to, ?int $length=null, int $offset=0)
stream_get_line($stream, int $length, string $ending="")
sapi_windows_vt100_support($stream, ?bool $enable=null)
stream_context_set_option($context, array|string $wrapper_or_options, ?string $option_name=null, mixed $value=UNKNOWN)
stream_select(?array &$read, ?array &$write, ?array &$except, ?int $seconds, ?int $microseconds=null)
stream_filter_append($stream, string $filter_name, int $mode=0, mixed $params=UNKNOWN)
stream_socket_sendto($socket, string $data, int $flags=0, string $address="")
stream_is_local($stream)
stream_resolve_include_path(string $filename)
stream_context_set_params($context, array $params)
stream_context_set_default(array $options)
stream_set_timeout($stream, int $seconds, int $microseconds=0)
stream_socket_pair(int $domain, int $type, int $protocol)
stream_get_wrappers()
stream_context_set_options($context, array $options)
stream_filter_remove($stream_filter)
stream_get_transports()
stream_set_write_buffer($stream, int $size)
stream_set_chunk_size($stream, int $size)
stream_supports_lock($stream)
stat(string $filename)
stream_context_get_options($stream_or_context)
stream_get_contents($stream, ?int $length=null, int $offset=-1)
stream_context_get_params($context)
stream_set_blocking($stream, bool $enable)
strchr(string $haystack, string $needle, bool $before_needle=false)
stream_set_read_buffer($stream, int $size)
PHP_WINUTIL_API BOOL php_win32_console_fileno_has_vt100(zend_long fileno)
Definition console.c:36
PHP_WINUTIL_API BOOL php_win32_console_fileno_is_console(zend_long fileno)
Definition console.c:22
PHP_WINUTIL_API BOOL php_win32_console_fileno_set_vt100(zend_long fileno, BOOL enable)
Definition console.c:58
unsigned int socklen_t
Definition fastcgi.c:87
zend_ffi_type * type
Definition ffi.c:3812
void * ptr
Definition ffi.c:3814
char * err
Definition ffi.c:3029
zval * val
Definition ffi.c:4262
HashTable * ht
Definition ffi.c:4838
zend_ffi_ctype_name_buf buf
Definition ffi.c:4685
PHPAPI int php_le_stream_context(void)
Definition file.c:114
const SEEK_CUR
Definition file.stub.php:16
zval * zcontext
zend_string * contents
zend_long maxlen
bool maxlen_is_null
#define TRUE
Definition gd_gd.c:7
#define FALSE
Definition gd_gd.c:8
#define SEEK_SET
Definition gd_io_file.c:20
#define NULL
Definition gdcache.h:45
#define SUCCESS
Definition hash_sha3.c:261
foreach($dp as $el) foreach( $dp as $el) if( $pass2< 2) echo ""
PHPAPI php_stream_filter * php_stream_filter_create(const char *filtername, zval *filterparams, uint8_t persistent)
Definition filter.c:220
PHPAPI int php_stream_filter_prepend_ex(php_stream_filter_chain *chain, php_stream_filter *filter)
Definition filter.c:285
PHPAPI int php_stream_filter_append_ex(php_stream_filter_chain *chain, php_stream_filter *filter)
Definition filter.c:306
PHPAPI php_stream_filter * php_stream_filter_remove(php_stream_filter *filter, int call_dtor)
Definition filter.c:483
PHPAPI ZEND_COLD void php_error_docref(const char *docref, int type, const char *format,...)
Definition main.c:1173
PHPAPI char * php_socket_strerror(long err, char *buf, size_t bufsize)
Definition network.c:1045
#define SOCK_ERR
Definition network.c:85
PHPAPI zend_result php_network_parse_network_address_with_port(const char *addr, size_t addrlen, struct sockaddr *sa, socklen_t *sl)
Definition network.c:552
#define PHP_FUNCTION
Definition php.h:364
#define INT_MAX
Definition php.h:237
unsigned const char * pos
Definition php_ffi.h:52
PHP_JSON_API size_t int options
Definition php_json.h:102
#define PHP_SAFE_FD_ISSET(fd, set)
#define PHP_SOCK_CHUNK_SIZE
#define PHP_SAFE_FD_SET(fd, set)
#define php_stream_sock_open_from_socket(socket, persistent)
#define php_socket_errno()
Definition php_network.h:60
#define PHP_SAFE_MAX_FD(m, n)
int php_socket_t
unsigned char key[REFLECTION_KEY_LEN]
PHPAPI void php_stream_notification_free(php_stream_notifier *notifier)
Definition streams.c:2399
PHPAPI php_stream_notifier * php_stream_notification_alloc(void)
Definition streams.c:2394
#define php_stream_context_from_zval(zcontext, nocontext)
#define php_stream_context_to_zval(context, zval)
PHPAPI php_stream_context * php_stream_context_alloc(void)
Definition streams.c:2383
PHPAPI void php_stream_context_set_option(php_stream_context *context, const char *wrappername, const char *optionname, zval *optionvalue)
Definition streams.c:2418
struct _php_stream_notifier php_stream_notifier
#define PHP_STREAM_FILTER_ALL
#define php_stream_filter_flush(filter, finish)
#define PHP_STREAM_FILTER_WRITE
#define PHP_STREAM_FILTER_READ
#define php_stream_xport_create(name, namelen, options, flags, persistent_id, timeout, context, estr, ecode)
PHPAPI int php_stream_xport_crypto_enable(php_stream *stream, int activate)
Definition transports.c:378
#define STREAM_XPORT_SERVER
#define STREAM_XPORT_BIND
PHPAPI int php_stream_xport_accept(php_stream *stream, php_stream **client, zend_string **textaddr, void **addr, socklen_t *addrlen, struct timeval *timeout, zend_string **error_text)
Definition transports.c:289
#define STREAM_XPORT_CONNECT_ASYNC
PHPAPI HashTable * php_stream_xport_get_hash(void)
Definition transports.c:23
PHPAPI int php_stream_xport_shutdown(php_stream *stream, stream_shutdown_t how)
Definition transports.c:509
#define STREAM_XPORT_CONNECT
PHPAPI int php_stream_xport_get_name(php_stream *stream, int want_peer, zend_string **textaddr, void **addr, socklen_t *addrlen)
Definition transports.c:327
PHPAPI int php_stream_xport_crypto_setup(php_stream *stream, php_stream_xport_crypt_method_t crypto_method, php_stream *session_stream)
Definition transports.c:357
#define STREAM_XPORT_CLIENT
@ STREAM_SHUT_RD
@ STREAM_SHUT_WR
@ STREAM_SHUT_RDWR
#define STREAM_XPORT_LISTEN
PHPAPI int php_stream_xport_recvfrom(php_stream *stream, char *buf, size_t buflen, int flags, void **addr, socklen_t *addrlen, zend_string **textaddr)
Definition transports.c:400
PHPAPI int php_stream_xport_sendto(php_stream *stream, const char *buf, size_t buflen, int flags, void *addr, socklen_t addrlen)
Definition transports.c:469
#define php_stream_cast(stream, as, ret, show_err)
PHPAPI zend_string * php_stream_get_record(php_stream *stream, size_t maxlen, const char *delim, size_t delim_len)
Definition streams.c:1062
PHPAPI int php_file_le_stream_filter(void)
Definition streams.c:52
struct _php_stream php_stream
Definition php_streams.h:96
struct _php_stream_context php_stream_context
Definition php_streams.h:98
#define REPORT_ERRORS
#define PHP_STREAM_OPTION_BLOCKING
#define PHP_STREAM_AS_FD_FOR_SELECT
#define php_stream_from_zval(xstr, pzval)
#define PHP_STREAM_OPTION_SET_CHUNK_SIZE
struct _php_stream_filter php_stream_filter
Definition php_streams.h:99
#define php_stream_populate_meta_data(stream, zv)
#define php_stream_auto_cleanup(stream)
#define PHP_STREAM_COPY_ALL
#define PHP_STREAM_FLAG_NO_SEEK
#define PHP_STREAM_BUFFER_NONE
#define php_stream_seek(stream, offset, whence)
#define php_stream_supports_lock(stream)
#define php_stream_to_zval(stream, zval)
#define php_stream_can_cast(stream, as)
#define PHP_STREAM_OPTION_WRITE_BUFFER
#define php_stream_eof(stream)
#define php_stream_free(stream, close_options)
#define PHP_STREAM_CONTEXT(stream)
#define PHP_STREAM_FREE_CLOSE
#define php_stream_tell(stream)
#define php_stream_is_persistent(stream)
#define PHP_STREAM_OPTION_READ_TIMEOUT
#define php_stream_copy_to_mem(src, maxlen, persistent)
#define PHP_STREAM_OPTION_READ_BUFFER
#define PHP_STREAM_BUFFER_FULL
#define php_stream_get_url_stream_wrappers_hash()
PHPAPI int php_file_le_pstream(void)
Definition streams.c:47
#define php_stream_from_zval_no_verify(xstr, pzval)
struct _php_stream_wrapper php_stream_wrapper
Definition php_streams.h:97
#define php_stream_copy_to_stream_ex(src, dest, maxlen, len)
PHPAPI php_stream_wrapper * php_stream_locate_url_wrapper(const char *path, const char **path_for_open, int options)
Definition streams.c:1964
#define php_stream_set_option(stream, option, value, ptrvalue)
#define PHP_STREAM_OPTION_RETURN_OK
#define PHP_STREAM_AS_FD
PHPAPI int php_file_le_stream(void)
Definition streams.c:42
#define PHP_STREAM_CAST_INTERNAL
PHPAPI zend_string * php_addslashes(zend_string *str)
Definition string.c:4073
zend_constant * data
struct timeval tv
Definition session.c:1280
#define spprintf
Definition spprintf.h:29
#define PHP_FILE_NO_DEFAULT_CONTEXT
Definition file.h:61
#define PHP_TIMEOUT_ULL_MAX
Definition file.h:64
#define FG(v)
Definition file.h:117
#define php_select(m, r, w, e, t)
unsigned long long php_timeout_ull
#define GET_CTX_OPT(stream, wrapper, name, val)
#define PHP_STREAM_CLIENT_ASYNC_CONNECT
#define PHP_STREAM_CLIENT_PERSISTENT
#define PHP_STREAM_CLIENT_CONNECT
const php_stream_filter_ops * fops
php_stream_filter * next
const char * label
int(* seek)(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffset)
const php_stream_wrapper_ops * wops
const php_stream_ops * ops
uint32_t flags
zend_off_t readpos
zend_resource * ctx
zend_resource * res
php_stream_wrapper * wrapper
char * orig_path
char mode[16]
zend_off_t writepos
Definition dce.c:49
PHPAPI int socketpair(int domain, int type, int protocol, SOCKET sock[2])
Definition sockets.c:94
#define close(a)
#define errno
ZEND_API ZEND_COLD void zend_type_error(const char *format,...)
Definition zend.c:1824
ZEND_API ZEND_COLD void zend_value_error(const char *format,...)
Definition zend.c:1849
ZEND_API ZEND_COLD void zend_error(int type, const char *format,...)
Definition zend.c:1666
ZEND_API zend_string *(* zend_resolve_path)(zend_string *filename)
Definition zend.c:94
#define INTERNAL_FUNCTION_PARAMETERS
Definition zend.h:49
#define INTERNAL_FUNCTION_PARAM_PASSTHRU
Definition zend.h:50
ZEND_API void add_assoc_zval_ex(zval *arg, const char *key, size_t key_len, zval *value)
Definition zend_API.c:2027
ZEND_API zend_result add_next_index_resource(zval *arg, zend_resource *r)
Definition zend_API.c:2159
ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format,...)
Definition zend_API.c:433
ZEND_API ZEND_COLD void zend_argument_type_error(uint32_t arg_num, const char *format,...)
Definition zend_API.c:423
ZEND_API zend_result add_next_index_string(zval *arg, const char *str)
Definition zend_API.c:2186
ZEND_API zend_result add_next_index_str(zval *arg, zend_string *str)
Definition zend_API.c:2177
#define Z_PARAM_PATH_STR(dest)
Definition zend_API.h:2041
#define ZEND_NUM_ARGS()
Definition zend_API.h:530
#define Z_PARAM_ARRAY_EX2(dest, check_null, deref, separate)
Definition zend_API.h:1671
#define ZEND_PARSE_PARAMETERS_END()
Definition zend_API.h:1641
#define RETURN_FALSE
Definition zend_API.h:1058
#define Z_PARAM_ARRAY_HT_OR_NULL(dest)
Definition zend_API.h:1855
#define Z_PARAM_RESOURCE(dest)
Definition zend_API.h:2056
#define ZEND_PARSE_PARAMETERS_NONE()
Definition zend_API.h:1623
#define ZVAL_STRING(z, s)
Definition zend_API.h:956
#define Z_PARAM_OPTIONAL
Definition zend_API.h:1667
#define Z_PARAM_STRING(dest, dest_len)
Definition zend_API.h:2071
#define Z_PARAM_STR(dest)
Definition zend_API.h:2086
#define Z_PARAM_STRING_OR_NULL(dest, dest_len)
Definition zend_API.h:2074
#define Z_PARAM_DOUBLE_OR_NULL(dest, is_null)
Definition zend_API.h:1806
#define ZEND_PARSE_PARAMETERS_START(min_num_args, max_num_args)
Definition zend_API.h:1620
#define Z_PARAM_BOOL_OR_NULL(dest, is_null)
Definition zend_API.h:1729
#define ZEND_TRY_ASSIGN_REF_LONG(zv, lval)
Definition zend_API.h:1205
#define Z_PARAM_ARRAY_HT_OR_STR(dest_ht, dest_str)
Definition zend_API.h:2151
#define ZEND_TRY_ASSIGN_REF_NULL(zv)
Definition zend_API.h:1117
#define Z_PARAM_LONG(dest)
Definition zend_API.h:1896
#define RETURN_LONG(l)
Definition zend_API.h:1037
#define RETURN_BOOL(b)
Definition zend_API.h:1035
#define RETURN_NEW_STR(s)
Definition zend_API.h:1041
#define RETURN_THROWS()
Definition zend_API.h:1060
#define Z_PARAM_ARRAY_HT(dest)
Definition zend_API.h:1852
#define RETURN_STR(s)
Definition zend_API.h:1039
#define RETVAL_BOOL(b)
Definition zend_API.h:1009
#define ZEND_TRY_ASSIGN_REF_EMPTY_STRING(zv)
Definition zend_API.h:1249
#define Z_PARAM_LONG_OR_NULL(dest, is_null)
Definition zend_API.h:1899
#define RETURN_RES(r)
Definition zend_API.h:1049
#define call_user_function(function_table, object, function_name, retval_ptr, param_count, params)
Definition zend_API.h:687
#define Z_PARAM_BOOL(dest)
Definition zend_API.h:1726
#define RETURN_EMPTY_STRING()
Definition zend_API.h:1047
#define Z_PARAM_RESOURCE_OR_NULL(dest)
Definition zend_API.h:2059
#define Z_PARAM_ZVAL(dest)
Definition zend_API.h:2100
#define RETVAL_STR(s)
Definition zend_API.h:1013
#define ZEND_TRY_ASSIGN_REF_STR(zv, str)
Definition zend_API.h:1271
#define RETVAL_FALSE
Definition zend_API.h:1032
#define RETURN_TRUE
Definition zend_API.h:1059
#define array_init(arg)
Definition zend_API.h:537
#define efree(ptr)
Definition zend_alloc.h:155
struct _zval_struct zval
zend_string_release_ex(func->internal_function.function_name, 0)
#define E_WARNING
Definition zend_errors.h:24
#define E_DEPRECATED
Definition zend_errors.h:37
#define EG(v)
ZEND_API zval *ZEND_FASTCALL zend_hash_str_find(const HashTable *ht, const char *str, size_t len)
Definition zend_hash.c:2689
ZEND_API zval *ZEND_FASTCALL zend_hash_index_update(HashTable *ht, zend_ulong h, zval *pData)
Definition zend_hash.c:1219
ZEND_API void ZEND_FASTCALL zend_array_destroy(HashTable *ht)
Definition zend_hash.c:1808
ZEND_API zval *ZEND_FASTCALL zend_hash_update(HashTable *ht, zend_string *key, zval *pData)
Definition zend_hash.c:997
#define HT_IS_PACKED(ht)
Definition zend_hash.h:59
#define zend_new_array(size)
Definition zend_hash.h:338
#define ZEND_HASH_FOREACH_KEY_VAL(ht, _h, _key, _val)
Definition zend_hash.h:1181
#define ZEND_HASH_FOREACH_STR_KEY_VAL(ht, _key, _val)
Definition zend_hash.h:1166
#define ZEND_HASH_MAP_FOREACH_STR_KEY(ht, _key)
Definition zend_hash.h:1346
#define ZEND_HASH_FOREACH_END()
Definition zend_hash.h:1086
#define ZVAL_EMPTY_ARRAY(z)
Definition zend_hash.h:87
#define ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(ht, _key, _val)
Definition zend_hash.h:1374
#define ZEND_HASH_FOREACH_VAL(ht, _val)
Definition zend_hash.h:1102
ZEND_API void * zend_fetch_resource(zend_resource *res, const char *resource_type_name, int resource_type)
Definition zend_list.c:117
ZEND_API zend_resource * zend_register_resource(void *rsrc_pointer, int rsrc_type)
Definition zend_list.c:87
ZEND_API void ZEND_FASTCALL zend_list_close(zend_resource *res)
Definition zend_list.c:78
ZEND_API void * zend_fetch_resource_ex(zval *res, const char *resource_type_name, int resource_type)
Definition zend_list.c:132
ZEND_API void * zend_fetch_resource2_ex(zval *res, const char *resource_type_name, int resource_type1, int resource_type2)
Definition zend_list.c:153
int32_t zend_long
Definition zend_long.h:42
uint32_t zend_ulong
Definition zend_long.h:43
int32_t zend_off_t
Definition zend_long.h:44
#define ZEND_LONG_FMT
Definition zend_long.h:87
struct _zend_string zend_string
#define zend_finite(a)
#define UNEXPECTED(condition)
ZEND_DLIMPORT int isatty(int fd)
#define zend_fstat
Definition zend_stream.h:98
struct stat zend_stat_t
Definition zend_stream.h:94
#define ZSTR_VAL(zstr)
Definition zend_string.h:68
#define ZSTR_LEN(zstr)
Definition zend_string.h:69
#define Z_TYPE_P(zval_p)
Definition zend_types.h:660
#define ZVAL_UNDEF(z)
#define Z_STRVAL_P(zval_p)
Definition zend_types.h:975
#define IS_UNDEF
Definition zend_types.h:600
#define Z_ARRVAL_P(zval_p)
Definition zend_types.h:987
#define ZVAL_NULL(z)
#define ZVAL_DEREF(z)
#define ZVAL_LONG(z, l)
struct _zend_array HashTable
Definition zend_types.h:386
#define IS_RESOURCE
Definition zend_types.h:609
#define IS_ARRAY
Definition zend_types.h:607
#define Z_ISUNDEF(zval)
Definition zend_types.h:956
#define GC_ADDREF(p)
Definition zend_types.h:709
#define Z_ADDREF_P(pz)
@ FAILURE
Definition zend_types.h:61
#define Z_TRY_ADDREF(z)
#define ZVAL_ARR(z, a)
#define ZVAL_COPY(z, v)
ZEND_RESULT_CODE zend_result
Definition zend_types.h:64
#define Z_RES_P(zval_p)
#define Z_TYPE(zval)
Definition zend_types.h:659
#define Z_LVAL_P(zval_p)
Definition zend_types.h:966
ZEND_API void zval_ptr_dtor(zval *zval_ptr)
ZEND_API void zval_add_ref(zval *p)
zval retval
zval * return_value
zval * arg1
zval * arg2
zend_string * name
zval * ret