php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
file.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: Rasmus Lerdorf <rasmus@php.net> |
14 | Stig Bakken <ssb@php.net> |
15 | Andi Gutmans <andi@php.net> |
16 | Zeev Suraski <zeev@php.net> |
17 | PHP 4.0 patches by Thies C. Arntzen (thies@thieso.net) |
18 | PHP streams by Wez Furlong (wez@thebrainroom.com) |
19 +----------------------------------------------------------------------+
20*/
21
22/* {{{ includes */
23
24#include "php.h"
29#include "php_ini.h"
30#include "zend_smart_str.h"
31
32#include <stdio.h>
33#include <stdlib.h>
34#include <errno.h>
35#include <wchar.h>
36#include <sys/types.h>
37#include <sys/stat.h>
38#include <fcntl.h>
39
40#ifdef PHP_WIN32
41# include <io.h>
42# define O_RDONLY _O_RDONLY
43# include "win32/param.h"
44# include "win32/winutil.h"
45# include "win32/fnmatch.h"
46# include "win32/ioutil.h"
47#else
48# ifdef HAVE_SYS_PARAM_H
49# include <sys/param.h>
50# endif
51# ifdef HAVE_SYS_SELECT_H
52# include <sys/select.h>
53# endif
54# include <sys/socket.h>
55# include <netinet/in.h>
56# include <netdb.h>
57# ifdef HAVE_ARPA_INET_H
58# include <arpa/inet.h>
59# endif
60#endif
61
62#include "php_string.h"
63#include "file.h"
64
65#ifdef HAVE_PWD_H
66# ifdef PHP_WIN32
67# include "win32/pwd.h"
68# else
69# include <pwd.h>
70# endif
71#endif
72
73#include "fsock.h"
74#include "fopen_wrappers.h"
75#include "streamsfuncs.h" /* To define constants in the arg_info */
76
77#ifdef HAVE_SYS_FILE_H
78# include <sys/file.h>
79#endif
80
81#ifdef HAVE_SYS_MMAN_H
82# include <sys/mman.h>
83#endif
84
85#include "scanf.h"
86#include "zend_API.h"
87
88#ifdef ZTS
89int file_globals_id;
90#else
92#endif
93
94#if defined(HAVE_FNMATCH) && !defined(PHP_WIN32)
95# ifndef _GNU_SOURCE
96# define _GNU_SOURCE
97# endif
98# include <fnmatch.h>
99#endif
100
101#include "file_arginfo.h"
102
103/* }}} */
104
105#define PHP_STREAM_FROM_ZVAL(stream, arg) \
106 ZEND_ASSERT(Z_TYPE_P(arg) == IS_RESOURCE); \
107 php_stream_from_res(stream, Z_RES_P(arg));
108
109/* {{{ ZTS-stuff / Globals / Prototypes */
110
111/* sharing globals is *evil* */
112static int le_stream_context = FAILURE;
113
115{
116 return le_stream_context;
117}
118/* }}} */
119
120/* {{{ Module-Stuff */
121static ZEND_RSRC_DTOR_FUNC(file_context_dtor)
122{
124 if (Z_TYPE(context->options) != IS_UNDEF) {
125 zval_ptr_dtor(&context->options);
126 ZVAL_UNDEF(&context->options);
127 }
129}
130
131static void file_globals_ctor(php_file_globals *file_globals_p)
132{
133 memset(file_globals_p, 0, sizeof(php_file_globals));
134 file_globals_p->def_chunk_size = PHP_SOCK_CHUNK_SIZE;
135}
136
137static void file_globals_dtor(php_file_globals *file_globals_p)
138{
139#if defined(HAVE_GETHOSTBYNAME_R)
140 if (file_globals_p->tmp_host_buf) {
141 free(file_globals_p->tmp_host_buf);
142 }
143#endif
144}
145
146static PHP_INI_MH(OnUpdateAutoDetectLineEndings)
147{
148 if (zend_ini_parse_bool(new_value)) {
149 zend_error(E_DEPRECATED, "auto_detect_line_endings is deprecated");
150 }
151 return OnUpdateBool(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
152}
153
155 STD_PHP_INI_ENTRY("user_agent", NULL, PHP_INI_ALL, OnUpdateString, user_agent, php_file_globals, file_globals)
156 STD_PHP_INI_ENTRY("from", NULL, PHP_INI_ALL, OnUpdateString, from_address, php_file_globals, file_globals)
157 STD_PHP_INI_ENTRY("default_socket_timeout", "60", PHP_INI_ALL, OnUpdateLong, default_socket_timeout, php_file_globals, file_globals)
158 STD_PHP_INI_BOOLEAN("auto_detect_line_endings", "0", PHP_INI_ALL, OnUpdateAutoDetectLineEndings, auto_detect_line_endings, php_file_globals, file_globals)
160
162{
163 le_stream_context = zend_register_list_destructors_ex(file_context_dtor, NULL, "stream-context", module_number);
164
165#ifdef ZTS
166 ts_allocate_id(&file_globals_id, sizeof(php_file_globals), (ts_allocate_ctor) file_globals_ctor, (ts_allocate_dtor) file_globals_dtor);
167#else
168 file_globals_ctor(&file_globals);
169#endif
170
172
173 register_file_symbols(module_number);
174
175 return SUCCESS;
176}
177/* }}} */
178
180{
181#ifndef ZTS
182 file_globals_dtor(&file_globals);
183#endif
184 return SUCCESS;
185}
186/* }}} */
187
189 uint32_t operation_arg_num, zval *wouldblock, zval *return_value)
190{
191 int flock_values[] = { LOCK_SH, LOCK_EX, LOCK_UN };
192 int act;
193
194 act = operation & PHP_LOCK_UN;
195 if (act < 1 || act > 3) {
196 zend_argument_value_error(operation_arg_num, "must be one of LOCK_SH, LOCK_EX, or LOCK_UN");
198 }
199
200 if (wouldblock) {
201 ZEND_TRY_ASSIGN_REF_LONG(wouldblock, 0);
202 }
203
204 /* flock_values contains all possible actions if (operation & PHP_LOCK_NB) we won't block on the lock */
205 act = flock_values[act - 1] | (operation & PHP_LOCK_NB ? LOCK_NB : 0);
206 if (php_stream_lock(stream, act)) {
207 if (operation && errno == EWOULDBLOCK && wouldblock) {
208 ZEND_TRY_ASSIGN_REF_LONG(wouldblock, 1);
209 }
211 }
213}
214
215/* {{{ Portable file locking */
217{
218 zval *res, *wouldblock = NULL;
219 php_stream *stream;
220 zend_long operation = 0;
221
224 Z_PARAM_LONG(operation)
226 Z_PARAM_ZVAL(wouldblock)
228
229 PHP_STREAM_FROM_ZVAL(stream, res);
230
231 php_flock_common(stream, operation, 2, wouldblock, return_value);
232}
233/* }}} */
234
235#define PHP_META_UNSAFE ".\\+*?[^]$() "
236
237/* {{{ Extracts all meta tag content attributes from a file and returns an array */
239{
240 char *filename;
241 size_t filename_len;
242 bool use_include_path = 0;
243 int in_tag = 0, done = 0;
244 int looking_for_val = 0, have_name = 0, have_content = 0;
245 int saw_name = 0, saw_content = 0;
246 char *name = NULL, *value = NULL, *temp = NULL;
247 php_meta_tags_token tok, tok_last;
249
250 /* Initialize our structure */
251 memset(&md, 0, sizeof(md));
252
253 /* Parse arguments */
255 Z_PARAM_PATH(filename, filename_len)
259
260 md.stream = php_stream_open_wrapper(filename, "rb",
262 NULL);
263 if (!md.stream) {
265 }
266
268
269 tok_last = TOK_EOF;
270
271 while (!done && (tok = php_next_meta_token(&md)) != TOK_EOF) {
272 if (tok == TOK_ID) {
273 if (tok_last == TOK_OPENTAG) {
274 md.in_meta = !strcasecmp("meta", md.token_data);
275 } else if (tok_last == TOK_SLASH && in_tag) {
276 if (strcasecmp("head", md.token_data) == 0) {
277 /* We are done here! */
278 done = 1;
279 }
280 } else if (tok_last == TOK_EQUAL && looking_for_val) {
281 if (saw_name) {
282 if (name) efree(name);
283 /* Get the NAME attr (Single word attr, non-quoted) */
284 temp = name = estrndup(md.token_data, md.token_len);
285
286 while (temp && *temp) {
287 if (strchr(PHP_META_UNSAFE, *temp)) {
288 *temp = '_';
289 }
290 temp++;
291 }
292
293 have_name = 1;
294 } else if (saw_content) {
295 if (value) efree(value);
297 have_content = 1;
298 }
299
300 looking_for_val = 0;
301 } else {
302 if (md.in_meta) {
303 if (strcasecmp("name", md.token_data) == 0) {
304 saw_name = 1;
305 saw_content = 0;
306 looking_for_val = 1;
307 } else if (strcasecmp("content", md.token_data) == 0) {
308 saw_name = 0;
309 saw_content = 1;
310 looking_for_val = 1;
311 }
312 }
313 }
314 } else if (tok == TOK_STRING && tok_last == TOK_EQUAL && looking_for_val) {
315 if (saw_name) {
316 if (name) efree(name);
317 /* Get the NAME attr (Quoted single/double) */
318 temp = name = estrndup(md.token_data, md.token_len);
319
320 while (temp && *temp) {
321 if (strchr(PHP_META_UNSAFE, *temp)) {
322 *temp = '_';
323 }
324 temp++;
325 }
326
327 have_name = 1;
328 } else if (saw_content) {
329 if (value) efree(value);
331 have_content = 1;
332 }
333
334 looking_for_val = 0;
335 } else if (tok == TOK_OPENTAG) {
336 if (looking_for_val) {
337 looking_for_val = 0;
338 have_name = saw_name = 0;
339 have_content = saw_content = 0;
340 }
341 in_tag = 1;
342 } else if (tok == TOK_CLOSETAG) {
343 if (have_name) {
344 /* For BC */
346 if (have_content) {
347 add_assoc_string(return_value, name, value);
348 } else {
349 add_assoc_string(return_value, name, "");
350 }
351
352 efree(name);
353 if (value) efree(value);
354 } else if (have_content) {
355 efree(value);
356 }
357
358 name = value = NULL;
359
360 /* Reset all of our flags */
361 in_tag = looking_for_val = 0;
362 have_name = saw_name = 0;
363 have_content = saw_content = 0;
364 md.in_meta = 0;
365 }
366
367 tok_last = tok;
368
369 if (md.token_data)
370 efree(md.token_data);
371
372 md.token_data = NULL;
373 }
374
375 if (value) efree(value);
376 if (name) efree(name);
378}
379/* }}} */
380
381/* {{{ Read the entire file into a string */
383{
384 char *filename;
385 size_t filename_len;
386 bool use_include_path = 0;
387 php_stream *stream;
388 zend_long offset = 0;
390 bool maxlen_is_null = 1;
391 zval *zcontext = NULL;
394
395 /* Parse arguments */
397 Z_PARAM_PATH(filename, filename_len)
404
405 if (maxlen_is_null) {
406 maxlen = (ssize_t) PHP_STREAM_COPY_ALL;
407 } else if (maxlen < 0) {
408 zend_argument_value_error(5, "must be greater than or equal to 0");
410 }
411
413
414 stream = php_stream_open_wrapper_ex(filename, "rb",
416 NULL, context);
417 if (!stream) {
419 }
420
421 /* disabling the read buffer allows doing the whole transfer
422 in just one read() system call */
423 if (php_stream_is(stream, PHP_STREAM_IS_STDIO)) {
425 }
426
427 if (offset != 0 && php_stream_seek(stream, offset, ((offset > 0) ? SEEK_SET : SEEK_END)) < 0) {
428 php_error_docref(NULL, E_WARNING, "Failed to seek to position " ZEND_LONG_FMT " in the stream", offset);
429 php_stream_close(stream);
431 }
432
433 if ((contents = php_stream_copy_to_mem(stream, maxlen, 0)) != NULL) {
435 } else {
437 }
438
439 php_stream_close(stream);
440}
441/* }}} */
442
443/* {{{ Write/Create a file with contents data and return the number of bytes written */
445{
446 php_stream *stream;
447 char *filename;
448 size_t filename_len;
449 zval *data;
450 ssize_t numbytes = 0;
451 zend_long flags = 0;
452 zval *zcontext = NULL;
454 php_stream *srcstream = NULL;
455 char mode[3] = "wb";
456
458 Z_PARAM_PATH(filename, filename_len)
464
465 if (Z_TYPE_P(data) == IS_RESOURCE) {
466 php_stream_from_zval(srcstream, data);
467 }
468
470
471 if (flags & PHP_FILE_APPEND) {
472 mode[0] = 'a';
473 } else if (flags & LOCK_EX) {
474 /* check to make sure we are dealing with a regular file */
475 if (php_memnstr(filename, "://", sizeof("://") - 1, filename + filename_len)) {
476 if (strncasecmp(filename, "file://", sizeof("file://") - 1)) {
477 php_error_docref(NULL, E_WARNING, "Exclusive locks may only be set for regular files");
479 }
480 }
481 mode[0] = 'c';
482 }
483 mode[2] = '\0';
484
486 if (stream == NULL) {
488 }
489
490 if ((flags & LOCK_EX) && (!php_stream_supports_lock(stream) || php_stream_lock(stream, LOCK_EX))) {
491 php_stream_close(stream);
492 php_error_docref(NULL, E_WARNING, "Exclusive locks are not supported for this stream");
494 }
495
496 if (mode[0] == 'c') {
498 }
499
500 switch (Z_TYPE_P(data)) {
501 case IS_RESOURCE: {
502 size_t len;
503 if (php_stream_copy_to_stream_ex(srcstream, stream, PHP_STREAM_COPY_ALL, &len) != SUCCESS) {
504 numbytes = -1;
505 } else {
506 if (len > ZEND_LONG_MAX) {
507 php_error_docref(NULL, E_WARNING, "content truncated from %zu to " ZEND_LONG_FMT " bytes", len, ZEND_LONG_MAX);
509 }
510 numbytes = len;
511 }
512 break;
513 }
514 case IS_NULL:
515 case IS_LONG:
516 case IS_DOUBLE:
517 case IS_FALSE:
518 case IS_TRUE:
521 case IS_STRING:
522 if (Z_STRLEN_P(data)) {
523 numbytes = php_stream_write(stream, Z_STRVAL_P(data), Z_STRLEN_P(data));
524 if (numbytes != -1 && numbytes != Z_STRLEN_P(data)) {
525 php_error_docref(NULL, E_WARNING, "Only %zd of %zd bytes written, possibly out of free disk space", numbytes, Z_STRLEN_P(data));
526 numbytes = -1;
527 }
528 }
529 break;
530
531 case IS_ARRAY:
532 if (zend_hash_num_elements(Z_ARRVAL_P(data))) {
533 ssize_t bytes_written;
534 zval *tmp;
535
537 zend_string *t;
538 zend_string *str = zval_get_tmp_string(tmp, &t);
539 if (ZSTR_LEN(str)) {
540 numbytes += ZSTR_LEN(str);
541 bytes_written = php_stream_write(stream, ZSTR_VAL(str), ZSTR_LEN(str));
542 if (bytes_written != ZSTR_LEN(str)) {
543 php_error_docref(NULL, E_WARNING, "Failed to write %zd bytes to %s", ZSTR_LEN(str), filename);
544 zend_tmp_string_release(t);
545 numbytes = -1;
546 break;
547 }
548 }
549 zend_tmp_string_release(t);
551 }
552 break;
553
554 case IS_OBJECT:
555 if (Z_OBJ_HT_P(data) != NULL) {
556 zval out;
557
559 numbytes = php_stream_write(stream, Z_STRVAL(out), Z_STRLEN(out));
560 if (numbytes != -1 && numbytes != Z_STRLEN(out)) {
561 php_error_docref(NULL, E_WARNING, "Only %zd of %zd bytes written, possibly out of free disk space", numbytes, Z_STRLEN(out));
562 numbytes = -1;
563 }
564 zval_ptr_dtor_str(&out);
565 break;
566 }
567 }
569 default:
570 numbytes = -1;
571 break;
572 }
573 php_stream_close(stream);
574
575 if (numbytes < 0) {
577 }
578
579 RETURN_LONG(numbytes);
580}
581/* }}} */
582
583#define PHP_FILE_BUF_SIZE 80
584
585/* {{{ Read entire file into an array */
587{
588 char *filename;
589 size_t filename_len;
590 char *p, *s, *e;
591 int i = 0;
592 char eol_marker = '\n';
593 zend_long flags = 0;
594 bool use_include_path;
595 bool include_new_line;
596 bool skip_blank_lines;
597 php_stream *stream;
598 zval *zcontext = NULL;
600 zend_string *target_buf;
601
602 /* Parse arguments */
604 Z_PARAM_PATH(filename, filename_len)
609
611 zend_argument_value_error(2, "must be a valid flag value");
613 }
614
616 include_new_line = !(flags & PHP_FILE_IGNORE_NEW_LINES);
617 skip_blank_lines = flags & PHP_FILE_SKIP_EMPTY_LINES;
618
620
622 if (!stream) {
624 }
625
626 /* Initialize return array */
628
629 if ((target_buf = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0)) != NULL) {
630 s = ZSTR_VAL(target_buf);
631 e = ZSTR_VAL(target_buf) + ZSTR_LEN(target_buf);
632
633 if (!(p = (char*)php_stream_locate_eol(stream, target_buf))) {
634 p = e;
635 goto parse_eol;
636 }
637
638 if (stream->flags & PHP_STREAM_FLAG_EOL_MAC) {
639 eol_marker = '\r';
640 }
641
642 /* for performance reasons the code is duplicated, so that the if (include_new_line)
643 * will not need to be done for every single line in the file. */
644 if (include_new_line) {
645 do {
646 p++;
647parse_eol:
649 s = p;
650 } while ((p = memchr(p, eol_marker, (e-p))));
651 } else {
652 do {
653 int windows_eol = 0;
654 if (p != ZSTR_VAL(target_buf) && eol_marker == '\n' && *(p - 1) == '\r') {
655 windows_eol++;
656 }
657 if (skip_blank_lines && !(p-s-windows_eol)) {
658 s = ++p;
659 continue;
660 }
661 add_index_stringl(return_value, i++, s, p-s-windows_eol);
662 s = ++p;
663 } while ((p = memchr(p, eol_marker, (e-p))));
664 }
665
666 /* handle any leftovers of files without new lines */
667 if (s != e) {
668 p = e;
669 goto parse_eol;
670 }
671 }
672
673 if (target_buf) {
674 zend_string_free(target_buf);
675 }
676 php_stream_close(stream);
677}
678/* }}} */
679
680/* {{{ Create a unique filename in a directory */
682{
683 char *dir, *prefix;
684 size_t dir_len, prefix_len;
685 zend_string *opened_path;
686 int fd;
687 zend_string *p;
688
690 Z_PARAM_PATH(dir, dir_len)
691 Z_PARAM_PATH(prefix, prefix_len)
693
694 p = php_basename(prefix, prefix_len, NULL, 0);
695 if (ZSTR_LEN(p) >= 64) {
696 ZSTR_VAL(p)[63] = '\0';
697 }
698
700
702 close(fd);
703 RETVAL_STR(opened_path);
704 }
706}
707/* }}} */
708
709/* {{{ Create a temporary file that will be deleted automatically after use */
711{
712 php_stream *stream;
713
715
716 stream = php_stream_fopen_tmpfile();
717
718 if (stream) {
720 } else {
722 }
723}
724/* }}} */
725
726/* {{{ Open a file or a URL and return a file pointer */
754/* }}} */
755
756/* {{{ Close an open file pointer */
758{
759 zval *res;
760 php_stream *stream;
761
765
766 PHP_STREAM_FROM_ZVAL(stream, res);
767
768 if ((stream->flags & PHP_STREAM_FLAG_NO_FCLOSE) != 0) {
769 php_error_docref(NULL, E_WARNING, ZEND_LONG_FMT " is not a valid stream resource", stream->res->handle);
771 }
772
773 php_stream_free(stream,
776
778}
779/* }}} */
780
781/* {{{ Execute a command and open either a read or a write pipe to it */
783{
784 char *command, *mode;
785 size_t command_len, mode_len;
786 FILE *fp;
787 php_stream *stream;
788 char *posix_mode;
789
791 Z_PARAM_PATH(command, command_len)
794
795 posix_mode = estrndup(mode, mode_len);
796#ifndef PHP_WIN32
797 {
798 char *z = memchr(posix_mode, 'b', mode_len);
799 if (z) {
800 memmove(z, z + 1, mode_len - (z - posix_mode));
801 mode_len--;
802 }
803 }
804#endif
805
806 /* Musl only partially validates the mode. Manually check it to ensure consistent behavior. */
807 if (mode_len > 2 ||
808 (mode_len == 1 && (*posix_mode != 'r' && *posix_mode != 'w')) ||
809 (mode_len == 2 && (memcmp(posix_mode, "rb", 2) && memcmp(posix_mode, "wb", 2)))
810 ) {
811 zend_argument_value_error(2, "must be one of \"r\", \"rb\", \"w\", or \"wb\"");
812 efree(posix_mode);
814 }
815
816 fp = VCWD_POPEN(command, posix_mode);
817 if (!fp) {
818 php_error_docref2(NULL, command, posix_mode, E_WARNING, "%s", strerror(errno));
819 efree(posix_mode);
821 }
822
823 stream = php_stream_fopen_from_pipe(fp, mode);
824
825 if (stream == NULL) {
826 php_error_docref2(NULL, command, mode, E_WARNING, "%s", strerror(errno));
828 } else {
830 }
831
832 efree(posix_mode);
833}
834/* }}} */
835
836/* {{{ Close a file pointer opened by popen() */
838{
839 zval *res;
840 php_stream *stream;
841
845
846 PHP_STREAM_FROM_ZVAL(stream, res);
847
848 FG(pclose_wait) = 1;
849 zend_list_close(stream->res);
850 FG(pclose_wait) = 0;
851 RETURN_LONG(FG(pclose_ret));
852}
853/* }}} */
854
855/* {{{ Test for end-of-file on a file pointer */
857{
858 zval *res;
859 php_stream *stream;
860
864
865 PHP_STREAM_FROM_ZVAL(stream, res);
866
867 if (php_stream_eof(stream)) {
869 } else {
871 }
872}
873/* }}} */
874
875/* {{{ Get a line from file pointer */
877{
878 zval *res;
879 zend_long len = 1024;
880 bool len_is_null = 1;
881 char *buf = NULL;
882 size_t line_len = 0;
883 zend_string *str;
884 php_stream *stream;
885
889 Z_PARAM_LONG_OR_NULL(len, len_is_null)
891
892 PHP_STREAM_FROM_ZVAL(stream, res);
893
894 if (len_is_null) {
895 /* ask streams to give us a buffer of an appropriate size */
896 buf = php_stream_get_line(stream, NULL, 0, &line_len);
897 if (buf == NULL) {
899 }
900 // TODO: avoid reallocation ???
901 RETVAL_STRINGL(buf, line_len);
902 efree(buf);
903 } else {
904 if (len <= 0) {
905 zend_argument_value_error(2, "must be greater than 0");
907 }
908
909 str = zend_string_alloc(len, 0);
910 if (php_stream_get_line(stream, ZSTR_VAL(str), len, &line_len) == NULL) {
911 zend_string_efree(str);
913 }
914 /* resize buffer if it's much larger than the result.
915 * Only needed if the user requested a buffer size. */
916 if (line_len < (size_t)len / 2) {
917 str = zend_string_truncate(str, line_len, 0);
918 } else {
919 ZSTR_LEN(str) = line_len;
920 }
921 RETURN_NEW_STR(str);
922 }
923}
924/* }}} */
925
926/* {{{ Get a character from file pointer */
928{
929 zval *res;
930 php_stream *stream;
931
935
936 PHP_STREAM_FROM_ZVAL(stream, res);
937
938 int result = php_stream_getc(stream);
939
940 if (result == EOF) {
942 } else {
944 }
945}
946/* }}} */
947
948/* {{{ Implements a mostly ANSI compatible fscanf() */
950{
951 int result, argc = 0;
952 size_t format_len;
953 zval *args = NULL;
954 zval *file_handle;
955 char *buf, *format;
956 size_t len;
957 void *what;
958
960 Z_PARAM_RESOURCE(file_handle)
961 Z_PARAM_STRING(format, format_len)
962 Z_PARAM_VARIADIC('*', args, argc)
964
965 what = zend_fetch_resource2(Z_RES_P(file_handle), "File-Handle", php_file_le_stream(), php_file_le_pstream());
966
967 /* we can't do a ZEND_VERIFY_RESOURCE(what), otherwise we end up
968 * with a leak if we have an invalid filehandle. This needs changing
969 * if the code behind ZEND_VERIFY_RESOURCE changed. - cc */
970 if (!what) {
972 }
973
974 buf = php_stream_get_line((php_stream *) what, NULL, 0, &len);
975 if (buf == NULL) {
977 }
978
979 result = php_sscanf_internal(buf, format, argc, args, 0, return_value);
980
981 efree(buf);
982
985 }
986}
987/* }}} */
988
989/* {{{ Binary-safe file write */
991{
992 zval *res;
993 char *input;
994 size_t inputlen;
995 ssize_t ret;
996 size_t num_bytes;
997 zend_long maxlen = 0;
998 bool maxlen_is_null = 1;
999 php_stream *stream;
1000
1003 Z_PARAM_STRING(input, inputlen)
1007
1008 if (maxlen_is_null) {
1009 num_bytes = inputlen;
1010 } else if (maxlen <= 0) {
1011 num_bytes = 0;
1012 } else {
1013 num_bytes = MIN((size_t) maxlen, inputlen);
1014 }
1015
1016 if (!num_bytes) {
1017 RETURN_LONG(0);
1018 }
1019
1020 PHP_STREAM_FROM_ZVAL(stream, res);
1021
1022 ret = php_stream_write(stream, input, num_bytes);
1023 if (ret < 0) {
1025 }
1026
1028}
1029/* }}} */
1030
1031/* {{{ Flushes output */
1033{
1034 zval *res;
1035 int ret;
1036 php_stream *stream;
1037
1041
1042 PHP_STREAM_FROM_ZVAL(stream, res);
1043
1044 ret = php_stream_flush(stream);
1045 if (ret) {
1047 }
1049}
1050/* }}} */
1051
1052/* {{{ Rewind the position of a file pointer */
1054{
1055 zval *res;
1056 php_stream *stream;
1057
1061
1062 PHP_STREAM_FROM_ZVAL(stream, res);
1063
1064 if (-1 == php_stream_rewind(stream)) {
1066 }
1068}
1069/* }}} */
1070
1071/* {{{ Get file pointer's read/write position */
1073{
1074 zval *res;
1075 zend_long ret;
1076 php_stream *stream;
1077
1081
1082 PHP_STREAM_FROM_ZVAL(stream, res);
1083
1084 ret = php_stream_tell(stream);
1085 if (ret == -1) {
1087 }
1089}
1090/* }}} */
1091
1092/* {{{ Seek on a file pointer */
1094{
1095 zval *res;
1096 zend_long offset, whence = SEEK_SET;
1097 php_stream *stream;
1098
1103 Z_PARAM_LONG(whence)
1105
1106 PHP_STREAM_FROM_ZVAL(stream, res);
1107
1108 RETURN_LONG(php_stream_seek(stream, offset, (int) whence));
1109}
1110/* }}} */
1111
1112/* {{{ Create a directory */
1114{
1115 char *dir;
1116 size_t dir_len;
1117 zval *zcontext = NULL;
1118 zend_long mode = 0777;
1119 bool recursive = 0;
1121
1123 Z_PARAM_PATH(dir, dir_len)
1126 Z_PARAM_BOOL(recursive)
1129
1131
1133}
1134/* }}} */
1135
1136/* {{{ Remove a directory */
1154/* }}} */
1155
1156/* {{{ Output a file or a URL */
1158{
1159 char *filename;
1160 size_t filename_len;
1161 size_t size = 0;
1162 bool use_include_path = 0;
1163 zval *zcontext = NULL;
1164 php_stream *stream;
1166
1168 Z_PARAM_PATH(filename, filename_len)
1173
1175
1176 stream = php_stream_open_wrapper_ex(filename, "rb", (use_include_path ? USE_PATH : 0) | REPORT_ERRORS, NULL, context);
1177 if (stream) {
1178 size = php_stream_passthru(stream);
1179 php_stream_close(stream);
1181 }
1182
1184}
1185/* }}} */
1186
1187/* {{{ Return or change the umask */
1189{
1190 zend_long mask = 0;
1191 bool mask_is_null = 1;
1192 int oldumask;
1193
1196 Z_PARAM_LONG_OR_NULL(mask, mask_is_null)
1198
1199 oldumask = umask(077);
1200
1201 if (BG(umask) == -1) {
1202 BG(umask) = oldumask;
1203 }
1204
1205 if (mask_is_null) {
1206 umask(oldumask);
1207 } else {
1208 umask((int) mask);
1209 }
1210
1211 RETURN_LONG(oldumask);
1212}
1213/* }}} */
1214
1215/* {{{ Output all remaining data from a file pointer */
1217{
1218 zval *res;
1219 size_t size;
1220 php_stream *stream;
1221
1225
1226 PHP_STREAM_FROM_ZVAL(stream, res);
1227
1228 size = php_stream_passthru(stream);
1230}
1231/* }}} */
1232
1233/* {{{ Rename a file */
1235{
1236 char *old_name, *new_name;
1237 size_t old_name_len, new_name_len;
1238 zval *zcontext = NULL;
1239 php_stream_wrapper *wrapper;
1241
1243 Z_PARAM_PATH(old_name, old_name_len)
1244 Z_PARAM_PATH(new_name, new_name_len)
1248
1249 wrapper = php_stream_locate_url_wrapper(old_name, NULL, 0);
1250
1251 if (!wrapper || !wrapper->wops) {
1252 php_error_docref(NULL, E_WARNING, "Unable to locate stream wrapper");
1254 }
1255
1256 if (!wrapper->wops->rename) {
1257 php_error_docref(NULL, E_WARNING, "%s wrapper does not support renaming", wrapper->wops->label ? wrapper->wops->label : "Source");
1259 }
1260
1261 if (wrapper != php_stream_locate_url_wrapper(new_name, NULL, 0)) {
1262 php_error_docref(NULL, E_WARNING, "Cannot rename a file across wrapper types");
1264 }
1265
1267
1268 RETURN_BOOL(wrapper->wops->rename(wrapper, old_name, new_name, 0, context));
1269}
1270/* }}} */
1271
1272/* {{{ Delete a file */
1274{
1275 char *filename;
1276 size_t filename_len;
1277 php_stream_wrapper *wrapper;
1278 zval *zcontext = NULL;
1280
1282 Z_PARAM_PATH(filename, filename_len)
1286
1288
1289 wrapper = php_stream_locate_url_wrapper(filename, NULL, 0);
1290
1291 if (!wrapper || !wrapper->wops) {
1292 php_error_docref(NULL, E_WARNING, "Unable to locate stream wrapper");
1294 }
1295
1296 if (!wrapper->wops->unlink) {
1297 php_error_docref(NULL, E_WARNING, "%s does not allow unlinking", wrapper->wops->label ? wrapper->wops->label : "Wrapper");
1299 }
1300 RETURN_BOOL(wrapper->wops->unlink(wrapper, filename, REPORT_ERRORS, context));
1301}
1302/* }}} */
1303
1305{
1306 zval *res;
1307 php_stream *stream;
1308
1312
1313 PHP_STREAM_FROM_ZVAL(stream, res);
1314
1315 if (!php_stream_sync_supported(stream)) {
1316 php_error_docref(NULL, E_WARNING, "Can't fsync this stream!");
1318 }
1319
1320 RETURN_BOOL(php_stream_sync(stream, /* data_only */ 0) == 0);
1321}
1322
1324{
1325 zval *res;
1326 php_stream *stream;
1327
1331
1332 PHP_STREAM_FROM_ZVAL(stream, res);
1333
1334 if (!php_stream_sync_supported(stream)) {
1335 php_error_docref(NULL, E_WARNING, "Can't fsync this stream!");
1337 }
1338
1339 RETURN_BOOL(php_stream_sync(stream, /* data_only */ 1) == 0);
1340}
1341
1342/* {{{ Truncate file to 'size' length */
1344{
1345 zval *fp;
1347 php_stream *stream;
1348
1353
1354 if (size < 0) {
1355 zend_argument_value_error(2, "must be greater than or equal to 0");
1356 RETURN_THROWS();
1357 }
1358
1359 PHP_STREAM_FROM_ZVAL(stream, fp);
1360
1361 if (!php_stream_truncate_supported(stream)) {
1362 php_error_docref(NULL, E_WARNING, "Can't truncate this stream!");
1364 }
1365
1367}
1368/* }}} */
1370{
1371 php_stream_statbuf stat_ssb;
1372 zval stat_dev, stat_ino, stat_mode, stat_nlink, stat_uid, stat_gid, stat_rdev,
1373 stat_size, stat_atime, stat_mtime, stat_ctime, stat_blksize, stat_blocks;
1374 char *stat_sb_names[13] = {
1375 "dev", "ino", "mode", "nlink", "uid", "gid", "rdev",
1376 "size", "atime", "mtime", "ctime", "blksize", "blocks"
1377 };
1378
1379 if (php_stream_stat(stream, &stat_ssb)) {
1381 }
1382
1384
1385 ZVAL_LONG(&stat_dev, stat_ssb.sb.st_dev);
1386 ZVAL_LONG(&stat_ino, stat_ssb.sb.st_ino);
1387 ZVAL_LONG(&stat_mode, stat_ssb.sb.st_mode);
1388 ZVAL_LONG(&stat_nlink, stat_ssb.sb.st_nlink);
1389 ZVAL_LONG(&stat_uid, stat_ssb.sb.st_uid);
1390 ZVAL_LONG(&stat_gid, stat_ssb.sb.st_gid);
1391#ifdef HAVE_STRUCT_STAT_ST_RDEV
1392 ZVAL_LONG(&stat_rdev, stat_ssb.sb.st_rdev);
1393#else
1394 ZVAL_LONG(&stat_rdev, -1);
1395#endif
1396 ZVAL_LONG(&stat_size, stat_ssb.sb.st_size);
1397 ZVAL_LONG(&stat_atime, stat_ssb.sb.st_atime);
1398 ZVAL_LONG(&stat_mtime, stat_ssb.sb.st_mtime);
1399 ZVAL_LONG(&stat_ctime, stat_ssb.sb.st_ctime);
1400#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1401 ZVAL_LONG(&stat_blksize, stat_ssb.sb.st_blksize);
1402#else
1403 ZVAL_LONG(&stat_blksize,-1);
1404#endif
1405#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1406 ZVAL_LONG(&stat_blocks, stat_ssb.sb.st_blocks);
1407#else
1408 ZVAL_LONG(&stat_blocks,-1);
1409#endif
1410 /* Store numeric indexes in proper order */
1424
1425 /* Store string indexes referencing the same zval*/
1426 zend_hash_str_add_new(Z_ARRVAL_P(return_value), stat_sb_names[0], strlen(stat_sb_names[0]), &stat_dev);
1427 zend_hash_str_add_new(Z_ARRVAL_P(return_value), stat_sb_names[1], strlen(stat_sb_names[1]), &stat_ino);
1428 zend_hash_str_add_new(Z_ARRVAL_P(return_value), stat_sb_names[2], strlen(stat_sb_names[2]), &stat_mode);
1429 zend_hash_str_add_new(Z_ARRVAL_P(return_value), stat_sb_names[3], strlen(stat_sb_names[3]), &stat_nlink);
1430 zend_hash_str_add_new(Z_ARRVAL_P(return_value), stat_sb_names[4], strlen(stat_sb_names[4]), &stat_uid);
1431 zend_hash_str_add_new(Z_ARRVAL_P(return_value), stat_sb_names[5], strlen(stat_sb_names[5]), &stat_gid);
1432 zend_hash_str_add_new(Z_ARRVAL_P(return_value), stat_sb_names[6], strlen(stat_sb_names[6]), &stat_rdev);
1433 zend_hash_str_add_new(Z_ARRVAL_P(return_value), stat_sb_names[7], strlen(stat_sb_names[7]), &stat_size);
1434 zend_hash_str_add_new(Z_ARRVAL_P(return_value), stat_sb_names[8], strlen(stat_sb_names[8]), &stat_atime);
1435 zend_hash_str_add_new(Z_ARRVAL_P(return_value), stat_sb_names[9], strlen(stat_sb_names[9]), &stat_mtime);
1436 zend_hash_str_add_new(Z_ARRVAL_P(return_value), stat_sb_names[10], strlen(stat_sb_names[10]), &stat_ctime);
1437 zend_hash_str_add_new(Z_ARRVAL_P(return_value), stat_sb_names[11], strlen(stat_sb_names[11]), &stat_blksize);
1438 zend_hash_str_add_new(Z_ARRVAL_P(return_value), stat_sb_names[12], strlen(stat_sb_names[12]), &stat_blocks);
1439}
1440
1441/* {{{ Stat() on a filehandle */
1443{
1444 zval *fp;
1445 php_stream *stream;
1446
1450
1451 PHP_STREAM_FROM_ZVAL(stream, fp);
1452
1453 php_fstat(stream, return_value);
1454}
1455/* }}} */
1456
1457/* {{{ Copy a file */
1459{
1460 char *source, *target;
1461 size_t source_len, target_len;
1462 zval *zcontext = NULL;
1464
1466 Z_PARAM_PATH(source, source_len)
1467 Z_PARAM_PATH(target, target_len)
1471
1474 }
1475
1477
1478 RETURN_BOOL(php_copy_file_ctx(source, target, 0, context) == SUCCESS);
1479}
1480/* }}} */
1481
1482/* {{{ php_copy_file */
1483PHPAPI zend_result php_copy_file(const char *src, const char *dest)
1484{
1485 return php_copy_file_ctx(src, dest, 0, NULL);
1486}
1487/* }}} */
1488
1489/* {{{ php_copy_file_ex */
1490PHPAPI zend_result php_copy_file_ex(const char *src, const char *dest, int src_flags)
1491{
1492 return php_copy_file_ctx(src, dest, src_flags, NULL);
1493}
1494/* }}} */
1495
1496/* {{{ php_copy_file_ctx */
1497PHPAPI zend_result php_copy_file_ctx(const char *src, const char *dest, int src_flags, php_stream_context *ctx)
1498{
1499 php_stream *srcstream = NULL, *deststream = NULL;
1501 php_stream_statbuf src_s, dest_s;
1502 int src_stat_flags = (src_flags & STREAM_DISABLE_OPEN_BASEDIR) ? PHP_STREAM_URL_STAT_IGNORE_OPEN_BASEDIR : 0;
1503
1504 switch (php_stream_stat_path_ex(src, src_stat_flags, &src_s, ctx)) {
1505 case -1:
1506 /* non-statable stream */
1507 goto safe_to_copy;
1508 break;
1509 case 0:
1510 break;
1511 default: /* failed to stat file, does not exist? */
1512 return ret;
1513 }
1514 if (S_ISDIR(src_s.sb.st_mode)) {
1515 php_error_docref(NULL, E_WARNING, "The first argument to copy() function cannot be a directory");
1516 return FAILURE;
1517 }
1518
1519 switch (php_stream_stat_path_ex(dest, PHP_STREAM_URL_STAT_QUIET, &dest_s, ctx)) {
1520 case -1:
1521 /* non-statable stream */
1522 goto safe_to_copy;
1523 break;
1524 case 0:
1525 break;
1526 default: /* failed to stat file, does not exist? */
1527 return ret;
1528 }
1529 if (S_ISDIR(dest_s.sb.st_mode)) {
1530 php_error_docref(NULL, E_WARNING, "The second argument to copy() function cannot be a directory");
1531 return FAILURE;
1532 }
1533 if (!src_s.sb.st_ino || !dest_s.sb.st_ino) {
1534 goto no_stat;
1535 }
1536 if (src_s.sb.st_ino == dest_s.sb.st_ino && src_s.sb.st_dev == dest_s.sb.st_dev) {
1537 return ret;
1538 } else {
1539 goto safe_to_copy;
1540 }
1541no_stat:
1542 {
1543 char *sp, *dp;
1544 int res;
1545
1546 if ((sp = expand_filepath(src, NULL)) == NULL) {
1547 return ret;
1548 }
1549 if ((dp = expand_filepath(dest, NULL)) == NULL) {
1550 efree(sp);
1551 goto safe_to_copy;
1552 }
1553
1554 res =
1555#ifndef PHP_WIN32
1556 !strcmp(sp, dp);
1557#else
1558 !strcasecmp(sp, dp);
1559#endif
1560
1561 efree(sp);
1562 efree(dp);
1563 if (res) {
1564 return ret;
1565 }
1566 }
1567safe_to_copy:
1568
1569 srcstream = php_stream_open_wrapper_ex(src, "rb", src_flags | REPORT_ERRORS, NULL, ctx);
1570
1571 if (!srcstream) {
1572 return ret;
1573 }
1574
1575 deststream = php_stream_open_wrapper_ex(dest, "wb", REPORT_ERRORS, NULL, ctx);
1576
1577 if (deststream) {
1578 ret = php_stream_copy_to_stream_ex(srcstream, deststream, PHP_STREAM_COPY_ALL, NULL);
1579 }
1580 php_stream_close(srcstream);
1581 if (deststream) {
1582 php_stream_close(deststream);
1583 }
1584 return ret;
1585}
1586/* }}} */
1587
1588/* {{{ Binary-safe file read */
1590{
1591 zval *res;
1592 zend_long len;
1593 php_stream *stream;
1594 zend_string *str;
1595
1600
1601 PHP_STREAM_FROM_ZVAL(stream, res);
1602
1603 if (len <= 0) {
1604 zend_argument_value_error(2, "must be greater than 0");
1605 RETURN_THROWS();
1606 }
1607
1608 str = php_stream_read_to_str(stream, len);
1609 if (!str) {
1610 zval_ptr_dtor_str(return_value);
1612 }
1613
1614 RETURN_STR(str);
1615}
1616/* }}} */
1617
1618static const char *php_fgetcsv_lookup_trailing_spaces(const char *ptr, size_t len) /* {{{ */
1619{
1620 int inc_len;
1621 unsigned char last_chars[2] = { 0, 0 };
1622
1623 while (len > 0) {
1624 inc_len = (*ptr == '\0' ? 1 : php_mblen(ptr, len));
1625 switch (inc_len) {
1626 case -2:
1627 case -1:
1628 inc_len = 1;
1629 php_mb_reset();
1630 break;
1631 case 0:
1632 goto quit_loop;
1633 case 1:
1634 default:
1635 last_chars[0] = last_chars[1];
1636 last_chars[1] = *ptr;
1637 break;
1638 }
1639 ptr += inc_len;
1640 len -= inc_len;
1641 }
1642quit_loop:
1643 switch (last_chars[1]) {
1644 case '\n':
1645 if (last_chars[0] == '\r') {
1646 return ptr - 2;
1647 }
1649 case '\r':
1650 return ptr - 1;
1651 }
1652 return ptr;
1653}
1654/* }}} */
1655
1657{
1658 if (escape_str != NULL) {
1659 if (ZSTR_LEN(escape_str) > 1) {
1660 zend_argument_value_error(arg_num, "must be empty or a single character");
1661 return PHP_CSV_ESCAPE_ERROR;
1662 }
1663 if (ZSTR_LEN(escape_str) < 1) {
1664 return PHP_CSV_NO_ESCAPE;
1665 } else {
1666 /* use first character from string */
1667 return (unsigned char) ZSTR_VAL(escape_str)[0];
1668 }
1669 } else {
1670 php_error_docref(NULL, E_DEPRECATED, "the $escape parameter must be provided as its default value will change");
1671 if (UNEXPECTED(EG(exception))) {
1672 return PHP_CSV_ESCAPE_ERROR;
1673 }
1674 return (unsigned char) '\\';
1675 }
1676}
1677
1678#define FPUTCSV_FLD_CHK(c) memchr(ZSTR_VAL(field_str), c, ZSTR_LEN(field_str))
1679
1680/* {{{ Format line as CSV and write to file pointer */
1682{
1683 char delimiter = ','; /* allow this to be set as parameter */
1684 char enclosure = '"'; /* allow this to be set as parameter */
1685 php_stream *stream;
1686 zval *fp = NULL, *fields = NULL;
1687 ssize_t ret;
1688 char *delimiter_str = NULL, *enclosure_str = NULL;
1689 zend_string *escape_str = NULL;
1690 size_t delimiter_str_len = 0, enclosure_str_len = 0;
1691 zend_string *eol_str = NULL;
1692
1695 Z_PARAM_ARRAY(fields)
1697 Z_PARAM_STRING(delimiter_str, delimiter_str_len)
1698 Z_PARAM_STRING(enclosure_str, enclosure_str_len)
1699 Z_PARAM_STR(escape_str)
1700 Z_PARAM_STR_OR_NULL(eol_str)
1702
1703 if (delimiter_str != NULL) {
1704 /* Make sure that there is at least one character in string */
1705 if (delimiter_str_len != 1) {
1706 zend_argument_value_error(3, "must be a single character");
1707 RETURN_THROWS();
1708 }
1709
1710 /* use first character from string */
1711 delimiter = *delimiter_str;
1712 }
1713
1714 if (enclosure_str != NULL) {
1715 if (enclosure_str_len != 1) {
1716 zend_argument_value_error(4, "must be a single character");
1717 RETURN_THROWS();
1718 }
1719 /* use first character from string */
1720 enclosure = *enclosure_str;
1721 }
1722
1723 int escape_char = php_csv_handle_escape_argument(escape_str, 5);
1724 if (escape_char == PHP_CSV_ESCAPE_ERROR) {
1725 RETURN_THROWS();
1726 }
1727
1728 PHP_STREAM_FROM_ZVAL(stream, fp);
1729
1730 ret = php_fputcsv(stream, fields, delimiter, enclosure, escape_char, eol_str);
1731 if (ret < 0) {
1733 }
1735}
1736/* }}} */
1737
1738/* {{{ PHPAPI size_t php_fputcsv(php_stream *stream, zval *fields, char delimiter, char enclosure, int escape_char, zend_string *eol_str) */
1739PHPAPI ssize_t php_fputcsv(php_stream *stream, zval *fields, char delimiter, char enclosure, int escape_char, zend_string *eol_str)
1740{
1741 uint32_t count, i = 0;
1742 size_t ret;
1743 zval *field_tmp;
1744 smart_str csvline = {0};
1745
1746 ZEND_ASSERT((escape_char >= 0 && escape_char <= UCHAR_MAX) || escape_char == PHP_CSV_NO_ESCAPE);
1747 count = zend_hash_num_elements(Z_ARRVAL_P(fields));
1748 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(fields), field_tmp) {
1749 zend_string *tmp_field_str;
1750 zend_string *field_str = zval_get_tmp_string(field_tmp, &tmp_field_str);
1751
1752 /* enclose a field that contains a delimiter, an enclosure character, or a newline */
1753 if (FPUTCSV_FLD_CHK(delimiter) ||
1754 FPUTCSV_FLD_CHK(enclosure) ||
1755 (escape_char != PHP_CSV_NO_ESCAPE && FPUTCSV_FLD_CHK(escape_char)) ||
1756 FPUTCSV_FLD_CHK('\n') ||
1757 FPUTCSV_FLD_CHK('\r') ||
1758 FPUTCSV_FLD_CHK('\t') ||
1759 FPUTCSV_FLD_CHK(' ')
1760 ) {
1761 char *ch = ZSTR_VAL(field_str);
1762 char *end = ch + ZSTR_LEN(field_str);
1763 int escaped = 0;
1764
1765 smart_str_appendc(&csvline, enclosure);
1766 while (ch < end) {
1767 if (escape_char != PHP_CSV_NO_ESCAPE && *ch == escape_char) {
1768 escaped = 1;
1769 } else if (!escaped && *ch == enclosure) {
1770 smart_str_appendc(&csvline, enclosure);
1771 } else {
1772 escaped = 0;
1773 }
1774 smart_str_appendc(&csvline, *ch);
1775 ch++;
1776 }
1777 smart_str_appendc(&csvline, enclosure);
1778 } else {
1779 smart_str_append(&csvline, field_str);
1780 }
1781
1782 if (++i != count) {
1783 smart_str_appendl(&csvline, &delimiter, 1);
1784 }
1785 zend_tmp_string_release(tmp_field_str);
1787
1788 if (eol_str) {
1789 smart_str_append(&csvline, eol_str);
1790 } else {
1791 smart_str_appendc(&csvline, '\n');
1792 }
1793 smart_str_0(&csvline);
1794
1795 ret = php_stream_write(stream, ZSTR_VAL(csvline.s), ZSTR_LEN(csvline.s));
1796
1797 smart_str_free(&csvline);
1798
1799 return ret;
1800}
1801/* }}} */
1802
1803/* {{{ Get line from file pointer and parse for CSV fields */
1805{
1806 char delimiter = ','; /* allow this to be set as parameter */
1807 char enclosure = '"'; /* allow this to be set as parameter */
1808
1809 zend_long len = 0;
1810 size_t buf_len;
1811 char *buf;
1812 php_stream *stream;
1813
1814 zval *fd;
1815 bool len_is_null = 1;
1816 char *delimiter_str = NULL;
1817 size_t delimiter_str_len = 0;
1818 char *enclosure_str = NULL;
1819 size_t enclosure_str_len = 0;
1820 zend_string *escape_str = NULL;
1821
1825 Z_PARAM_LONG_OR_NULL(len, len_is_null)
1826 Z_PARAM_STRING(delimiter_str, delimiter_str_len)
1827 Z_PARAM_STRING(enclosure_str, enclosure_str_len)
1828 Z_PARAM_STR(escape_str)
1830
1831 if (delimiter_str != NULL) {
1832 /* Make sure that there is at least one character in string */
1833 if (delimiter_str_len != 1) {
1834 zend_argument_value_error(3, "must be a single character");
1835 RETURN_THROWS();
1836 }
1837
1838 /* use first character from string */
1839 delimiter = delimiter_str[0];
1840 }
1841
1842 if (enclosure_str != NULL) {
1843 if (enclosure_str_len != 1) {
1844 zend_argument_value_error(4, "must be a single character");
1845 RETURN_THROWS();
1846 }
1847
1848 /* use first character from string */
1849 enclosure = enclosure_str[0];
1850 }
1851
1852 int escape_char = php_csv_handle_escape_argument(escape_str, 5);
1853 if (escape_char == PHP_CSV_ESCAPE_ERROR) {
1854 RETURN_THROWS();
1855 }
1856
1857 if (len_is_null || len == 0) {
1858 len = -1;
1859 } else if (len < 0 || len > (ZEND_LONG_MAX - 1)) {
1860 zend_argument_value_error(2, "must be between 0 and " ZEND_LONG_FMT, (ZEND_LONG_MAX - 1));
1861 RETURN_THROWS();
1862 }
1863
1864 PHP_STREAM_FROM_ZVAL(stream, fd);
1865
1866 if (len < 0) {
1867 if ((buf = php_stream_get_line(stream, NULL, 0, &buf_len)) == NULL) {
1869 }
1870 } else {
1871 buf = emalloc(len + 1);
1872 if (php_stream_get_line(stream, buf, len + 1, &buf_len) == NULL) {
1873 efree(buf);
1875 }
1876 }
1877
1878 HashTable *values = php_fgetcsv(stream, delimiter, enclosure, escape_char, buf_len, buf);
1879 if (values == NULL) {
1880 values = php_bc_fgetcsv_empty_line();
1881 }
1882 RETURN_ARR(values);
1883}
1884/* }}} */
1885
1887{
1888 HashTable *values = zend_new_array(1);
1889 zval tmp;
1890 ZVAL_NULL(&tmp);
1891 zend_hash_next_index_insert(values, &tmp);
1892 return values;
1893}
1894
1895PHPAPI HashTable *php_fgetcsv(php_stream *stream, char delimiter, char enclosure, int escape_char, size_t buf_len, char *buf) /* {{{ */
1896{
1897 char *temp, *bptr, *line_end, *limit;
1898 size_t temp_len, line_end_len;
1899 int inc_len;
1900 bool first_field = true;
1901
1902 ZEND_ASSERT((escape_char >= 0 && escape_char <= UCHAR_MAX) || escape_char == PHP_CSV_NO_ESCAPE);
1903
1904 /* initialize internal state */
1905 php_mb_reset();
1906
1907 /* Now into new section that parses buf for delimiter/enclosure fields */
1908
1909 /* Strip trailing space from buf, saving end of line in case required for enclosure field */
1910
1911 bptr = buf;
1912 line_end = limit = (char *)php_fgetcsv_lookup_trailing_spaces(buf, buf_len);
1913 line_end_len = buf_len - (size_t)(limit - buf);
1914
1915 /* reserve workspace for building each individual field */
1916 temp_len = buf_len;
1917 temp = emalloc(temp_len + line_end_len + 1);
1918
1919 /* Initialize values HashTable */
1920 HashTable *values = zend_new_array(0);
1921
1922 /* Main loop to read CSV fields */
1923 /* NB this routine will return NULL for a blank line */
1924 do {
1925 char *comp_end, *hunk_begin;
1926 char *tptr = temp;
1927
1928 inc_len = (bptr < limit ? (*bptr == '\0' ? 1 : php_mblen(bptr, limit - bptr)): 0);
1929 if (inc_len == 1) {
1930 char *tmp = bptr;
1931 while ((*tmp != delimiter) && isspace((int)*(unsigned char *)tmp)) {
1932 tmp++;
1933 }
1934 if (*tmp == enclosure && tmp < limit) {
1935 bptr = tmp;
1936 }
1937 }
1938
1939 if (first_field && bptr == line_end) {
1940 zend_array_destroy(values);
1941 values = NULL;
1942 break;
1943 }
1944 first_field = false;
1945 /* 2. Read field, leaving bptr pointing at start of next field */
1946 if (inc_len != 0 && *bptr == enclosure) {
1947 int state = 0;
1948
1949 bptr++; /* move on to first character in field */
1950 hunk_begin = bptr;
1951
1952 /* 2A. handle enclosure delimited field */
1953 for (;;) {
1954 switch (inc_len) {
1955 case 0:
1956 switch (state) {
1957 case 2:
1958 tptr = zend_mempcpy(tptr, hunk_begin, (bptr - hunk_begin - 1));
1959 hunk_begin = bptr;
1960 goto quit_loop_2;
1961
1962 case 1:
1963 tptr = zend_mempcpy(tptr, hunk_begin, (bptr - hunk_begin));
1964 hunk_begin = bptr;
1966
1967 case 0: {
1968 if (hunk_begin != line_end) {
1969 tptr = zend_mempcpy(tptr, hunk_begin, (bptr - hunk_begin));
1970 hunk_begin = bptr;
1971 }
1972
1973 /* add the embedded line end to the field */
1974 tptr = zend_mempcpy(tptr, line_end, line_end_len);
1975
1976 /* nothing can be fetched if stream is NULL (e.g. str_getcsv()) */
1977 if (stream == NULL) {
1978 /* the enclosure is unterminated */
1979 if (bptr > limit) {
1980 /* if the line ends with enclosure, we need to go back by
1981 * one character so the \0 character is not copied. */
1982 if (hunk_begin == bptr) {
1983 --hunk_begin;
1984 }
1985 --bptr;
1986 }
1987 goto quit_loop_2;
1988 }
1989
1990 size_t new_len;
1991 char *new_buf = php_stream_get_line(stream, NULL, 0, &new_len);
1992 if (!new_buf) {
1993 /* we've got an unterminated enclosure,
1994 * assign all the data from the start of
1995 * the enclosure to end of data to the
1996 * last element */
1997 if (bptr > limit) {
1998 /* if the line ends with enclosure, we need to go back by
1999 * one character so the \0 character is not copied. */
2000 if (hunk_begin == bptr) {
2001 --hunk_begin;
2002 }
2003 --bptr;
2004 }
2005 goto quit_loop_2;
2006 }
2007
2008 temp_len += new_len;
2009 char *new_temp = erealloc(temp, temp_len);
2010 tptr = new_temp + (size_t)(tptr - temp);
2011 temp = new_temp;
2012
2013 efree(buf);
2014 buf_len = new_len;
2015 bptr = buf = new_buf;
2016 hunk_begin = buf;
2017
2018 line_end = limit = (char *)php_fgetcsv_lookup_trailing_spaces(buf, buf_len);
2019 line_end_len = buf_len - (size_t)(limit - buf);
2020
2021 state = 0;
2022 } break;
2023 }
2024 break;
2025
2026 case -2:
2027 case -1:
2028 php_mb_reset();
2030 case 1:
2031 /* we need to determine if the enclosure is
2032 * 'real' or is it escaped */
2033 switch (state) {
2034 case 1: /* escaped */
2035 bptr++;
2036 state = 0;
2037 break;
2038 case 2: /* embedded enclosure ? let's check it */
2039 if (*bptr != enclosure) {
2040 /* real enclosure */
2041 tptr = zend_mempcpy(tptr, hunk_begin, bptr - hunk_begin - 1);
2042 hunk_begin = bptr;
2043 goto quit_loop_2;
2044 }
2045 tptr = zend_mempcpy(tptr, hunk_begin, bptr - hunk_begin);
2046 bptr++;
2047 hunk_begin = bptr;
2048 state = 0;
2049 break;
2050 default:
2051 if (*bptr == enclosure) {
2052 state = 2;
2053 } else if (escape_char != PHP_CSV_NO_ESCAPE && *bptr == escape_char) {
2054 state = 1;
2055 }
2056 bptr++;
2057 break;
2058 }
2059 break;
2060
2061 default:
2062 switch (state) {
2063 case 2:
2064 /* real enclosure */
2065 tptr = zend_mempcpy(tptr, hunk_begin, bptr - hunk_begin - 1);
2066 hunk_begin = bptr;
2067 goto quit_loop_2;
2068 case 1:
2069 bptr += inc_len;
2070 tptr = zend_mempcpy(tptr, hunk_begin, bptr - hunk_begin);
2071 hunk_begin = bptr;
2072 state = 0;
2073 break;
2074 default:
2075 bptr += inc_len;
2076 break;
2077 }
2078 break;
2079 }
2080 inc_len = (bptr < limit ? (*bptr == '\0' ? 1 : php_mblen(bptr, limit - bptr)): 0);
2081 }
2082
2083 quit_loop_2:
2084 /* look up for a delimiter */
2085 for (;;) {
2086 switch (inc_len) {
2087 case 0:
2088 goto quit_loop_3;
2089
2090 case -2:
2091 case -1:
2092 inc_len = 1;
2093 php_mb_reset();
2095 case 1:
2096 if (*bptr == delimiter) {
2097 goto quit_loop_3;
2098 }
2099 break;
2100 default:
2101 break;
2102 }
2103 bptr += inc_len;
2104 inc_len = (bptr < limit ? (*bptr == '\0' ? 1 : php_mblen(bptr, limit - bptr)): 0);
2105 }
2106
2107 quit_loop_3:
2108 tptr = zend_mempcpy(tptr, hunk_begin, bptr - hunk_begin);
2109 bptr += inc_len;
2110 comp_end = tptr;
2111 } else {
2112 /* 2B. Handle non-enclosure field */
2113
2114 hunk_begin = bptr;
2115
2116 for (;;) {
2117 switch (inc_len) {
2118 case 0:
2119 goto quit_loop_4;
2120 case -2:
2121 case -1:
2122 inc_len = 1;
2123 php_mb_reset();
2125 case 1:
2126 if (*bptr == delimiter) {
2127 goto quit_loop_4;
2128 }
2129 break;
2130 default:
2131 break;
2132 }
2133 bptr += inc_len;
2134 inc_len = (bptr < limit ? (*bptr == '\0' ? 1 : php_mblen(bptr, limit - bptr)): 0);
2135 }
2136 quit_loop_4:
2137 tptr = zend_mempcpy(tptr, hunk_begin, bptr - hunk_begin);
2138
2139 comp_end = (char *)php_fgetcsv_lookup_trailing_spaces(temp, tptr - temp);
2140 if (*bptr == delimiter) {
2141 bptr++;
2142 }
2143 }
2144
2145 /* 3. Now pass our field back to php */
2146 *comp_end = '\0';
2147
2148 zval z_tmp;
2149 ZVAL_STRINGL(&z_tmp, temp, comp_end - temp);
2150 zend_hash_next_index_insert(values, &z_tmp);
2151 } while (inc_len > 0);
2152
2153 efree(temp);
2154 if (stream) {
2155 efree(buf);
2156 }
2157
2158 return values;
2159}
2160/* }}} */
2161
2162/* {{{ Return the resolved path */
2164{
2165 char *filename;
2166 size_t filename_len;
2167 char resolved_path_buff[MAXPATHLEN];
2168
2170 Z_PARAM_PATH(filename, filename_len)
2172
2173 if (VCWD_REALPATH(filename, resolved_path_buff)) {
2174 if (php_check_open_basedir(resolved_path_buff)) {
2176 }
2177
2178#ifdef ZTS
2179 if (VCWD_ACCESS(resolved_path_buff, F_OK)) {
2181 }
2182#endif
2183 RETURN_STRING(resolved_path_buff);
2184 } else {
2186 }
2187}
2188/* }}} */
2189
2190/* See http://www.w3.org/TR/html4/intro/sgmltut.html#h-3.2.2 */
2191#define PHP_META_HTML401_CHARS "-_.:"
2192
2193/* {{{ php_next_meta_token
2194 Tokenizes an HTML file for get_meta_tags */
2196{
2197 int ch = 0, compliment;
2198 char buff[META_DEF_BUFSIZE + 1];
2199
2200 memset((void *)buff, 0, META_DEF_BUFSIZE + 1);
2201
2202 while (md->ulc || (!php_stream_eof(md->stream) && (ch = php_stream_getc(md->stream)))) {
2203 if (php_stream_eof(md->stream)) {
2204 break;
2205 }
2206
2207 if (md->ulc) {
2208 ch = md->lc;
2209 md->ulc = 0;
2210 }
2211
2212 switch (ch) {
2213 case '<':
2214 return TOK_OPENTAG;
2215 break;
2216
2217 case '>':
2218 return TOK_CLOSETAG;
2219 break;
2220
2221 case '=':
2222 return TOK_EQUAL;
2223 break;
2224 case '/':
2225 return TOK_SLASH;
2226 break;
2227
2228 case '\'':
2229 case '"':
2230 compliment = ch;
2231 md->token_len = 0;
2232 while (!php_stream_eof(md->stream) && (ch = php_stream_getc(md->stream)) && ch != compliment && ch != '<' && ch != '>') {
2233 buff[(md->token_len)++] = ch;
2234
2235 if (md->token_len == META_DEF_BUFSIZE) {
2236 break;
2237 }
2238 }
2239
2240 if (ch == '<' || ch == '>') {
2241 /* Was just an apostrophe */
2242 md->ulc = 1;
2243 md->lc = ch;
2244 }
2245
2246 /* We don't need to alloc unless we are in a meta tag */
2247 if (md->in_meta) {
2248 md->token_data = (char *) emalloc(md->token_len + 1);
2249 memcpy(md->token_data, buff, md->token_len+1);
2250 }
2251
2252 return TOK_STRING;
2253 break;
2254
2255 case '\n':
2256 case '\r':
2257 case '\t':
2258 break;
2259
2260 case ' ':
2261 return TOK_SPACE;
2262 break;
2263
2264 default:
2265 if (isalnum(ch)) {
2266 md->token_len = 0;
2267 buff[(md->token_len)++] = ch;
2268 while (!php_stream_eof(md->stream) && (ch = php_stream_getc(md->stream)) && (isalnum(ch) || strchr(PHP_META_HTML401_CHARS, ch))) {
2269 buff[(md->token_len)++] = ch;
2270
2271 if (md->token_len == META_DEF_BUFSIZE) {
2272 break;
2273 }
2274 }
2275
2276 /* This is ugly, but we have to replace ungetc */
2277 if (!isalpha(ch) && ch != '-') {
2278 md->ulc = 1;
2279 md->lc = ch;
2280 }
2281
2282 md->token_data = (char *) emalloc(md->token_len + 1);
2283 memcpy(md->token_data, buff, md->token_len+1);
2284
2285 return TOK_ID;
2286 } else {
2287 return TOK_OTHER;
2288 }
2289 break;
2290 }
2291 }
2292
2293 return TOK_EOF;
2294}
2295/* }}} */
2296
2297#ifdef HAVE_FNMATCH
2298/* {{{ Match filename against pattern */
2300{
2301 char *pattern, *filename;
2302 size_t pattern_len, filename_len;
2303 zend_long flags = 0;
2304
2306 Z_PARAM_PATH(pattern, pattern_len)
2307 Z_PARAM_PATH(filename, filename_len)
2311
2313 php_error_docref(NULL, E_WARNING, "Filename exceeds the maximum allowed length of %d characters", MAXPATHLEN);
2315 }
2316 if (pattern_len >= MAXPATHLEN) {
2317 php_error_docref(NULL, E_WARNING, "Pattern exceeds the maximum allowed length of %d characters", MAXPATHLEN);
2319 }
2320
2321 RETURN_BOOL( ! fnmatch( pattern, filename, (int)flags ));
2322}
2323/* }}} */
2324#endif
2325
2326/* {{{ Returns directory path used for temporary files */
2333/* }}} */
size_t len
Definition apprentice.c:174
bool exception
Definition assert.c:30
#define BG(v)
readfile(string $filename, bool $use_include_path=false, $context=null)
umask(?int $mask=null)
unlink(string $filename, $context=null)
fsync($stream)
rewind($stream)
ftruncate($stream, int $size)
rename(string $from, string $to, $context=null)
fgetc($stream)
file_get_contents(string $filename, bool $use_include_path=false, $context=null, int $offset=0, ?int $length=null)
fputcsv($stream, array $fields, string $separator=",", string $enclosure="\"", string $escape="\\", string $eol="\n")
file(string $filename, int $flags=0, $context=null)
fgetcsv($stream, ?int $length=null, string $separator=",", string $enclosure="\"", string $escape="\\")
feof($stream)
tempnam(string $directory, string $prefix)
fstat($stream)
copy(string $from, string $to, $context=null)
pclose($handle)
fseek($stream, int $offset, int $whence=SEEK_SET)
file_put_contents(string $filename, mixed $data, int $flags=0, $context=null)
fwrite($stream, string $data, ?int $length=null)
rmdir(string $directory, $context=null)
dir(string $directory, $context=null)
fclose($stream)
get_meta_tags(string $filename, bool $use_include_path=false)
popen(string $command, string $mode)
fnmatch(string $pattern, string $filename, int $flags=0)
ftell($stream)
fopen(string $filename, string $mode, bool $use_include_path=false, $context=null)
count(Countable|array $value, int $mode=COUNT_NORMAL)
fscanf($stream, string $format, mixed &... $vars)
fread($stream, int $length)
fflush($stream)
flock($stream, int $operation, &$would_block=null)
mkdir(string $directory, int $permissions=0777, bool $recursive=false, $context=null)
fpassthru($stream)
fgets($stream, ?int $length=null)
strchr(string $haystack, string $needle, bool $before_needle=false)
realpath(string $path)
char s[4]
Definition cdf.c:77
zend_long ch
Definition ffi.c:4580
new_type size
Definition ffi.c:4365
zend_string * res
Definition ffi.c:4692
void * ptr
Definition ffi.c:3814
memcpy(ptr1, ptr2, size)
memset(ptr, 0, type->size)
zend_ffi_ctype_name_buf buf
Definition ffi.c:4685
PHPAPI void php_fstat(php_stream *stream, zval *return_value)
Definition file.c:1369
PHPAPI HashTable * php_bc_fgetcsv_empty_line(void)
Definition file.c:1886
#define PHP_META_HTML401_CHARS
Definition file.c:2191
#define PHP_STREAM_FROM_ZVAL(stream, arg)
Definition file.c:105
php_file_globals file_globals
Definition file.c:91
PHPAPI zend_result php_copy_file(const char *src, const char *dest)
Definition file.c:1483
PHPAPI int php_le_stream_context(void)
Definition file.c:114
PHPAPI HashTable * php_fgetcsv(php_stream *stream, char delimiter, char enclosure, int escape_char, size_t buf_len, char *buf)
Definition file.c:1895
PHPAPI int php_csv_handle_escape_argument(const zend_string *escape_str, uint32_t arg_num)
Definition file.c:1656
PHPAPI ssize_t php_fputcsv(php_stream *stream, zval *fields, char delimiter, char enclosure, int escape_char, zend_string *eol_str)
Definition file.c:1739
PHPAPI zend_result php_copy_file_ex(const char *src, const char *dest, int src_flags)
Definition file.c:1490
#define FPUTCSV_FLD_CHK(c)
Definition file.c:1678
PHPAPI void php_flock_common(php_stream *stream, zend_long operation, uint32_t operation_arg_num, zval *wouldblock, zval *return_value)
Definition file.c:188
PHPAPI zend_result php_copy_file_ctx(const char *src, const char *dest, int src_flags, php_stream_context *ctx)
Definition file.c:1497
php_meta_tags_token php_next_meta_token(php_meta_tags_data *md)
Definition file.c:2195
#define PHP_META_UNSAFE
Definition file.c:235
const SEEK_END
Definition file.stub.php:21
#define LOCK_NB
#define PHP_LOCK_NB
#define PHP_LOCK_UN
PHPAPI int php_check_open_basedir(const char *path)
PHPAPI char * expand_filepath(const char *filepath, char *real_path)
size_t mode_len
zval * zcontext
bool use_include_path
zend_long offset
char * mode
zend_string * contents
zend_long maxlen
bool maxlen_is_null
size_t filename_len
#define SEEK_SET
Definition gd_io_file.c:20
#define NULL
Definition gdcache.h:45
#define prefix
#define SUCCESS
Definition hash_sha3.c:261
foreach($dp as $el) foreach( $dp as $el) if( $pass2< 2) echo ""
#define F_OK
Definition ioutil.h:86
PHPAPI ZEND_COLD void php_error_docref2(const char *docref, const char *param1, const char *param2, int type, const char *format,...)
Definition main.c:1198
PHPAPI ZEND_COLD void php_error_docref(const char *docref, int type, const char *format,...)
Definition main.c:1173
#define memmove(a, b, c)
#define PHP_FUNCTION
Definition php.h:364
#define PHP_MSHUTDOWN_FUNCTION
Definition php.h:401
#define PHP_MINIT_FUNCTION
Definition php.h:400
#define php_memnstr
Definition php.h:343
#define PHPAPI
Definition php.h:71
unsigned const char * end
Definition php_ffi.h:51
#define PHP_INI_ALL
Definition php_ini.h:45
#define PHP_INI_BEGIN
Definition php_ini.h:52
#define STD_PHP_INI_ENTRY
Definition php_ini.h:64
#define STD_PHP_INI_BOOLEAN
Definition php_ini.h:66
#define PHP_INI_MH
Definition php_ini.h:49
#define PHP_INI_END
Definition php_ini.h:53
#define PHP_SOCK_CHUNK_SIZE
#define EWOULDBLOCK
Definition php_network.h:47
PHPAPI int php_open_temporary_fd_ex(const char *dir, const char *pfx, zend_string **opened_path_p, uint32_t flags)
PHPAPI const char * php_get_temporary_directory(void)
#define PHP_TMP_FILE_OPEN_BASEDIR_CHECK_ALWAYS
#define php_stream_context_from_zval(zcontext, nocontext)
PHPAPI void php_stream_context_free(php_stream_context *context)
Definition streams.c:2370
#define php_stream_fopen_tmpfile()
PHPAPI php_stream_wrapper php_plain_files_wrapper
#define php_stream_fopen_from_pipe(file, mode)
#define php_stream_truncate_supported(stream)
#define PHP_STREAM_IS_STDIO
struct _php_stream php_stream
Definition php_streams.h:96
struct _php_stream_context php_stream_context
Definition php_streams.h:98
PHPAPI const char * php_stream_locate_eol(php_stream *stream, zend_string *buf)
Definition streams.c:879
#define php_stream_stat_path_ex(path, flags, ssb, context)
#define REPORT_ERRORS
#define php_stream_from_zval(xstr, pzval)
#define PHP_STREAM_URL_STAT_IGNORE_OPEN_BASEDIR
#define PHP_STREAM_FREE_CLOSE_PERSISTENT
#define php_stream_rewind(stream)
#define php_stream_sync(stream, d)
#define php_stream_get_line(stream, buf, maxlen, retlen)
#define php_stream_mkdir(path, mode, options, context)
#define PHP_STREAM_COPY_ALL
#define php_stream_getc(stream)
#define PHP_STREAM_BUFFER_NONE
#define php_stream_seek(stream, offset, whence)
#define php_stream_flush(stream)
#define PHP_STREAM_MKDIR_RECURSIVE
#define php_stream_supports_lock(stream)
PHPAPI zend_string * php_stream_read_to_str(php_stream *stream, size_t len)
Definition streams.c:792
#define php_stream_to_zval(stream, zval)
#define php_stream_truncate_set_size(stream, size)
#define php_stream_eof(stream)
#define php_stream_open_wrapper_ex(path, mode, options, opened, context)
#define php_stream_free(stream, close_options)
#define php_stream_close(stream)
#define PHP_STREAM_FREE_CLOSE
#define php_stream_is(stream, anops)
#define php_stream_tell(stream)
#define STREAM_DISABLE_OPEN_BASEDIR
#define php_stream_copy_to_mem(src, maxlen, persistent)
#define php_stream_sync_supported(stream)
#define PHP_STREAM_OPTION_READ_BUFFER
#define php_stream_lock(stream, mode)
#define php_stream_open_wrapper(path, mode, options, opened)
#define PHP_STREAM_FREE_KEEP_RSRC
PHPAPI int php_file_le_pstream(void)
Definition streams.c:47
#define php_stream_stat(stream, ssb)
struct _php_stream_wrapper php_stream_wrapper
Definition php_streams.h:97
#define php_stream_rmdir(path, options, context)
#define PHP_STREAM_FLAG_NO_FCLOSE
#define PHP_STREAM_FLAG_EOL_MAC
#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 USE_PATH
#define php_stream_set_option(stream, option, value, ptrvalue)
#define PHP_STREAM_URL_STAT_QUIET
#define php_stream_passthru(stream)
struct _php_stream_statbuf php_stream_statbuf
#define php_stream_write(stream, buf, count)
PHPAPI int php_file_le_stream(void)
Definition streams.c:42
PHPAPI zend_string * php_basename(const char *s, size_t len, const char *suffix, size_t sufflen)
Definition string.c:1372
#define php_mb_reset()
Definition php_string.h:67
#define php_mblen(ptr, len)
Definition php_string.h:66
int fd
Definition phpdbg.h:282
zend_constant * data
#define fdatasync
PHPAPI int php_sscanf_internal(char *string, char *format, int argCount, zval *args, int varStart, zval *return_value)
Definition scanf.c:574
#define SCAN_ERROR_WRONG_PARAM_COUNT
Definition scanf.h:31
p
Definition session.c:1105
#define PHP_FILE_USE_INCLUDE_PATH
Definition file.h:57
#define PHP_FILE_NO_DEFAULT_CONTEXT
Definition file.h:61
@ TOK_SLASH
Definition file.h:73
@ TOK_CLOSETAG
Definition file.h:72
@ TOK_OTHER
Definition file.h:78
@ TOK_OPENTAG
Definition file.h:71
@ TOK_EQUAL
Definition file.h:74
@ TOK_STRING
Definition file.h:77
@ TOK_ID
Definition file.h:76
@ TOK_SPACE
Definition file.h:75
@ TOK_EOF
Definition file.h:70
#define PHP_CSV_NO_ESCAPE
Definition file.h:47
#define META_DEF_BUFSIZE
Definition file.h:55
#define PHP_FILE_APPEND
Definition file.h:60
#define PHP_FILE_IGNORE_NEW_LINES
Definition file.h:58
#define PHP_FILE_SKIP_EMPTY_LINES
Definition file.h:59
#define PHP_CSV_ESCAPE_ERROR
Definition file.h:48
enum _php_meta_tags_token php_meta_tags_token
#define FG(v)
Definition file.h:117
struct _php_meta_tags_data php_meta_tags_data
char * token_data
Definition file.h:86
php_stream * stream
Definition file.h:82
int(* rename)(php_stream_wrapper *wrapper, const char *url_from, const char *url_to, int options, php_stream_context *context)
int(* unlink)(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context)
const php_stream_wrapper_ops * wops
uint16_t is_persistent
uint32_t flags
zend_resource * res
zend_long handle
Definition zend_types.h:568
Definition dce.c:49
size_t def_chunk_size
Definition file.h:95
zend_string * s
#define close(a)
#define errno
ZEND_API ZEND_COLD void zend_error(int type, const char *format,...)
Definition zend.c:1666
ZEND_API void add_index_stringl(zval *arg, zend_ulong index, const char *str, size_t length)
Definition zend_API.c:2096
ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format,...)
Definition zend_API.c:433
#define RETURN_CHAR(c)
Definition zend_API.h:1048
#define RETURN_STRING(s)
Definition zend_API.h:1043
#define ZEND_PARSE_PARAMETERS_END()
Definition zend_API.h:1641
#define RETURN_FALSE
Definition zend_API.h:1058
#define Z_PARAM_RESOURCE(dest)
Definition zend_API.h:2056
#define Z_PARAM_STR_OR_NULL(dest)
Definition zend_API.h:2089
#define ZEND_PARSE_PARAMETERS_NONE()
Definition zend_API.h:1623
#define RETURN_ARR(r)
Definition zend_API.h:1050
#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 ZEND_PARSE_PARAMETERS_START(min_num_args, max_num_args)
Definition zend_API.h:1620
#define RETVAL_EMPTY_STRING()
Definition zend_API.h:1021
#define ZEND_TRY_ASSIGN_REF_LONG(zv, lval)
Definition zend_API.h:1205
#define Z_PARAM_LONG(dest)
Definition zend_API.h:1896
#define Z_PARAM_VARIADIC(spec, dest, dest_num)
Definition zend_API.h:2124
#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 RETURN_STR(s)
Definition zend_API.h:1039
#define Z_PARAM_LONG_OR_NULL(dest, is_null)
Definition zend_API.h:1899
#define Z_PARAM_BOOL(dest)
Definition zend_API.h:1726
#define Z_PARAM_PATH(dest, dest_len)
Definition zend_API.h:2026
#define Z_PARAM_ARRAY(dest)
Definition zend_API.h:1682
#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 ZVAL_STRINGL(z, s, l)
Definition zend_API.h:952
#define WRONG_PARAM_COUNT
Definition zend_API.h:529
#define RETVAL_FALSE
Definition zend_API.h:1032
#define RETURN_TRUE
Definition zend_API.h:1059
#define RETVAL_STRINGL(s, l)
Definition zend_API.h:1018
#define array_init(arg)
Definition zend_API.h:537
#define estrndup(s, length)
Definition zend_alloc.h:165
#define efree(ptr)
Definition zend_alloc.h:155
#define erealloc(ptr, size)
Definition zend_alloc.h:159
#define emalloc(size)
Definition zend_alloc.h:151
struct _zval_struct zval
strlen(string $string)
strcmp(string $string1, string $string2)
zend_string_release_ex(func->internal_function.function_name, 0)
zval * args
#define strncasecmp(s1, s2, n)
#define strcasecmp(s1, s2)
#define E_WARNING
Definition zend_errors.h:24
#define E_DEPRECATED
Definition zend_errors.h:37
#define LOCK_UN
#define LOCK_EX
#define LOCK_SH
#define EG(v)
ZEND_API zval *ZEND_FASTCALL zend_hash_next_index_insert(HashTable *ht, zval *pData)
Definition zend_hash.c:1224
ZEND_API void ZEND_FASTCALL zend_array_destroy(HashTable *ht)
Definition zend_hash.c:1808
ZEND_API zval *ZEND_FASTCALL zend_hash_str_add_new(HashTable *ht, const char *str, size_t len, zval *pData)
Definition zend_hash.c:1052
#define zend_new_array(size)
Definition zend_hash.h:338
#define ZEND_HASH_FOREACH_END()
Definition zend_hash.h:1086
#define ZEND_HASH_FOREACH_VAL(ht, _val)
Definition zend_hash.h:1102
ZEND_API bool zend_ini_parse_bool(zend_string *str)
Definition zend_ini.c:573
#define REGISTER_INI_ENTRIES()
Definition zend_ini.h:203
ZEND_API void * zend_fetch_resource2(zend_resource *res, const char *resource_type_name, int resource_type1, int resource_type2)
Definition zend_list.c:96
ZEND_API void ZEND_FASTCALL zend_list_close(zend_resource *res)
Definition zend_list.c:78
ZEND_API int zend_register_list_destructors_ex(rsrc_dtor_func_t ld, rsrc_dtor_func_t pld, const char *type_name, int module_number)
Definition zend_list.c:265
#define ZEND_RSRC_DTOR_FUNC(name)
Definition zend_list.h:29
int32_t zend_long
Definition zend_long.h:42
#define ZEND_LONG_FMT
Definition zend_long.h:87
#define ZEND_LONG_MAX
Definition zend_long.h:45
struct _zend_string zend_string
ZEND_API zend_result zend_std_cast_object_tostring(zend_object *readobj, zval *writeobj, int type)
ZEND_API void ZEND_FASTCALL zend_str_tolower(char *str, size_t length)
#define convert_to_string(op)
#define MIN(a, b)
#define ZEND_FALLTHROUGH
#define ZEND_ASSERT(c)
#define UNEXPECTED(condition)
#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 IS_TRUE
Definition zend_types.h:603
#define ZVAL_UNDEF(z)
#define IS_FALSE
Definition zend_types.h:602
#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_LONG(z, l)
#define IS_STRING
Definition zend_types.h:606
struct _zend_array HashTable
Definition zend_types.h:386
#define IS_RESOURCE
Definition zend_types.h:609
#define Z_OBJ_P(zval_p)
Definition zend_types.h:990
#define IS_ARRAY
Definition zend_types.h:607
#define Z_OBJ_HT_P(zval_p)
Definition zend_types.h:993
#define IS_DOUBLE
Definition zend_types.h:605
#define Z_STRLEN_P(zval_p)
Definition zend_types.h:978
#define IS_NULL
Definition zend_types.h:601
#define Z_STRVAL(zval)
Definition zend_types.h:974
@ FAILURE
Definition zend_types.h:61
#define Z_STRLEN(zval)
Definition zend_types.h:977
#define IS_OBJECT
Definition zend_types.h:608
#define IS_LONG
Definition zend_types.h:604
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
ZEND_API void zval_ptr_dtor(zval *zval_ptr)
#define S_ISDIR(mode)
#define VCWD_POPEN(command, type)
#define MAXPATHLEN
#define VCWD_ACCESS(pathname, mode)
#define VCWD_REALPATH(path, real_path)
zval * return_value
uint32_t arg_num
zend_string * name
bool result
zval * ret
value
out($f, $s)