1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 5 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2016 The PHP Group |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Author: Marcus Boerger <helly@php.net> |
16 +----------------------------------------------------------------------+
17 */
18
19 /* $Id$ */
20
21 #ifdef HAVE_CONFIG_H
22 # include "config.h"
23 #endif
24
25 #include "php.h"
26 #include "php_ini.h"
27 #include "ext/standard/info.h"
28 #include "ext/standard/file.h"
29 #include "ext/standard/php_string.h"
30 #include "zend_compile.h"
31 #include "zend_exceptions.h"
32 #include "zend_interfaces.h"
33
34 #include "php_spl.h"
35 #include "spl_functions.h"
36 #include "spl_engine.h"
37 #include "spl_iterators.h"
38 #include "spl_directory.h"
39 #include "spl_exceptions.h"
40
41 #include "php.h"
42 #include "fopen_wrappers.h"
43
44 #include "ext/standard/basic_functions.h"
45 #include "ext/standard/php_filestat.h"
46
47 #define SPL_HAS_FLAG(flags, test_flag) ((flags & test_flag) ? 1 : 0)
48
49 /* declare the class handlers */
50 static zend_object_handlers spl_filesystem_object_handlers;
51 /* includes handler to validate object state when retrieving methods */
52 static zend_object_handlers spl_filesystem_object_check_handlers;
53
54 /* decalre the class entry */
55 PHPAPI zend_class_entry *spl_ce_SplFileInfo;
56 PHPAPI zend_class_entry *spl_ce_DirectoryIterator;
57 PHPAPI zend_class_entry *spl_ce_FilesystemIterator;
58 PHPAPI zend_class_entry *spl_ce_RecursiveDirectoryIterator;
59 PHPAPI zend_class_entry *spl_ce_GlobIterator;
60 PHPAPI zend_class_entry *spl_ce_SplFileObject;
61 PHPAPI zend_class_entry *spl_ce_SplTempFileObject;
62
spl_filesystem_file_free_line(spl_filesystem_object * intern TSRMLS_DC)63 static void spl_filesystem_file_free_line(spl_filesystem_object *intern TSRMLS_DC) /* {{{ */
64 {
65 if (intern->u.file.current_line) {
66 efree(intern->u.file.current_line);
67 intern->u.file.current_line = NULL;
68 }
69 if (intern->u.file.current_zval) {
70 zval_ptr_dtor(&intern->u.file.current_zval);
71 intern->u.file.current_zval = NULL;
72 }
73 } /* }}} */
74
spl_filesystem_object_free_storage(void * object TSRMLS_DC)75 static void spl_filesystem_object_free_storage(void *object TSRMLS_DC) /* {{{ */
76 {
77 spl_filesystem_object *intern = (spl_filesystem_object*)object;
78
79 if (intern->oth_handler && intern->oth_handler->dtor) {
80 intern->oth_handler->dtor(intern TSRMLS_CC);
81 }
82
83 zend_object_std_dtor(&intern->std TSRMLS_CC);
84
85 if (intern->_path) {
86 efree(intern->_path);
87 }
88 if (intern->file_name) {
89 efree(intern->file_name);
90 }
91 switch(intern->type) {
92 case SPL_FS_INFO:
93 break;
94 case SPL_FS_DIR:
95 if (intern->u.dir.dirp) {
96 php_stream_close(intern->u.dir.dirp);
97 intern->u.dir.dirp = NULL;
98 }
99 if (intern->u.dir.sub_path) {
100 efree(intern->u.dir.sub_path);
101 }
102 break;
103 case SPL_FS_FILE:
104 if (intern->u.file.stream) {
105 if (intern->u.file.zcontext) {
106 /* zend_list_delref(Z_RESVAL_P(intern->zcontext));*/
107 }
108 if (!intern->u.file.stream->is_persistent) {
109 php_stream_free(intern->u.file.stream, PHP_STREAM_FREE_CLOSE);
110 } else {
111 php_stream_free(intern->u.file.stream, PHP_STREAM_FREE_CLOSE_PERSISTENT);
112 }
113 if (intern->u.file.open_mode) {
114 efree(intern->u.file.open_mode);
115 }
116 if (intern->orig_path) {
117 efree(intern->orig_path);
118 }
119 }
120 spl_filesystem_file_free_line(intern TSRMLS_CC);
121 break;
122 }
123
124 {
125 zend_object_iterator *iterator;
126 iterator = (zend_object_iterator*)
127 spl_filesystem_object_to_iterator(intern);
128 if (iterator->data != NULL) {
129 iterator->data = NULL;
130 iterator->funcs->dtor(iterator TSRMLS_CC);
131 }
132 }
133 efree(object);
134 } /* }}} */
135
136 /* {{{ spl_ce_dir_object_new */
137 /* creates the object by
138 - allocating memory
139 - initializing the object members
140 - storing the object
141 - setting it's handlers
142
143 called from
144 - clone
145 - new
146 */
spl_filesystem_object_new_ex(zend_class_entry * class_type,spl_filesystem_object ** obj TSRMLS_DC)147 static zend_object_value spl_filesystem_object_new_ex(zend_class_entry *class_type, spl_filesystem_object **obj TSRMLS_DC)
148 {
149 zend_object_value retval;
150 spl_filesystem_object *intern;
151
152 intern = emalloc(sizeof(spl_filesystem_object));
153 memset(intern, 0, sizeof(spl_filesystem_object));
154 /* intern->type = SPL_FS_INFO; done by set 0 */
155 intern->file_class = spl_ce_SplFileObject;
156 intern->info_class = spl_ce_SplFileInfo;
157 if (obj) *obj = intern;
158
159 zend_object_std_init(&intern->std, class_type TSRMLS_CC);
160 object_properties_init(&intern->std, class_type);
161
162 retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) spl_filesystem_object_free_storage, NULL TSRMLS_CC);
163 retval.handlers = &spl_filesystem_object_handlers;
164 return retval;
165 }
166 /* }}} */
167
168 /* {{{ spl_filesystem_object_new */
169 /* See spl_filesystem_object_new_ex */
spl_filesystem_object_new(zend_class_entry * class_type TSRMLS_DC)170 static zend_object_value spl_filesystem_object_new(zend_class_entry *class_type TSRMLS_DC)
171 {
172 return spl_filesystem_object_new_ex(class_type, NULL TSRMLS_CC);
173 }
174 /* }}} */
175
176 /* {{{ spl_filesystem_object_new_ex */
spl_filesystem_object_new_check(zend_class_entry * class_type TSRMLS_DC)177 static zend_object_value spl_filesystem_object_new_check(zend_class_entry *class_type TSRMLS_DC)
178 {
179 zend_object_value ret = spl_filesystem_object_new_ex(class_type, NULL TSRMLS_CC);
180 ret.handlers = &spl_filesystem_object_check_handlers;
181 return ret;
182 }
183 /* }}} */
184
185
spl_filesystem_object_get_path(spl_filesystem_object * intern,int * len TSRMLS_DC)186 PHPAPI char* spl_filesystem_object_get_path(spl_filesystem_object *intern, int *len TSRMLS_DC) /* {{{ */
187 {
188 #ifdef HAVE_GLOB
189 if (intern->type == SPL_FS_DIR) {
190 if (php_stream_is(intern->u.dir.dirp ,&php_glob_stream_ops)) {
191 return php_glob_stream_get_path(intern->u.dir.dirp, 0, len);
192 }
193 }
194 #endif
195 if (len) {
196 *len = intern->_path_len;
197 }
198 return intern->_path;
199 } /* }}} */
200
spl_filesystem_object_get_file_name(spl_filesystem_object * intern TSRMLS_DC)201 static inline void spl_filesystem_object_get_file_name(spl_filesystem_object *intern TSRMLS_DC) /* {{{ */
202 {
203 char slash = SPL_HAS_FLAG(intern->flags, SPL_FILE_DIR_UNIXPATHS) ? '/' : DEFAULT_SLASH;
204
205 switch (intern->type) {
206 case SPL_FS_INFO:
207 case SPL_FS_FILE:
208 if (!intern->file_name) {
209 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Object not initialized");
210 }
211 break;
212 case SPL_FS_DIR:
213 if (intern->file_name) {
214 efree(intern->file_name);
215 }
216 intern->file_name_len = spprintf(&intern->file_name, 0, "%s%c%s",
217 spl_filesystem_object_get_path(intern, NULL TSRMLS_CC),
218 slash, intern->u.dir.entry.d_name);
219 break;
220 }
221 } /* }}} */
222
spl_filesystem_dir_read(spl_filesystem_object * intern TSRMLS_DC)223 static int spl_filesystem_dir_read(spl_filesystem_object *intern TSRMLS_DC) /* {{{ */
224 {
225 if (!intern->u.dir.dirp || !php_stream_readdir(intern->u.dir.dirp, &intern->u.dir.entry)) {
226 intern->u.dir.entry.d_name[0] = '\0';
227 return 0;
228 } else {
229 return 1;
230 }
231 }
232 /* }}} */
233
234 #define IS_SLASH_AT(zs, pos) (IS_SLASH(zs[pos]))
235
spl_filesystem_is_dot(const char * d_name)236 static inline int spl_filesystem_is_dot(const char * d_name) /* {{{ */
237 {
238 return !strcmp(d_name, ".") || !strcmp(d_name, "..");
239 }
240 /* }}} */
241
242 /* {{{ spl_filesystem_dir_open */
243 /* open a directory resource */
spl_filesystem_dir_open(spl_filesystem_object * intern,char * path TSRMLS_DC)244 static void spl_filesystem_dir_open(spl_filesystem_object* intern, char *path TSRMLS_DC)
245 {
246 int skip_dots = SPL_HAS_FLAG(intern->flags, SPL_FILE_DIR_SKIPDOTS);
247
248 intern->type = SPL_FS_DIR;
249 intern->_path_len = strlen(path);
250 intern->u.dir.dirp = php_stream_opendir(path, REPORT_ERRORS, FG(default_context));
251
252 if (intern->_path_len > 1 && IS_SLASH_AT(path, intern->_path_len-1)) {
253 intern->_path = estrndup(path, --intern->_path_len);
254 } else {
255 intern->_path = estrndup(path, intern->_path_len);
256 }
257 intern->u.dir.index = 0;
258
259 if (EG(exception) || intern->u.dir.dirp == NULL) {
260 intern->u.dir.entry.d_name[0] = '\0';
261 if (!EG(exception)) {
262 /* open failed w/out notice (turned to exception due to EH_THROW) */
263 zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0
264 TSRMLS_CC, "Failed to open directory \"%s\"", path);
265 }
266 } else {
267 do {
268 spl_filesystem_dir_read(intern TSRMLS_CC);
269 } while (skip_dots && spl_filesystem_is_dot(intern->u.dir.entry.d_name));
270 }
271 }
272 /* }}} */
273
spl_filesystem_file_open(spl_filesystem_object * intern,int use_include_path,int silent TSRMLS_DC)274 static int spl_filesystem_file_open(spl_filesystem_object *intern, int use_include_path, int silent TSRMLS_DC) /* {{{ */
275 {
276 zval tmp;
277
278 intern->type = SPL_FS_FILE;
279
280 php_stat(intern->file_name, intern->file_name_len, FS_IS_DIR, &tmp TSRMLS_CC);
281 if (Z_LVAL(tmp)) {
282 intern->u.file.open_mode = NULL;
283 intern->file_name = NULL;
284 zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Cannot use SplFileObject with directories");
285 return FAILURE;
286 }
287
288 intern->u.file.context = php_stream_context_from_zval(intern->u.file.zcontext, 0);
289 intern->u.file.stream = php_stream_open_wrapper_ex(intern->file_name, intern->u.file.open_mode, (use_include_path ? USE_PATH : 0) | REPORT_ERRORS, NULL, intern->u.file.context);
290
291 if (!intern->file_name_len || !intern->u.file.stream) {
292 if (!EG(exception)) {
293 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot open file '%s'", intern->file_name_len ? intern->file_name : "");
294 }
295 intern->file_name = NULL; /* until here it is not a copy */
296 intern->u.file.open_mode = NULL;
297 return FAILURE;
298 }
299
300 if (intern->u.file.zcontext) {
301 zend_list_addref(Z_RESVAL_P(intern->u.file.zcontext));
302 }
303
304 if (intern->file_name_len > 1 && IS_SLASH_AT(intern->file_name, intern->file_name_len-1)) {
305 intern->file_name_len--;
306 }
307
308 intern->orig_path = estrndup(intern->u.file.stream->orig_path, strlen(intern->u.file.stream->orig_path));
309
310 intern->file_name = estrndup(intern->file_name, intern->file_name_len);
311 intern->u.file.open_mode = estrndup(intern->u.file.open_mode, intern->u.file.open_mode_len);
312
313 /* avoid reference counting in debug mode, thus do it manually */
314 ZVAL_RESOURCE(&intern->u.file.zresource, php_stream_get_resource_id(intern->u.file.stream));
315 Z_SET_REFCOUNT(intern->u.file.zresource, 1);
316
317 intern->u.file.delimiter = ',';
318 intern->u.file.enclosure = '"';
319 intern->u.file.escape = '\\';
320
321 zend_hash_find(&intern->std.ce->function_table, "getcurrentline", sizeof("getcurrentline"), (void **) &intern->u.file.func_getCurr);
322
323 return SUCCESS;
324 } /* }}} */
325
326 /* {{{ spl_filesystem_object_clone */
327 /* Local zend_object_value creation (on stack)
328 Load the 'other' object
329 Create a new empty object (See spl_filesystem_object_new_ex)
330 Open the directory
331 Clone other members (properties)
332 */
spl_filesystem_object_clone(zval * zobject TSRMLS_DC)333 static zend_object_value spl_filesystem_object_clone(zval *zobject TSRMLS_DC)
334 {
335 zend_object_value new_obj_val;
336 zend_object *old_object;
337 zend_object *new_object;
338 zend_object_handle handle = Z_OBJ_HANDLE_P(zobject);
339 spl_filesystem_object *intern;
340 spl_filesystem_object *source;
341 int index, skip_dots;
342
343 old_object = zend_objects_get_address(zobject TSRMLS_CC);
344 source = (spl_filesystem_object*)old_object;
345
346 new_obj_val = spl_filesystem_object_new_ex(old_object->ce, &intern TSRMLS_CC);
347 new_object = &intern->std;
348
349 intern->flags = source->flags;
350
351 switch (source->type) {
352 case SPL_FS_INFO:
353 intern->_path_len = source->_path_len;
354 intern->_path = estrndup(source->_path, source->_path_len);
355 intern->file_name_len = source->file_name_len;
356 intern->file_name = estrndup(source->file_name, intern->file_name_len);
357 break;
358 case SPL_FS_DIR:
359 spl_filesystem_dir_open(intern, source->_path TSRMLS_CC);
360 /* read until we hit the position in which we were before */
361 skip_dots = SPL_HAS_FLAG(source->flags, SPL_FILE_DIR_SKIPDOTS);
362 for(index = 0; index < source->u.dir.index; ++index) {
363 do {
364 spl_filesystem_dir_read(intern TSRMLS_CC);
365 } while (skip_dots && spl_filesystem_is_dot(intern->u.dir.entry.d_name));
366 }
367 intern->u.dir.index = index;
368 break;
369 case SPL_FS_FILE:
370 php_error_docref(NULL TSRMLS_CC, E_ERROR, "An object of class %s cannot be cloned", old_object->ce->name);
371 break;
372 }
373
374 intern->file_class = source->file_class;
375 intern->info_class = source->info_class;
376 intern->oth = source->oth;
377 intern->oth_handler = source->oth_handler;
378
379 zend_objects_clone_members(new_object, new_obj_val, old_object, handle TSRMLS_CC);
380
381 if (intern->oth_handler && intern->oth_handler->clone) {
382 intern->oth_handler->clone(source, intern TSRMLS_CC);
383 }
384
385 return new_obj_val;
386 }
387 /* }}} */
388
spl_filesystem_info_set_filename(spl_filesystem_object * intern,char * path,int len,int use_copy TSRMLS_DC)389 void spl_filesystem_info_set_filename(spl_filesystem_object *intern, char *path, int len, int use_copy TSRMLS_DC) /* {{{ */
390 {
391 char *p1, *p2;
392
393 if (intern->file_name) {
394 efree(intern->file_name);
395 }
396
397 intern->file_name = use_copy ? estrndup(path, len) : path;
398 intern->file_name_len = len;
399
400 while(IS_SLASH_AT(intern->file_name, intern->file_name_len-1) && intern->file_name_len > 1) {
401 intern->file_name[intern->file_name_len-1] = 0;
402 intern->file_name_len--;
403 }
404
405 p1 = strrchr(intern->file_name, '/');
406 #if defined(PHP_WIN32) || defined(NETWARE)
407 p2 = strrchr(intern->file_name, '\\');
408 #else
409 p2 = 0;
410 #endif
411 if (p1 || p2) {
412 intern->_path_len = (p1 > p2 ? p1 : p2) - intern->file_name;
413 } else {
414 intern->_path_len = 0;
415 }
416
417 if (intern->_path) {
418 efree(intern->_path);
419 }
420 intern->_path = estrndup(path, intern->_path_len);
421 } /* }}} */
422
spl_filesystem_object_create_info(spl_filesystem_object * source,char * file_path,int file_path_len,int use_copy,zend_class_entry * ce,zval * return_value TSRMLS_DC)423 static spl_filesystem_object * spl_filesystem_object_create_info(spl_filesystem_object *source, char *file_path, int file_path_len, int use_copy, zend_class_entry *ce, zval *return_value TSRMLS_DC) /* {{{ */
424 {
425 spl_filesystem_object *intern;
426 zval *arg1;
427 zend_error_handling error_handling;
428
429 if (!file_path || !file_path_len) {
430 #if defined(PHP_WIN32)
431 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot create SplFileInfo for empty path");
432 if (file_path && !use_copy) {
433 efree(file_path);
434 }
435 #else
436 if (file_path && !use_copy) {
437 efree(file_path);
438 }
439 file_path_len = 1;
440 file_path = "/";
441 #endif
442 return NULL;
443 }
444
445 zend_replace_error_handling(EH_THROW, spl_ce_RuntimeException, &error_handling TSRMLS_CC);
446
447 ce = ce ? ce : source->info_class;
448
449 zend_update_class_constants(ce TSRMLS_CC);
450
451 return_value->value.obj = spl_filesystem_object_new_ex(ce, &intern TSRMLS_CC);
452 Z_TYPE_P(return_value) = IS_OBJECT;
453
454 if (ce->constructor->common.scope != spl_ce_SplFileInfo) {
455 MAKE_STD_ZVAL(arg1);
456 ZVAL_STRINGL(arg1, file_path, file_path_len, use_copy);
457 zend_call_method_with_1_params(&return_value, ce, &ce->constructor, "__construct", NULL, arg1);
458 zval_ptr_dtor(&arg1);
459 } else {
460 spl_filesystem_info_set_filename(intern, file_path, file_path_len, use_copy TSRMLS_CC);
461 }
462
463 zend_restore_error_handling(&error_handling TSRMLS_CC);
464 return intern;
465 } /* }}} */
466
spl_filesystem_object_create_type(int ht,spl_filesystem_object * source,int type,zend_class_entry * ce,zval * return_value TSRMLS_DC)467 static spl_filesystem_object * spl_filesystem_object_create_type(int ht, spl_filesystem_object *source, int type, zend_class_entry *ce, zval *return_value TSRMLS_DC) /* {{{ */
468 {
469 spl_filesystem_object *intern;
470 zend_bool use_include_path = 0;
471 zval *arg1, *arg2;
472 zend_error_handling error_handling;
473
474 zend_replace_error_handling(EH_THROW, spl_ce_RuntimeException, &error_handling TSRMLS_CC);
475
476 switch (source->type) {
477 case SPL_FS_INFO:
478 case SPL_FS_FILE:
479 break;
480 case SPL_FS_DIR:
481 if (!source->u.dir.entry.d_name[0]) {
482 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Could not open file");
483 zend_restore_error_handling(&error_handling TSRMLS_CC);
484 return NULL;
485 }
486 }
487
488 switch (type) {
489 case SPL_FS_INFO:
490 ce = ce ? ce : source->info_class;
491
492 zend_update_class_constants(ce TSRMLS_CC);
493
494 return_value->value.obj = spl_filesystem_object_new_ex(ce, &intern TSRMLS_CC);
495 Z_TYPE_P(return_value) = IS_OBJECT;
496
497 spl_filesystem_object_get_file_name(source TSRMLS_CC);
498 if (ce->constructor->common.scope != spl_ce_SplFileInfo) {
499 MAKE_STD_ZVAL(arg1);
500 ZVAL_STRINGL(arg1, source->file_name, source->file_name_len, 1);
501 zend_call_method_with_1_params(&return_value, ce, &ce->constructor, "__construct", NULL, arg1);
502 zval_ptr_dtor(&arg1);
503 } else {
504 intern->file_name = estrndup(source->file_name, source->file_name_len);
505 intern->file_name_len = source->file_name_len;
506 intern->_path = spl_filesystem_object_get_path(source, &intern->_path_len TSRMLS_CC);
507 intern->_path = estrndup(intern->_path, intern->_path_len);
508 }
509 break;
510 case SPL_FS_FILE:
511 ce = ce ? ce : source->file_class;
512
513 zend_update_class_constants(ce TSRMLS_CC);
514
515 return_value->value.obj = spl_filesystem_object_new_ex(ce, &intern TSRMLS_CC);
516 Z_TYPE_P(return_value) = IS_OBJECT;
517
518 spl_filesystem_object_get_file_name(source TSRMLS_CC);
519
520 if (ce->constructor->common.scope != spl_ce_SplFileObject) {
521 MAKE_STD_ZVAL(arg1);
522 MAKE_STD_ZVAL(arg2);
523 ZVAL_STRINGL(arg1, source->file_name, source->file_name_len, 1);
524 ZVAL_STRINGL(arg2, "r", 1, 1);
525 zend_call_method_with_2_params(&return_value, ce, &ce->constructor, "__construct", NULL, arg1, arg2);
526 zval_ptr_dtor(&arg1);
527 zval_ptr_dtor(&arg2);
528 } else {
529 intern->file_name = source->file_name;
530 intern->file_name_len = source->file_name_len;
531 intern->_path = spl_filesystem_object_get_path(source, &intern->_path_len TSRMLS_CC);
532 intern->_path = estrndup(intern->_path, intern->_path_len);
533
534 intern->u.file.open_mode = "r";
535 intern->u.file.open_mode_len = 1;
536
537 if (ht && zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sbr",
538 &intern->u.file.open_mode, &intern->u.file.open_mode_len,
539 &use_include_path, &intern->u.file.zcontext) == FAILURE) {
540 zend_restore_error_handling(&error_handling TSRMLS_CC);
541 intern->u.file.open_mode = NULL;
542 intern->file_name = NULL;
543 zval_dtor(return_value);
544 Z_TYPE_P(return_value) = IS_NULL;
545 return NULL;
546 }
547
548 if (spl_filesystem_file_open(intern, use_include_path, 0 TSRMLS_CC) == FAILURE) {
549 zend_restore_error_handling(&error_handling TSRMLS_CC);
550 zval_dtor(return_value);
551 Z_TYPE_P(return_value) = IS_NULL;
552 return NULL;
553 }
554 }
555 break;
556 case SPL_FS_DIR:
557 zend_restore_error_handling(&error_handling TSRMLS_CC);
558 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Operation not supported");
559 return NULL;
560 }
561 zend_restore_error_handling(&error_handling TSRMLS_CC);
562 return NULL;
563 } /* }}} */
564
spl_filesystem_is_invalid_or_dot(const char * d_name)565 static int spl_filesystem_is_invalid_or_dot(const char * d_name) /* {{{ */
566 {
567 return d_name[0] == '\0' || spl_filesystem_is_dot(d_name);
568 }
569 /* }}} */
570
spl_filesystem_object_get_pathname(spl_filesystem_object * intern,int * len TSRMLS_DC)571 static char *spl_filesystem_object_get_pathname(spl_filesystem_object *intern, int *len TSRMLS_DC) { /* {{{ */
572 switch (intern->type) {
573 case SPL_FS_INFO:
574 case SPL_FS_FILE:
575 *len = intern->file_name_len;
576 return intern->file_name;
577 case SPL_FS_DIR:
578 if (intern->u.dir.entry.d_name[0]) {
579 spl_filesystem_object_get_file_name(intern TSRMLS_CC);
580 *len = intern->file_name_len;
581 return intern->file_name;
582 }
583 }
584 *len = 0;
585 return NULL;
586 }
587 /* }}} */
588
spl_filesystem_object_get_debug_info(zval * obj,int * is_temp TSRMLS_DC)589 static HashTable* spl_filesystem_object_get_debug_info(zval *obj, int *is_temp TSRMLS_DC) /* {{{ */
590 {
591 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(obj TSRMLS_CC);
592 HashTable *rv;
593 zval *tmp, zrv;
594 char *pnstr, *path;
595 int pnlen, path_len;
596 char stmp[2];
597
598 *is_temp = 1;
599
600 if (!intern->std.properties) {
601 rebuild_object_properties(&intern->std);
602 }
603
604 ALLOC_HASHTABLE(rv);
605 ZEND_INIT_SYMTABLE_EX(rv, zend_hash_num_elements(intern->std.properties) + 3, 0);
606
607 INIT_PZVAL(&zrv);
608 Z_ARRVAL(zrv) = rv;
609
610 zend_hash_copy(rv, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
611
612 pnstr = spl_gen_private_prop_name(spl_ce_SplFileInfo, "pathName", sizeof("pathName")-1, &pnlen TSRMLS_CC);
613 path = spl_filesystem_object_get_pathname(intern, &path_len TSRMLS_CC);
614 add_assoc_stringl_ex(&zrv, pnstr, pnlen+1, path, path_len, 1);
615 efree(pnstr);
616
617 if (intern->file_name) {
618 pnstr = spl_gen_private_prop_name(spl_ce_SplFileInfo, "fileName", sizeof("fileName")-1, &pnlen TSRMLS_CC);
619 spl_filesystem_object_get_path(intern, &path_len TSRMLS_CC);
620
621 if (path_len && path_len < intern->file_name_len) {
622 add_assoc_stringl_ex(&zrv, pnstr, pnlen+1, intern->file_name + path_len + 1, intern->file_name_len - (path_len + 1), 1);
623 } else {
624 add_assoc_stringl_ex(&zrv, pnstr, pnlen+1, intern->file_name, intern->file_name_len, 1);
625 }
626 efree(pnstr);
627 }
628 if (intern->type == SPL_FS_DIR) {
629 #ifdef HAVE_GLOB
630 pnstr = spl_gen_private_prop_name(spl_ce_DirectoryIterator, "glob", sizeof("glob")-1, &pnlen TSRMLS_CC);
631 if (php_stream_is(intern->u.dir.dirp ,&php_glob_stream_ops)) {
632 add_assoc_stringl_ex(&zrv, pnstr, pnlen+1, intern->_path, intern->_path_len, 1);
633 } else {
634 add_assoc_bool_ex(&zrv, pnstr, pnlen+1, 0);
635 }
636 efree(pnstr);
637 #endif
638 pnstr = spl_gen_private_prop_name(spl_ce_RecursiveDirectoryIterator, "subPathName", sizeof("subPathName")-1, &pnlen TSRMLS_CC);
639 if (intern->u.dir.sub_path) {
640 add_assoc_stringl_ex(&zrv, pnstr, pnlen+1, intern->u.dir.sub_path, intern->u.dir.sub_path_len, 1);
641 } else {
642 add_assoc_stringl_ex(&zrv, pnstr, pnlen+1, "", 0, 1);
643 }
644 efree(pnstr);
645 }
646 if (intern->type == SPL_FS_FILE) {
647 pnstr = spl_gen_private_prop_name(spl_ce_SplFileObject, "openMode", sizeof("openMode")-1, &pnlen TSRMLS_CC);
648 add_assoc_stringl_ex(&zrv, pnstr, pnlen+1, intern->u.file.open_mode, intern->u.file.open_mode_len, 1);
649 efree(pnstr);
650 stmp[1] = '\0';
651 stmp[0] = intern->u.file.delimiter;
652 pnstr = spl_gen_private_prop_name(spl_ce_SplFileObject, "delimiter", sizeof("delimiter")-1, &pnlen TSRMLS_CC);
653 add_assoc_stringl_ex(&zrv, pnstr, pnlen+1, stmp, 1, 1);
654 efree(pnstr);
655 stmp[0] = intern->u.file.enclosure;
656 pnstr = spl_gen_private_prop_name(spl_ce_SplFileObject, "enclosure", sizeof("enclosure")-1, &pnlen TSRMLS_CC);
657 add_assoc_stringl_ex(&zrv, pnstr, pnlen+1, stmp, 1, 1);
658 efree(pnstr);
659 }
660
661 return rv;
662 }
663 /* }}} */
664
spl_filesystem_object_get_method_check(zval ** object_ptr,char * method,int method_len,const struct _zend_literal * key TSRMLS_DC)665 zend_function *spl_filesystem_object_get_method_check(zval **object_ptr, char *method, int method_len, const struct _zend_literal *key TSRMLS_DC) /* {{{ */
666 {
667 spl_filesystem_object *fsobj = zend_object_store_get_object(*object_ptr TSRMLS_CC);
668
669 if (fsobj->u.dir.dirp == NULL && fsobj->orig_path == NULL) {
670 method = "_bad_state_ex";
671 method_len = sizeof("_bad_state_ex") - 1;
672 key = NULL;
673 }
674
675 return zend_get_std_object_handlers()->get_method(object_ptr, method, method_len, key TSRMLS_CC);
676 }
677 /* }}} */
678
679 #define DIT_CTOR_FLAGS 0x00000001
680 #define DIT_CTOR_GLOB 0x00000002
681
spl_filesystem_object_construct(INTERNAL_FUNCTION_PARAMETERS,long ctor_flags)682 void spl_filesystem_object_construct(INTERNAL_FUNCTION_PARAMETERS, long ctor_flags) /* {{{ */
683 {
684 spl_filesystem_object *intern;
685 char *path;
686 int parsed, len;
687 long flags;
688 zend_error_handling error_handling;
689
690 zend_replace_error_handling(EH_THROW, spl_ce_UnexpectedValueException, &error_handling TSRMLS_CC);
691
692 if (SPL_HAS_FLAG(ctor_flags, DIT_CTOR_FLAGS)) {
693 flags = SPL_FILE_DIR_KEY_AS_PATHNAME|SPL_FILE_DIR_CURRENT_AS_FILEINFO;
694 parsed = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &path, &len, &flags);
695 } else {
696 flags = SPL_FILE_DIR_KEY_AS_PATHNAME|SPL_FILE_DIR_CURRENT_AS_SELF;
697 parsed = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &path, &len);
698 }
699 if (SPL_HAS_FLAG(ctor_flags, SPL_FILE_DIR_SKIPDOTS)) {
700 flags |= SPL_FILE_DIR_SKIPDOTS;
701 }
702 if (SPL_HAS_FLAG(ctor_flags, SPL_FILE_DIR_UNIXPATHS)) {
703 flags |= SPL_FILE_DIR_UNIXPATHS;
704 }
705 if (parsed == FAILURE) {
706 zend_restore_error_handling(&error_handling TSRMLS_CC);
707 return;
708 }
709 if (!len) {
710 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Directory name must not be empty.");
711 zend_restore_error_handling(&error_handling TSRMLS_CC);
712 return;
713 }
714
715 intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
716 if (intern->_path) {
717 /* object is alreay initialized */
718 zend_restore_error_handling(&error_handling TSRMLS_CC);
719 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Directory object is already initialized");
720 return;
721 }
722 intern->flags = flags;
723 #ifdef HAVE_GLOB
724 if (SPL_HAS_FLAG(ctor_flags, DIT_CTOR_GLOB) && strstr(path, "glob://") != path) {
725 spprintf(&path, 0, "glob://%s", path);
726 spl_filesystem_dir_open(intern, path TSRMLS_CC);
727 efree(path);
728 } else
729 #endif
730 {
731 spl_filesystem_dir_open(intern, path TSRMLS_CC);
732
733 }
734
735 intern->u.dir.is_recursive = instanceof_function(intern->std.ce, spl_ce_RecursiveDirectoryIterator TSRMLS_CC) ? 1 : 0;
736
737 zend_restore_error_handling(&error_handling TSRMLS_CC);
738 }
739 /* }}} */
740
741 /* {{{ proto void DirectoryIterator::__construct(string path)
742 Cronstructs a new dir iterator from a path. */
SPL_METHOD(DirectoryIterator,__construct)743 SPL_METHOD(DirectoryIterator, __construct)
744 {
745 spl_filesystem_object_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
746 }
747 /* }}} */
748
749 /* {{{ proto void DirectoryIterator::rewind()
750 Rewind dir back to the start */
SPL_METHOD(DirectoryIterator,rewind)751 SPL_METHOD(DirectoryIterator, rewind)
752 {
753 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
754
755 if (zend_parse_parameters_none() == FAILURE) {
756 return;
757 }
758
759 intern->u.dir.index = 0;
760 if (intern->u.dir.dirp) {
761 php_stream_rewinddir(intern->u.dir.dirp);
762 }
763 spl_filesystem_dir_read(intern TSRMLS_CC);
764 }
765 /* }}} */
766
767 /* {{{ proto string DirectoryIterator::key()
768 Return current dir entry */
SPL_METHOD(DirectoryIterator,key)769 SPL_METHOD(DirectoryIterator, key)
770 {
771 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
772
773 if (zend_parse_parameters_none() == FAILURE) {
774 return;
775 }
776
777 if (intern->u.dir.dirp) {
778 RETURN_LONG(intern->u.dir.index);
779 } else {
780 RETURN_FALSE;
781 }
782 }
783 /* }}} */
784
785 /* {{{ proto DirectoryIterator DirectoryIterator::current()
786 Return this (needed for Iterator interface) */
SPL_METHOD(DirectoryIterator,current)787 SPL_METHOD(DirectoryIterator, current)
788 {
789 if (zend_parse_parameters_none() == FAILURE) {
790 return;
791 }
792 RETURN_ZVAL(getThis(), 1, 0);
793 }
794 /* }}} */
795
796 /* {{{ proto void DirectoryIterator::next()
797 Move to next entry */
SPL_METHOD(DirectoryIterator,next)798 SPL_METHOD(DirectoryIterator, next)
799 {
800 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
801 int skip_dots = SPL_HAS_FLAG(intern->flags, SPL_FILE_DIR_SKIPDOTS);
802
803 if (zend_parse_parameters_none() == FAILURE) {
804 return;
805 }
806
807 intern->u.dir.index++;
808 do {
809 spl_filesystem_dir_read(intern TSRMLS_CC);
810 } while (skip_dots && spl_filesystem_is_dot(intern->u.dir.entry.d_name));
811 if (intern->file_name) {
812 efree(intern->file_name);
813 intern->file_name = NULL;
814 }
815 }
816 /* }}} */
817
818 /* {{{ proto void DirectoryIterator::seek(int position)
819 Seek to the given position */
SPL_METHOD(DirectoryIterator,seek)820 SPL_METHOD(DirectoryIterator, seek)
821 {
822 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
823 zval *retval = NULL;
824 long pos;
825
826 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &pos) == FAILURE) {
827 return;
828 }
829
830 if (intern->u.dir.index > pos) {
831 /* we first rewind */
832 zend_call_method_with_0_params(&this_ptr, Z_OBJCE_P(getThis()), &intern->u.dir.func_rewind, "rewind", &retval);
833 if (retval) {
834 zval_ptr_dtor(&retval);
835 retval = NULL;
836 }
837 }
838
839 while (intern->u.dir.index < pos) {
840 int valid = 0;
841 zend_call_method_with_0_params(&this_ptr, Z_OBJCE_P(getThis()), &intern->u.dir.func_valid, "valid", &retval);
842 if (retval) {
843 valid = zend_is_true(retval);
844 zval_ptr_dtor(&retval);
845 retval = NULL;
846 }
847 if (!valid) {
848 zend_throw_exception_ex(spl_ce_OutOfBoundsException, 0 TSRMLS_CC, "Seek position %ld is out of range", pos);
849 return;
850 }
851 zend_call_method_with_0_params(&this_ptr, Z_OBJCE_P(getThis()), &intern->u.dir.func_next, "next", &retval);
852 if (retval) {
853 zval_ptr_dtor(&retval);
854 }
855 }
856 } /* }}} */
857
858 /* {{{ proto string DirectoryIterator::valid()
859 Check whether dir contains more entries */
SPL_METHOD(DirectoryIterator,valid)860 SPL_METHOD(DirectoryIterator, valid)
861 {
862 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
863
864 if (zend_parse_parameters_none() == FAILURE) {
865 return;
866 }
867
868 RETURN_BOOL(intern->u.dir.entry.d_name[0] != '\0');
869 }
870 /* }}} */
871
872 /* {{{ proto string SplFileInfo::getPath()
873 Return the path */
SPL_METHOD(SplFileInfo,getPath)874 SPL_METHOD(SplFileInfo, getPath)
875 {
876 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
877 char *path;
878 int path_len;
879
880 if (zend_parse_parameters_none() == FAILURE) {
881 return;
882 }
883
884 path = spl_filesystem_object_get_path(intern, &path_len TSRMLS_CC);
885 RETURN_STRINGL(path, path_len, 1);
886 }
887 /* }}} */
888
889 /* {{{ proto string SplFileInfo::getFilename()
890 Return filename only */
SPL_METHOD(SplFileInfo,getFilename)891 SPL_METHOD(SplFileInfo, getFilename)
892 {
893 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
894 int path_len;
895
896 if (zend_parse_parameters_none() == FAILURE) {
897 return;
898 }
899
900 spl_filesystem_object_get_path(intern, &path_len TSRMLS_CC);
901
902 if (path_len && path_len < intern->file_name_len) {
903 RETURN_STRINGL(intern->file_name + path_len + 1, intern->file_name_len - (path_len + 1), 1);
904 } else {
905 RETURN_STRINGL(intern->file_name, intern->file_name_len, 1);
906 }
907 }
908 /* }}} */
909
910 /* {{{ proto string DirectoryIterator::getFilename()
911 Return filename of current dir entry */
SPL_METHOD(DirectoryIterator,getFilename)912 SPL_METHOD(DirectoryIterator, getFilename)
913 {
914 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
915
916 if (zend_parse_parameters_none() == FAILURE) {
917 return;
918 }
919
920 RETURN_STRING(intern->u.dir.entry.d_name, 1);
921 }
922 /* }}} */
923
924 /* {{{ proto string SplFileInfo::getExtension()
925 Returns file extension component of path */
SPL_METHOD(SplFileInfo,getExtension)926 SPL_METHOD(SplFileInfo, getExtension)
927 {
928 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
929 char *fname = NULL;
930 const char *p;
931 size_t flen;
932 int path_len, idx;
933
934 if (zend_parse_parameters_none() == FAILURE) {
935 return;
936 }
937
938 spl_filesystem_object_get_path(intern, &path_len TSRMLS_CC);
939
940 if (path_len && path_len < intern->file_name_len) {
941 fname = intern->file_name + path_len + 1;
942 flen = intern->file_name_len - (path_len + 1);
943 } else {
944 fname = intern->file_name;
945 flen = intern->file_name_len;
946 }
947
948 php_basename(fname, flen, NULL, 0, &fname, &flen TSRMLS_CC);
949
950 p = zend_memrchr(fname, '.', flen);
951 if (p) {
952 idx = p - fname;
953 RETVAL_STRINGL(fname + idx + 1, flen - idx - 1, 1);
954 efree(fname);
955 return;
956 } else {
957 if (fname) {
958 efree(fname);
959 }
960 RETURN_EMPTY_STRING();
961 }
962 }
963 /* }}}*/
964
965 /* {{{ proto string DirectoryIterator::getExtension()
966 Returns the file extension component of path */
SPL_METHOD(DirectoryIterator,getExtension)967 SPL_METHOD(DirectoryIterator, getExtension)
968 {
969 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
970 char *fname = NULL;
971 const char *p;
972 size_t flen;
973 int idx;
974
975 if (zend_parse_parameters_none() == FAILURE) {
976 return;
977 }
978
979 php_basename(intern->u.dir.entry.d_name, strlen(intern->u.dir.entry.d_name), NULL, 0, &fname, &flen TSRMLS_CC);
980
981 p = zend_memrchr(fname, '.', flen);
982 if (p) {
983 idx = p - fname;
984 RETVAL_STRINGL(fname + idx + 1, flen - idx - 1, 1);
985 efree(fname);
986 return;
987 } else {
988 if (fname) {
989 efree(fname);
990 }
991 RETURN_EMPTY_STRING();
992 }
993 }
994 /* }}} */
995
996 /* {{{ proto string SplFileInfo::getBasename([string $suffix]) U
997 Returns filename component of path */
SPL_METHOD(SplFileInfo,getBasename)998 SPL_METHOD(SplFileInfo, getBasename)
999 {
1000 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1001 char *fname, *suffix = 0;
1002 size_t flen;
1003 int slen = 0, path_len;
1004
1005 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &suffix, &slen) == FAILURE) {
1006 return;
1007 }
1008
1009 spl_filesystem_object_get_path(intern, &path_len TSRMLS_CC);
1010
1011 if (path_len && path_len < intern->file_name_len) {
1012 fname = intern->file_name + path_len + 1;
1013 flen = intern->file_name_len - (path_len + 1);
1014 } else {
1015 fname = intern->file_name;
1016 flen = intern->file_name_len;
1017 }
1018
1019 php_basename(fname, flen, suffix, slen, &fname, &flen TSRMLS_CC);
1020
1021 RETURN_STRINGL(fname, flen, 0);
1022 }
1023 /* }}}*/
1024
1025 /* {{{ proto string DirectoryIterator::getBasename([string $suffix]) U
1026 Returns filename component of current dir entry */
SPL_METHOD(DirectoryIterator,getBasename)1027 SPL_METHOD(DirectoryIterator, getBasename)
1028 {
1029 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1030 char *suffix = 0, *fname;
1031 int slen = 0;
1032 size_t flen;
1033
1034 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &suffix, &slen) == FAILURE) {
1035 return;
1036 }
1037
1038 php_basename(intern->u.dir.entry.d_name, strlen(intern->u.dir.entry.d_name), suffix, slen, &fname, &flen TSRMLS_CC);
1039
1040 RETURN_STRINGL(fname, flen, 0);
1041 }
1042 /* }}} */
1043
1044 /* {{{ proto string SplFileInfo::getPathname()
1045 Return path and filename */
SPL_METHOD(SplFileInfo,getPathname)1046 SPL_METHOD(SplFileInfo, getPathname)
1047 {
1048 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1049 char *path;
1050 int path_len;
1051
1052 if (zend_parse_parameters_none() == FAILURE) {
1053 return;
1054 }
1055 path = spl_filesystem_object_get_pathname(intern, &path_len TSRMLS_CC);
1056 if (path != NULL) {
1057 RETURN_STRINGL(path, path_len, 1);
1058 } else {
1059 RETURN_FALSE;
1060 }
1061 }
1062 /* }}} */
1063
1064 /* {{{ proto string FilesystemIterator::key()
1065 Return getPathname() or getFilename() depending on flags */
SPL_METHOD(FilesystemIterator,key)1066 SPL_METHOD(FilesystemIterator, key)
1067 {
1068 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1069
1070 if (zend_parse_parameters_none() == FAILURE) {
1071 return;
1072 }
1073
1074 if (SPL_FILE_DIR_KEY(intern, SPL_FILE_DIR_KEY_AS_FILENAME)) {
1075 RETURN_STRING(intern->u.dir.entry.d_name, 1);
1076 } else {
1077 spl_filesystem_object_get_file_name(intern TSRMLS_CC);
1078 RETURN_STRINGL(intern->file_name, intern->file_name_len, 1);
1079 }
1080 }
1081 /* }}} */
1082
1083 /* {{{ proto string FilesystemIterator::current()
1084 Return getFilename(), getFileInfo() or $this depending on flags */
SPL_METHOD(FilesystemIterator,current)1085 SPL_METHOD(FilesystemIterator, current)
1086 {
1087 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1088
1089 if (zend_parse_parameters_none() == FAILURE) {
1090 return;
1091 }
1092
1093 if (SPL_FILE_DIR_CURRENT(intern, SPL_FILE_DIR_CURRENT_AS_PATHNAME)) {
1094 spl_filesystem_object_get_file_name(intern TSRMLS_CC);
1095 RETURN_STRINGL(intern->file_name, intern->file_name_len, 1);
1096 } else if (SPL_FILE_DIR_CURRENT(intern, SPL_FILE_DIR_CURRENT_AS_FILEINFO)) {
1097 spl_filesystem_object_get_file_name(intern TSRMLS_CC);
1098 spl_filesystem_object_create_type(0, intern, SPL_FS_INFO, NULL, return_value TSRMLS_CC);
1099 } else {
1100 RETURN_ZVAL(getThis(), 1, 0);
1101 /*RETURN_STRING(intern->u.dir.entry.d_name, 1);*/
1102 }
1103 }
1104 /* }}} */
1105
1106 /* {{{ proto bool DirectoryIterator::isDot()
1107 Returns true if current entry is '.' or '..' */
SPL_METHOD(DirectoryIterator,isDot)1108 SPL_METHOD(DirectoryIterator, isDot)
1109 {
1110 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1111
1112 if (zend_parse_parameters_none() == FAILURE) {
1113 return;
1114 }
1115
1116 RETURN_BOOL(spl_filesystem_is_dot(intern->u.dir.entry.d_name));
1117 }
1118 /* }}} */
1119
1120 /* {{{ proto void SplFileInfo::__construct(string file_name)
1121 Cronstructs a new SplFileInfo from a path. */
1122 /* zend_replace_error_handling() is used to throw exceptions in case
1123 the constructor fails. Here we use this to ensure the object
1124 has a valid directory resource.
1125
1126 When the constructor gets called the object is already created
1127 by the engine, so we must only call 'additional' initializations.
1128 */
SPL_METHOD(SplFileInfo,__construct)1129 SPL_METHOD(SplFileInfo, __construct)
1130 {
1131 spl_filesystem_object *intern;
1132 char *path;
1133 int len;
1134 zend_error_handling error_handling;
1135
1136 zend_replace_error_handling(EH_THROW, spl_ce_RuntimeException, &error_handling TSRMLS_CC);
1137
1138 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &path, &len) == FAILURE) {
1139 zend_restore_error_handling(&error_handling TSRMLS_CC);
1140 return;
1141 }
1142
1143 intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1144
1145 spl_filesystem_info_set_filename(intern, path, len, 1 TSRMLS_CC);
1146
1147 zend_restore_error_handling(&error_handling TSRMLS_CC);
1148
1149 /* intern->type = SPL_FS_INFO; already set */
1150 }
1151 /* }}} */
1152
1153 /* {{{ FileInfoFunction */
1154 #define FileInfoFunction(func_name, func_num) \
1155 SPL_METHOD(SplFileInfo, func_name) \
1156 { \
1157 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); \
1158 zend_error_handling error_handling; \
1159 if (zend_parse_parameters_none() == FAILURE) { \
1160 return; \
1161 } \
1162 \
1163 zend_replace_error_handling(EH_THROW, spl_ce_RuntimeException, &error_handling TSRMLS_CC);\
1164 spl_filesystem_object_get_file_name(intern TSRMLS_CC); \
1165 php_stat(intern->file_name, intern->file_name_len, func_num, return_value TSRMLS_CC); \
1166 zend_restore_error_handling(&error_handling TSRMLS_CC); \
1167 }
1168 /* }}} */
1169
1170 /* {{{ proto int SplFileInfo::getPerms()
1171 Get file permissions */
FileInfoFunction(getPerms,FS_PERMS)1172 FileInfoFunction(getPerms, FS_PERMS)
1173 /* }}} */
1174
1175 /* {{{ proto int SplFileInfo::getInode()
1176 Get file inode */
1177 FileInfoFunction(getInode, FS_INODE)
1178 /* }}} */
1179
1180 /* {{{ proto int SplFileInfo::getSize()
1181 Get file size */
1182 FileInfoFunction(getSize, FS_SIZE)
1183 /* }}} */
1184
1185 /* {{{ proto int SplFileInfo::getOwner()
1186 Get file owner */
1187 FileInfoFunction(getOwner, FS_OWNER)
1188 /* }}} */
1189
1190 /* {{{ proto int SplFileInfo::getGroup()
1191 Get file group */
1192 FileInfoFunction(getGroup, FS_GROUP)
1193 /* }}} */
1194
1195 /* {{{ proto int SplFileInfo::getATime()
1196 Get last access time of file */
1197 FileInfoFunction(getATime, FS_ATIME)
1198 /* }}} */
1199
1200 /* {{{ proto int SplFileInfo::getMTime()
1201 Get last modification time of file */
1202 FileInfoFunction(getMTime, FS_MTIME)
1203 /* }}} */
1204
1205 /* {{{ proto int SplFileInfo::getCTime()
1206 Get inode modification time of file */
1207 FileInfoFunction(getCTime, FS_CTIME)
1208 /* }}} */
1209
1210 /* {{{ proto string SplFileInfo::getType()
1211 Get file type */
1212 FileInfoFunction(getType, FS_TYPE)
1213 /* }}} */
1214
1215 /* {{{ proto bool SplFileInfo::isWritable()
1216 Returns true if file can be written */
1217 FileInfoFunction(isWritable, FS_IS_W)
1218 /* }}} */
1219
1220 /* {{{ proto bool SplFileInfo::isReadable()
1221 Returns true if file can be read */
1222 FileInfoFunction(isReadable, FS_IS_R)
1223 /* }}} */
1224
1225 /* {{{ proto bool SplFileInfo::isExecutable()
1226 Returns true if file is executable */
1227 FileInfoFunction(isExecutable, FS_IS_X)
1228 /* }}} */
1229
1230 /* {{{ proto bool SplFileInfo::isFile()
1231 Returns true if file is a regular file */
1232 FileInfoFunction(isFile, FS_IS_FILE)
1233 /* }}} */
1234
1235 /* {{{ proto bool SplFileInfo::isDir()
1236 Returns true if file is directory */
1237 FileInfoFunction(isDir, FS_IS_DIR)
1238 /* }}} */
1239
1240 /* {{{ proto bool SplFileInfo::isLink()
1241 Returns true if file is symbolic link */
1242 FileInfoFunction(isLink, FS_IS_LINK)
1243 /* }}} */
1244
1245 /* {{{ proto string SplFileInfo::getLinkTarget() U
1246 Return the target of a symbolic link */
1247 SPL_METHOD(SplFileInfo, getLinkTarget)
1248 {
1249 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1250 int ret;
1251 char buff[MAXPATHLEN];
1252 zend_error_handling error_handling;
1253
1254 if (zend_parse_parameters_none() == FAILURE) {
1255 return;
1256 }
1257
1258 zend_replace_error_handling(EH_THROW, spl_ce_RuntimeException, &error_handling TSRMLS_CC);
1259
1260 #if defined(PHP_WIN32) || HAVE_SYMLINK
1261 if (intern->file_name == NULL) {
1262 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty filename");
1263 RETURN_FALSE;
1264 } else if (!IS_ABSOLUTE_PATH(intern->file_name, intern->file_name_len)) {
1265 char expanded_path[MAXPATHLEN];
1266 if (!expand_filepath_with_mode(intern->file_name, expanded_path, NULL, 0, CWD_EXPAND TSRMLS_CC)) {
1267 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such file or directory");
1268 RETURN_FALSE;
1269 }
1270 ret = php_sys_readlink(expanded_path, buff, MAXPATHLEN - 1);
1271 } else {
1272 ret = php_sys_readlink(intern->file_name, buff, MAXPATHLEN-1);
1273 }
1274 #else
1275 ret = -1; /* always fail if not implemented */
1276 #endif
1277
1278 if (ret == -1) {
1279 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Unable to read link %s, error: %s", intern->file_name, strerror(errno));
1280 RETVAL_FALSE;
1281 } else {
1282 /* Append NULL to the end of the string */
1283 buff[ret] = '\0';
1284
1285 RETVAL_STRINGL(buff, ret, 1);
1286 }
1287
1288 zend_restore_error_handling(&error_handling TSRMLS_CC);
1289 }
1290 /* }}} */
1291
1292 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
1293 /* {{{ proto string SplFileInfo::getRealPath()
1294 Return the resolved path */
SPL_METHOD(SplFileInfo,getRealPath)1295 SPL_METHOD(SplFileInfo, getRealPath)
1296 {
1297 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1298 char buff[MAXPATHLEN];
1299 char *filename;
1300 zend_error_handling error_handling;
1301
1302 if (zend_parse_parameters_none() == FAILURE) {
1303 return;
1304 }
1305
1306 zend_replace_error_handling(EH_THROW, spl_ce_RuntimeException, &error_handling TSRMLS_CC);
1307
1308 if (intern->type == SPL_FS_DIR && !intern->file_name && intern->u.dir.entry.d_name[0]) {
1309 spl_filesystem_object_get_file_name(intern TSRMLS_CC);
1310 }
1311
1312 if (intern->orig_path) {
1313 filename = intern->orig_path;
1314 } else {
1315 filename = intern->file_name;
1316 }
1317
1318
1319 if (filename && VCWD_REALPATH(filename, buff)) {
1320 #ifdef ZTS
1321 if (VCWD_ACCESS(buff, F_OK)) {
1322 RETVAL_FALSE;
1323 } else
1324 #endif
1325 RETVAL_STRING(buff, 1);
1326 } else {
1327 RETVAL_FALSE;
1328 }
1329
1330 zend_restore_error_handling(&error_handling TSRMLS_CC);
1331 }
1332 /* }}} */
1333 #endif
1334
1335 /* {{{ proto SplFileObject SplFileInfo::openFile([string mode = 'r' [, bool use_include_path [, resource context]]])
1336 Open the current file */
SPL_METHOD(SplFileInfo,openFile)1337 SPL_METHOD(SplFileInfo, openFile)
1338 {
1339 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1340
1341 spl_filesystem_object_create_type(ht, intern, SPL_FS_FILE, NULL, return_value TSRMLS_CC);
1342 }
1343 /* }}} */
1344
1345 /* {{{ proto void SplFileInfo::setFileClass([string class_name])
1346 Class to use in openFile() */
SPL_METHOD(SplFileInfo,setFileClass)1347 SPL_METHOD(SplFileInfo, setFileClass)
1348 {
1349 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1350 zend_class_entry *ce = spl_ce_SplFileObject;
1351 zend_error_handling error_handling;
1352
1353 zend_replace_error_handling(EH_THROW, spl_ce_UnexpectedValueException, &error_handling TSRMLS_CC);
1354
1355 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == SUCCESS) {
1356 intern->file_class = ce;
1357 }
1358
1359 zend_restore_error_handling(&error_handling TSRMLS_CC);
1360 }
1361 /* }}} */
1362
1363 /* {{{ proto void SplFileInfo::setInfoClass([string class_name])
1364 Class to use in getFileInfo(), getPathInfo() */
SPL_METHOD(SplFileInfo,setInfoClass)1365 SPL_METHOD(SplFileInfo, setInfoClass)
1366 {
1367 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1368 zend_class_entry *ce = spl_ce_SplFileInfo;
1369 zend_error_handling error_handling;
1370
1371 zend_replace_error_handling(EH_THROW, spl_ce_UnexpectedValueException, &error_handling TSRMLS_CC);
1372
1373 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == SUCCESS) {
1374 intern->info_class = ce;
1375 }
1376
1377 zend_restore_error_handling(&error_handling TSRMLS_CC);
1378 }
1379 /* }}} */
1380
1381 /* {{{ proto SplFileInfo SplFileInfo::getFileInfo([string $class_name])
1382 Get/copy file info */
SPL_METHOD(SplFileInfo,getFileInfo)1383 SPL_METHOD(SplFileInfo, getFileInfo)
1384 {
1385 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1386 zend_class_entry *ce = intern->info_class;
1387 zend_error_handling error_handling;
1388
1389 zend_replace_error_handling(EH_THROW, spl_ce_UnexpectedValueException, &error_handling TSRMLS_CC);
1390
1391 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == SUCCESS) {
1392 spl_filesystem_object_create_type(ht, intern, SPL_FS_INFO, ce, return_value TSRMLS_CC);
1393 }
1394
1395 zend_restore_error_handling(&error_handling TSRMLS_CC);
1396 }
1397 /* }}} */
1398
1399 /* {{{ proto SplFileInfo SplFileInfo::getPathInfo([string $class_name])
1400 Get/copy file info */
SPL_METHOD(SplFileInfo,getPathInfo)1401 SPL_METHOD(SplFileInfo, getPathInfo)
1402 {
1403 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1404 zend_class_entry *ce = intern->info_class;
1405 zend_error_handling error_handling;
1406
1407 zend_replace_error_handling(EH_THROW, spl_ce_UnexpectedValueException, &error_handling TSRMLS_CC);
1408
1409 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == SUCCESS) {
1410 int path_len;
1411 char *path = spl_filesystem_object_get_pathname(intern, &path_len TSRMLS_CC);
1412 if (path) {
1413 char *dpath = estrndup(path, path_len);
1414 path_len = php_dirname(dpath, path_len);
1415 spl_filesystem_object_create_info(intern, dpath, path_len, 1, ce, return_value TSRMLS_CC);
1416 efree(dpath);
1417 }
1418 }
1419
1420 zend_restore_error_handling(&error_handling TSRMLS_CC);
1421 }
1422 /* }}} */
1423
1424 /* {{{ */
SPL_METHOD(SplFileInfo,_bad_state_ex)1425 SPL_METHOD(SplFileInfo, _bad_state_ex)
1426 {
1427 zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC,
1428 "The parent constructor was not called: the object is in an "
1429 "invalid state ");
1430 }
1431 /* }}} */
1432
1433 /* {{{ proto void FilesystemIterator::__construct(string path [, int flags])
1434 Cronstructs a new dir iterator from a path. */
SPL_METHOD(FilesystemIterator,__construct)1435 SPL_METHOD(FilesystemIterator, __construct)
1436 {
1437 spl_filesystem_object_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, DIT_CTOR_FLAGS | SPL_FILE_DIR_SKIPDOTS);
1438 }
1439 /* }}} */
1440
1441 /* {{{ proto void FilesystemIterator::rewind()
1442 Rewind dir back to the start */
SPL_METHOD(FilesystemIterator,rewind)1443 SPL_METHOD(FilesystemIterator, rewind)
1444 {
1445 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1446 int skip_dots = SPL_HAS_FLAG(intern->flags, SPL_FILE_DIR_SKIPDOTS);
1447
1448 if (zend_parse_parameters_none() == FAILURE) {
1449 return;
1450 }
1451
1452 intern->u.dir.index = 0;
1453 if (intern->u.dir.dirp) {
1454 php_stream_rewinddir(intern->u.dir.dirp);
1455 }
1456 do {
1457 spl_filesystem_dir_read(intern TSRMLS_CC);
1458 } while (skip_dots && spl_filesystem_is_dot(intern->u.dir.entry.d_name));
1459 }
1460 /* }}} */
1461
1462 /* {{{ proto int FilesystemIterator::getFlags()
1463 Get handling flags */
SPL_METHOD(FilesystemIterator,getFlags)1464 SPL_METHOD(FilesystemIterator, getFlags)
1465 {
1466 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1467
1468 if (zend_parse_parameters_none() == FAILURE) {
1469 return;
1470 }
1471
1472 RETURN_LONG(intern->flags & (SPL_FILE_DIR_KEY_MODE_MASK | SPL_FILE_DIR_CURRENT_MODE_MASK | SPL_FILE_DIR_OTHERS_MASK));
1473 } /* }}} */
1474
1475 /* {{{ proto void FilesystemIterator::setFlags(long $flags)
1476 Set handling flags */
SPL_METHOD(FilesystemIterator,setFlags)1477 SPL_METHOD(FilesystemIterator, setFlags)
1478 {
1479 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1480 long flags;
1481
1482 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &flags) == FAILURE) {
1483 return;
1484 }
1485
1486 intern->flags &= ~(SPL_FILE_DIR_KEY_MODE_MASK|SPL_FILE_DIR_CURRENT_MODE_MASK|SPL_FILE_DIR_OTHERS_MASK);
1487 intern->flags |= ((SPL_FILE_DIR_KEY_MODE_MASK|SPL_FILE_DIR_CURRENT_MODE_MASK|SPL_FILE_DIR_OTHERS_MASK) & flags);
1488 } /* }}} */
1489
1490 /* {{{ proto bool RecursiveDirectoryIterator::hasChildren([bool $allow_links = false])
1491 Returns whether current entry is a directory and not '.' or '..' */
SPL_METHOD(RecursiveDirectoryIterator,hasChildren)1492 SPL_METHOD(RecursiveDirectoryIterator, hasChildren)
1493 {
1494 zend_bool allow_links = 0;
1495 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1496
1497 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &allow_links) == FAILURE) {
1498 return;
1499 }
1500 if (spl_filesystem_is_invalid_or_dot(intern->u.dir.entry.d_name)) {
1501 RETURN_FALSE;
1502 } else {
1503 spl_filesystem_object_get_file_name(intern TSRMLS_CC);
1504 if (!allow_links && !(intern->flags & SPL_FILE_DIR_FOLLOW_SYMLINKS)) {
1505 php_stat(intern->file_name, intern->file_name_len, FS_IS_LINK, return_value TSRMLS_CC);
1506 if (zend_is_true(return_value)) {
1507 RETURN_FALSE;
1508 }
1509 }
1510 php_stat(intern->file_name, intern->file_name_len, FS_IS_DIR, return_value TSRMLS_CC);
1511 }
1512 }
1513 /* }}} */
1514
1515 /* {{{ proto RecursiveDirectoryIterator DirectoryIterator::getChildren()
1516 Returns an iterator for the current entry if it is a directory */
SPL_METHOD(RecursiveDirectoryIterator,getChildren)1517 SPL_METHOD(RecursiveDirectoryIterator, getChildren)
1518 {
1519 zval *zpath, *zflags;
1520 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1521 spl_filesystem_object *subdir;
1522 char slash = SPL_HAS_FLAG(intern->flags, SPL_FILE_DIR_UNIXPATHS) ? '/' : DEFAULT_SLASH;
1523
1524 if (zend_parse_parameters_none() == FAILURE) {
1525 return;
1526 }
1527
1528 spl_filesystem_object_get_file_name(intern TSRMLS_CC);
1529
1530 MAKE_STD_ZVAL(zflags);
1531 MAKE_STD_ZVAL(zpath);
1532 ZVAL_LONG(zflags, intern->flags);
1533 ZVAL_STRINGL(zpath, intern->file_name, intern->file_name_len, 1);
1534 spl_instantiate_arg_ex2(Z_OBJCE_P(getThis()), &return_value, 0, zpath, zflags TSRMLS_CC);
1535 zval_ptr_dtor(&zpath);
1536 zval_ptr_dtor(&zflags);
1537
1538 subdir = (spl_filesystem_object*)zend_object_store_get_object(return_value TSRMLS_CC);
1539 if (subdir) {
1540 if (intern->u.dir.sub_path && intern->u.dir.sub_path[0]) {
1541 subdir->u.dir.sub_path_len = spprintf(&subdir->u.dir.sub_path, 0, "%s%c%s", intern->u.dir.sub_path, slash, intern->u.dir.entry.d_name);
1542 } else {
1543 subdir->u.dir.sub_path_len = strlen(intern->u.dir.entry.d_name);
1544 subdir->u.dir.sub_path = estrndup(intern->u.dir.entry.d_name, subdir->u.dir.sub_path_len);
1545 }
1546 subdir->info_class = intern->info_class;
1547 subdir->file_class = intern->file_class;
1548 subdir->oth = intern->oth;
1549 }
1550 }
1551 /* }}} */
1552
1553 /* {{{ proto void RecursiveDirectoryIterator::getSubPath()
1554 Get sub path */
SPL_METHOD(RecursiveDirectoryIterator,getSubPath)1555 SPL_METHOD(RecursiveDirectoryIterator, getSubPath)
1556 {
1557 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1558
1559 if (zend_parse_parameters_none() == FAILURE) {
1560 return;
1561 }
1562
1563 if (intern->u.dir.sub_path) {
1564 RETURN_STRINGL(intern->u.dir.sub_path, intern->u.dir.sub_path_len, 1);
1565 } else {
1566 RETURN_STRINGL("", 0, 1);
1567 }
1568 }
1569 /* }}} */
1570
1571 /* {{{ proto void RecursiveDirectoryIterator::getSubPathname()
1572 Get sub path and file name */
SPL_METHOD(RecursiveDirectoryIterator,getSubPathname)1573 SPL_METHOD(RecursiveDirectoryIterator, getSubPathname)
1574 {
1575 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1576 char *sub_name;
1577 int len;
1578 char slash = SPL_HAS_FLAG(intern->flags, SPL_FILE_DIR_UNIXPATHS) ? '/' : DEFAULT_SLASH;
1579
1580 if (zend_parse_parameters_none() == FAILURE) {
1581 return;
1582 }
1583
1584 if (intern->u.dir.sub_path) {
1585 len = spprintf(&sub_name, 0, "%s%c%s", intern->u.dir.sub_path, slash, intern->u.dir.entry.d_name);
1586 RETURN_STRINGL(sub_name, len, 0);
1587 } else {
1588 RETURN_STRING(intern->u.dir.entry.d_name, 1);
1589 }
1590 }
1591 /* }}} */
1592
1593 /* {{{ proto int RecursiveDirectoryIterator::__construct(string path [, int flags])
1594 Cronstructs a new dir iterator from a path. */
SPL_METHOD(RecursiveDirectoryIterator,__construct)1595 SPL_METHOD(RecursiveDirectoryIterator, __construct)
1596 {
1597 spl_filesystem_object_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, DIT_CTOR_FLAGS);
1598 }
1599 /* }}} */
1600
1601 #ifdef HAVE_GLOB
1602 /* {{{ proto int GlobIterator::__construct(string path [, int flags])
1603 Cronstructs a new dir iterator from a glob expression (no glob:// needed). */
SPL_METHOD(GlobIterator,__construct)1604 SPL_METHOD(GlobIterator, __construct)
1605 {
1606 spl_filesystem_object_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, DIT_CTOR_FLAGS|DIT_CTOR_GLOB);
1607 }
1608 /* }}} */
1609
1610 /* {{{ proto int GlobIterator::cont()
1611 Return the number of directories and files found by globbing */
SPL_METHOD(GlobIterator,count)1612 SPL_METHOD(GlobIterator, count)
1613 {
1614 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1615
1616 if (zend_parse_parameters_none() == FAILURE) {
1617 return;
1618 }
1619
1620 if (intern->u.dir.dirp && php_stream_is(intern->u.dir.dirp ,&php_glob_stream_ops)) {
1621 RETURN_LONG(php_glob_stream_get_count(intern->u.dir.dirp, NULL));
1622 } else {
1623 /* should not happen */
1624 php_error_docref(NULL TSRMLS_CC, E_ERROR, "GlobIterator lost glob state");
1625 }
1626 }
1627 /* }}} */
1628 #endif /* HAVE_GLOB */
1629
1630 /* {{{ forward declarations to the iterator handlers */
1631 static void spl_filesystem_dir_it_dtor(zend_object_iterator *iter TSRMLS_DC);
1632 static int spl_filesystem_dir_it_valid(zend_object_iterator *iter TSRMLS_DC);
1633 static void spl_filesystem_dir_it_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC);
1634 static void spl_filesystem_dir_it_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC);
1635 static void spl_filesystem_dir_it_move_forward(zend_object_iterator *iter TSRMLS_DC);
1636 static void spl_filesystem_dir_it_rewind(zend_object_iterator *iter TSRMLS_DC);
1637
1638 /* iterator handler table */
1639 zend_object_iterator_funcs spl_filesystem_dir_it_funcs = {
1640 spl_filesystem_dir_it_dtor,
1641 spl_filesystem_dir_it_valid,
1642 spl_filesystem_dir_it_current_data,
1643 spl_filesystem_dir_it_current_key,
1644 spl_filesystem_dir_it_move_forward,
1645 spl_filesystem_dir_it_rewind
1646 };
1647 /* }}} */
1648
1649 /* {{{ spl_ce_dir_get_iterator */
spl_filesystem_dir_get_iterator(zend_class_entry * ce,zval * object,int by_ref TSRMLS_DC)1650 zend_object_iterator *spl_filesystem_dir_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
1651 {
1652 spl_filesystem_iterator *iterator;
1653 spl_filesystem_object *dir_object;
1654
1655 if (by_ref) {
1656 zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
1657 }
1658 dir_object = (spl_filesystem_object*)zend_object_store_get_object(object TSRMLS_CC);
1659 iterator = spl_filesystem_object_to_iterator(dir_object);
1660
1661 /* initialize iterator if it wasn't gotten before */
1662 if (iterator->intern.data == NULL) {
1663 iterator->intern.data = object;
1664 iterator->intern.funcs = &spl_filesystem_dir_it_funcs;
1665 /* ->current must be initialized; rewind doesn't set it and valid
1666 * doesn't check whether it's set */
1667 iterator->current = object;
1668 }
1669 zval_add_ref(&object);
1670
1671 return (zend_object_iterator*)iterator;
1672 }
1673 /* }}} */
1674
1675 /* {{{ spl_filesystem_dir_it_dtor */
spl_filesystem_dir_it_dtor(zend_object_iterator * iter TSRMLS_DC)1676 static void spl_filesystem_dir_it_dtor(zend_object_iterator *iter TSRMLS_DC)
1677 {
1678 spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter;
1679
1680 if (iterator->intern.data) {
1681 zval *object = iterator->intern.data;
1682 zval_ptr_dtor(&object);
1683 }
1684 /* Otherwise we were called from the owning object free storage handler as
1685 * it sets
1686 * iterator->intern.data to NULL.
1687 * We don't even need to destroy iterator->current as we didn't add a
1688 * reference to it in move_forward or get_iterator */
1689 }
1690 /* }}} */
1691
1692 /* {{{ spl_filesystem_dir_it_valid */
spl_filesystem_dir_it_valid(zend_object_iterator * iter TSRMLS_DC)1693 static int spl_filesystem_dir_it_valid(zend_object_iterator *iter TSRMLS_DC)
1694 {
1695 spl_filesystem_object *object = spl_filesystem_iterator_to_object((spl_filesystem_iterator *)iter);
1696
1697 return object->u.dir.entry.d_name[0] != '\0' ? SUCCESS : FAILURE;
1698 }
1699 /* }}} */
1700
1701 /* {{{ spl_filesystem_dir_it_current_data */
spl_filesystem_dir_it_current_data(zend_object_iterator * iter,zval *** data TSRMLS_DC)1702 static void spl_filesystem_dir_it_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC)
1703 {
1704 spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter;
1705
1706 *data = &iterator->current;
1707 }
1708 /* }}} */
1709
1710 /* {{{ spl_filesystem_dir_it_current_key */
spl_filesystem_dir_it_current_key(zend_object_iterator * iter,zval * key TSRMLS_DC)1711 static void spl_filesystem_dir_it_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC)
1712 {
1713 spl_filesystem_object *object = spl_filesystem_iterator_to_object((spl_filesystem_iterator *)iter);
1714
1715 ZVAL_LONG(key, object->u.dir.index);
1716 }
1717 /* }}} */
1718
1719 /* {{{ spl_filesystem_dir_it_move_forward */
spl_filesystem_dir_it_move_forward(zend_object_iterator * iter TSRMLS_DC)1720 static void spl_filesystem_dir_it_move_forward(zend_object_iterator *iter TSRMLS_DC)
1721 {
1722 spl_filesystem_object *object = spl_filesystem_iterator_to_object((spl_filesystem_iterator *)iter);
1723
1724 object->u.dir.index++;
1725 spl_filesystem_dir_read(object TSRMLS_CC);
1726 if (object->file_name) {
1727 efree(object->file_name);
1728 object->file_name = NULL;
1729 }
1730 }
1731 /* }}} */
1732
1733 /* {{{ spl_filesystem_dir_it_rewind */
spl_filesystem_dir_it_rewind(zend_object_iterator * iter TSRMLS_DC)1734 static void spl_filesystem_dir_it_rewind(zend_object_iterator *iter TSRMLS_DC)
1735 {
1736 spl_filesystem_object *object = spl_filesystem_iterator_to_object((spl_filesystem_iterator *)iter);
1737
1738 object->u.dir.index = 0;
1739 if (object->u.dir.dirp) {
1740 php_stream_rewinddir(object->u.dir.dirp);
1741 }
1742 spl_filesystem_dir_read(object TSRMLS_CC);
1743 }
1744 /* }}} */
1745
1746 /* {{{ spl_filesystem_tree_it_dtor */
spl_filesystem_tree_it_dtor(zend_object_iterator * iter TSRMLS_DC)1747 static void spl_filesystem_tree_it_dtor(zend_object_iterator *iter TSRMLS_DC)
1748 {
1749 spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter;
1750
1751 if (iterator->intern.data) {
1752 zval *object = iterator->intern.data;
1753 zval_ptr_dtor(&object);
1754 } else {
1755 if (iterator->current) {
1756 zval_ptr_dtor(&iterator->current);
1757 }
1758 }
1759 }
1760 /* }}} */
1761
1762 /* {{{ spl_filesystem_tree_it_current_data */
spl_filesystem_tree_it_current_data(zend_object_iterator * iter,zval *** data TSRMLS_DC)1763 static void spl_filesystem_tree_it_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC)
1764 {
1765 spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter;
1766 spl_filesystem_object *object = spl_filesystem_iterator_to_object(iterator);
1767
1768 if (SPL_FILE_DIR_CURRENT(object, SPL_FILE_DIR_CURRENT_AS_PATHNAME)) {
1769 if (!iterator->current) {
1770 ALLOC_INIT_ZVAL(iterator->current);
1771 spl_filesystem_object_get_file_name(object TSRMLS_CC);
1772 ZVAL_STRINGL(iterator->current, object->file_name, object->file_name_len, 1);
1773 }
1774 *data = &iterator->current;
1775 } else if (SPL_FILE_DIR_CURRENT(object, SPL_FILE_DIR_CURRENT_AS_FILEINFO)) {
1776 if (!iterator->current) {
1777 ALLOC_INIT_ZVAL(iterator->current);
1778 spl_filesystem_object_get_file_name(object TSRMLS_CC);
1779 spl_filesystem_object_create_type(0, object, SPL_FS_INFO, NULL, iterator->current TSRMLS_CC);
1780 }
1781 *data = &iterator->current;
1782 } else {
1783 *data = (zval**)&iterator->intern.data;
1784 }
1785 }
1786 /* }}} */
1787
1788 /* {{{ spl_filesystem_tree_it_current_key */
spl_filesystem_tree_it_current_key(zend_object_iterator * iter,zval * key TSRMLS_DC)1789 static void spl_filesystem_tree_it_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC)
1790 {
1791 spl_filesystem_object *object = spl_filesystem_iterator_to_object((spl_filesystem_iterator *)iter);
1792
1793 if (SPL_FILE_DIR_KEY(object, SPL_FILE_DIR_KEY_AS_FILENAME)) {
1794 ZVAL_STRING(key, object->u.dir.entry.d_name, 1);
1795 } else {
1796 spl_filesystem_object_get_file_name(object TSRMLS_CC);
1797 ZVAL_STRINGL(key, object->file_name, object->file_name_len, 1);
1798 }
1799 }
1800 /* }}} */
1801
1802 /* {{{ spl_filesystem_tree_it_move_forward */
spl_filesystem_tree_it_move_forward(zend_object_iterator * iter TSRMLS_DC)1803 static void spl_filesystem_tree_it_move_forward(zend_object_iterator *iter TSRMLS_DC)
1804 {
1805 spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter;
1806 spl_filesystem_object *object = spl_filesystem_iterator_to_object(iterator);
1807
1808 object->u.dir.index++;
1809 do {
1810 spl_filesystem_dir_read(object TSRMLS_CC);
1811 } while (spl_filesystem_is_dot(object->u.dir.entry.d_name));
1812 if (object->file_name) {
1813 efree(object->file_name);
1814 object->file_name = NULL;
1815 }
1816 if (iterator->current) {
1817 zval_ptr_dtor(&iterator->current);
1818 iterator->current = NULL;
1819 }
1820 }
1821 /* }}} */
1822
1823 /* {{{ spl_filesystem_tree_it_rewind */
spl_filesystem_tree_it_rewind(zend_object_iterator * iter TSRMLS_DC)1824 static void spl_filesystem_tree_it_rewind(zend_object_iterator *iter TSRMLS_DC)
1825 {
1826 spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter;
1827 spl_filesystem_object *object = spl_filesystem_iterator_to_object(iterator);
1828
1829 object->u.dir.index = 0;
1830 if (object->u.dir.dirp) {
1831 php_stream_rewinddir(object->u.dir.dirp);
1832 }
1833 do {
1834 spl_filesystem_dir_read(object TSRMLS_CC);
1835 } while (spl_filesystem_is_dot(object->u.dir.entry.d_name));
1836 if (iterator->current) {
1837 zval_ptr_dtor(&iterator->current);
1838 iterator->current = NULL;
1839 }
1840 }
1841 /* }}} */
1842
1843 /* {{{ iterator handler table */
1844 zend_object_iterator_funcs spl_filesystem_tree_it_funcs = {
1845 spl_filesystem_tree_it_dtor,
1846 spl_filesystem_dir_it_valid,
1847 spl_filesystem_tree_it_current_data,
1848 spl_filesystem_tree_it_current_key,
1849 spl_filesystem_tree_it_move_forward,
1850 spl_filesystem_tree_it_rewind
1851 };
1852 /* }}} */
1853
1854 /* {{{ spl_ce_dir_get_iterator */
spl_filesystem_tree_get_iterator(zend_class_entry * ce,zval * object,int by_ref TSRMLS_DC)1855 zend_object_iterator *spl_filesystem_tree_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
1856 {
1857 spl_filesystem_iterator *iterator;
1858 spl_filesystem_object *dir_object;
1859
1860 if (by_ref) {
1861 zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
1862 }
1863 dir_object = (spl_filesystem_object*)zend_object_store_get_object(object TSRMLS_CC);
1864 iterator = spl_filesystem_object_to_iterator(dir_object);
1865
1866 /* initialize iterator if wasn't gotten before */
1867 if (iterator->intern.data == NULL) {
1868 iterator->intern.data = object;
1869 iterator->intern.funcs = &spl_filesystem_tree_it_funcs;
1870 }
1871 zval_add_ref(&object);
1872
1873 return (zend_object_iterator*)iterator;
1874 }
1875 /* }}} */
1876
1877 /* {{{ spl_filesystem_object_cast */
spl_filesystem_object_cast(zval * readobj,zval * writeobj,int type TSRMLS_DC)1878 static int spl_filesystem_object_cast(zval *readobj, zval *writeobj, int type TSRMLS_DC)
1879 {
1880 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(readobj TSRMLS_CC);
1881
1882 if (type == IS_STRING) {
1883 if (Z_OBJCE_P(readobj)->__tostring) {
1884 return std_object_handlers.cast_object(readobj, writeobj, type TSRMLS_CC);
1885 }
1886
1887 switch (intern->type) {
1888 case SPL_FS_INFO:
1889 case SPL_FS_FILE:
1890 if (readobj == writeobj) {
1891 zval retval;
1892 zval *retval_ptr = &retval;
1893
1894 ZVAL_STRINGL(retval_ptr, intern->file_name, intern->file_name_len, 1);
1895 zval_dtor(readobj);
1896 ZVAL_ZVAL(writeobj, retval_ptr, 0, 0);
1897 } else {
1898 ZVAL_STRINGL(writeobj, intern->file_name, intern->file_name_len, 1);
1899 }
1900 return SUCCESS;
1901 case SPL_FS_DIR:
1902 if (readobj == writeobj) {
1903 zval retval;
1904 zval *retval_ptr = &retval;
1905
1906 ZVAL_STRING(retval_ptr, intern->u.dir.entry.d_name, 1);
1907 zval_dtor(readobj);
1908 ZVAL_ZVAL(writeobj, retval_ptr, 0, 0);
1909 } else {
1910 ZVAL_STRING(writeobj, intern->u.dir.entry.d_name, 1);
1911 }
1912 return SUCCESS;
1913 }
1914 } else if (type == IS_BOOL) {
1915 ZVAL_BOOL(writeobj, 1);
1916 return SUCCESS;
1917 }
1918 if (readobj == writeobj) {
1919 zval_dtor(readobj);
1920 }
1921 ZVAL_NULL(writeobj);
1922 return FAILURE;
1923 }
1924 /* }}} */
1925
1926 /* {{{ declare method parameters */
1927 /* supply a name and default to call by parameter */
1928 ZEND_BEGIN_ARG_INFO(arginfo_info___construct, 0)
1929 ZEND_ARG_INFO(0, file_name)
1930 ZEND_END_ARG_INFO()
1931
1932 ZEND_BEGIN_ARG_INFO_EX(arginfo_info_openFile, 0, 0, 0)
1933 ZEND_ARG_INFO(0, open_mode)
1934 ZEND_ARG_INFO(0, use_include_path)
1935 ZEND_ARG_INFO(0, context)
1936 ZEND_END_ARG_INFO()
1937
1938 ZEND_BEGIN_ARG_INFO_EX(arginfo_info_optinalFileClass, 0, 0, 0)
1939 ZEND_ARG_INFO(0, class_name)
1940 ZEND_END_ARG_INFO()
1941
1942 ZEND_BEGIN_ARG_INFO_EX(arginfo_optinalSuffix, 0, 0, 0)
1943 ZEND_ARG_INFO(0, suffix)
1944 ZEND_END_ARG_INFO()
1945
1946 ZEND_BEGIN_ARG_INFO(arginfo_splfileinfo_void, 0)
1947 ZEND_END_ARG_INFO()
1948
1949 /* the method table */
1950 /* each method can have its own parameters and visibility */
1951 static const zend_function_entry spl_SplFileInfo_functions[] = {
1952 SPL_ME(SplFileInfo, __construct, arginfo_info___construct, ZEND_ACC_PUBLIC)
1953 SPL_ME(SplFileInfo, getPath, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
1954 SPL_ME(SplFileInfo, getFilename, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
1955 SPL_ME(SplFileInfo, getExtension, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
1956 SPL_ME(SplFileInfo, getBasename, arginfo_optinalSuffix, ZEND_ACC_PUBLIC)
1957 SPL_ME(SplFileInfo, getPathname, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
1958 SPL_ME(SplFileInfo, getPerms, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
1959 SPL_ME(SplFileInfo, getInode, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
1960 SPL_ME(SplFileInfo, getSize, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
1961 SPL_ME(SplFileInfo, getOwner, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
1962 SPL_ME(SplFileInfo, getGroup, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
1963 SPL_ME(SplFileInfo, getATime, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
1964 SPL_ME(SplFileInfo, getMTime, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
1965 SPL_ME(SplFileInfo, getCTime, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
1966 SPL_ME(SplFileInfo, getType, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
1967 SPL_ME(SplFileInfo, isWritable, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
1968 SPL_ME(SplFileInfo, isReadable, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
1969 SPL_ME(SplFileInfo, isExecutable, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
1970 SPL_ME(SplFileInfo, isFile, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
1971 SPL_ME(SplFileInfo, isDir, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
1972 SPL_ME(SplFileInfo, isLink, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
1973 SPL_ME(SplFileInfo, getLinkTarget, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
1974 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
1975 SPL_ME(SplFileInfo, getRealPath, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
1976 #endif
1977 SPL_ME(SplFileInfo, getFileInfo, arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC)
1978 SPL_ME(SplFileInfo, getPathInfo, arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC)
1979 SPL_ME(SplFileInfo, openFile, arginfo_info_openFile, ZEND_ACC_PUBLIC)
1980 SPL_ME(SplFileInfo, setFileClass, arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC)
1981 SPL_ME(SplFileInfo, setInfoClass, arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC)
1982 SPL_ME(SplFileInfo, _bad_state_ex, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
1983 SPL_MA(SplFileInfo, __toString, SplFileInfo, getPathname, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
1984 PHP_FE_END
1985 };
1986
1987 ZEND_BEGIN_ARG_INFO(arginfo_dir___construct, 0)
1988 ZEND_ARG_INFO(0, path)
1989 ZEND_END_ARG_INFO()
1990
1991 ZEND_BEGIN_ARG_INFO(arginfo_dir_it_seek, 0)
1992 ZEND_ARG_INFO(0, position)
1993 ZEND_END_ARG_INFO();
1994
1995 /* the method table */
1996 /* each method can have its own parameters and visibility */
1997 static const zend_function_entry spl_DirectoryIterator_functions[] = {
1998 SPL_ME(DirectoryIterator, __construct, arginfo_dir___construct, ZEND_ACC_PUBLIC)
1999 SPL_ME(DirectoryIterator, getFilename, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
2000 SPL_ME(DirectoryIterator, getExtension, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
2001 SPL_ME(DirectoryIterator, getBasename, arginfo_optinalSuffix, ZEND_ACC_PUBLIC)
2002 SPL_ME(DirectoryIterator, isDot, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
2003 SPL_ME(DirectoryIterator, rewind, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
2004 SPL_ME(DirectoryIterator, valid, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
2005 SPL_ME(DirectoryIterator, key, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
2006 SPL_ME(DirectoryIterator, current, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
2007 SPL_ME(DirectoryIterator, next, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
2008 SPL_ME(DirectoryIterator, seek, arginfo_dir_it_seek, ZEND_ACC_PUBLIC)
2009 SPL_MA(DirectoryIterator, __toString, DirectoryIterator, getFilename, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
2010 PHP_FE_END
2011 };
2012
2013 ZEND_BEGIN_ARG_INFO_EX(arginfo_r_dir___construct, 0, 0, 1)
2014 ZEND_ARG_INFO(0, path)
2015 ZEND_ARG_INFO(0, flags)
2016 ZEND_END_ARG_INFO()
2017
2018 ZEND_BEGIN_ARG_INFO_EX(arginfo_r_dir_hasChildren, 0, 0, 0)
2019 ZEND_ARG_INFO(0, allow_links)
2020 ZEND_END_ARG_INFO()
2021
2022 ZEND_BEGIN_ARG_INFO_EX(arginfo_r_dir_setFlags, 0, 0, 0)
2023 ZEND_ARG_INFO(0, flags)
2024 ZEND_END_ARG_INFO()
2025
2026 static const zend_function_entry spl_FilesystemIterator_functions[] = {
2027 SPL_ME(FilesystemIterator, __construct, arginfo_r_dir___construct, ZEND_ACC_PUBLIC)
2028 SPL_ME(FilesystemIterator, rewind, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
2029 SPL_ME(DirectoryIterator, next, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
2030 SPL_ME(FilesystemIterator, key, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
2031 SPL_ME(FilesystemIterator, current, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
2032 SPL_ME(FilesystemIterator, getFlags, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
2033 SPL_ME(FilesystemIterator, setFlags, arginfo_r_dir_setFlags, ZEND_ACC_PUBLIC)
2034 PHP_FE_END
2035 };
2036
2037 static const zend_function_entry spl_RecursiveDirectoryIterator_functions[] = {
2038 SPL_ME(RecursiveDirectoryIterator, __construct, arginfo_r_dir___construct, ZEND_ACC_PUBLIC)
2039 SPL_ME(RecursiveDirectoryIterator, hasChildren, arginfo_r_dir_hasChildren, ZEND_ACC_PUBLIC)
2040 SPL_ME(RecursiveDirectoryIterator, getChildren, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
2041 SPL_ME(RecursiveDirectoryIterator, getSubPath, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
2042 SPL_ME(RecursiveDirectoryIterator, getSubPathname,arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
2043 PHP_FE_END
2044 };
2045
2046 #ifdef HAVE_GLOB
2047 static const zend_function_entry spl_GlobIterator_functions[] = {
2048 SPL_ME(GlobIterator, __construct, arginfo_r_dir___construct, ZEND_ACC_PUBLIC)
2049 SPL_ME(GlobIterator, count, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
2050 PHP_FE_END
2051 };
2052 #endif
2053 /* }}} */
2054
spl_filesystem_file_read(spl_filesystem_object * intern,int silent TSRMLS_DC)2055 static int spl_filesystem_file_read(spl_filesystem_object *intern, int silent TSRMLS_DC) /* {{{ */
2056 {
2057 char *buf;
2058 size_t line_len = 0;
2059 long line_add = (intern->u.file.current_line || intern->u.file.current_zval) ? 1 : 0;
2060
2061 spl_filesystem_file_free_line(intern TSRMLS_CC);
2062
2063 if (php_stream_eof(intern->u.file.stream)) {
2064 if (!silent) {
2065 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot read from file %s", intern->file_name);
2066 }
2067 return FAILURE;
2068 }
2069
2070 if (intern->u.file.max_line_len > 0) {
2071 buf = safe_emalloc((intern->u.file.max_line_len + 1), sizeof(char), 0);
2072 if (php_stream_get_line(intern->u.file.stream, buf, intern->u.file.max_line_len + 1, &line_len) == NULL) {
2073 efree(buf);
2074 buf = NULL;
2075 } else {
2076 buf[line_len] = '\0';
2077 }
2078 } else {
2079 buf = php_stream_get_line(intern->u.file.stream, NULL, 0, &line_len);
2080 }
2081
2082 if (!buf) {
2083 intern->u.file.current_line = estrdup("");
2084 intern->u.file.current_line_len = 0;
2085 } else {
2086 if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_DROP_NEW_LINE)) {
2087 line_len = strcspn(buf, "\r\n");
2088 buf[line_len] = '\0';
2089 }
2090
2091 intern->u.file.current_line = buf;
2092 intern->u.file.current_line_len = line_len;
2093 }
2094 intern->u.file.current_line_num += line_add;
2095
2096 return SUCCESS;
2097 } /* }}} */
2098
spl_filesystem_file_call(spl_filesystem_object * intern,zend_function * func_ptr,int pass_num_args,zval * return_value,zval * arg2 TSRMLS_DC)2099 static int spl_filesystem_file_call(spl_filesystem_object *intern, zend_function *func_ptr, int pass_num_args, zval *return_value, zval *arg2 TSRMLS_DC) /* {{{ */
2100 {
2101 zend_fcall_info fci;
2102 zend_fcall_info_cache fcic;
2103 zval z_fname;
2104 zval * zresource_ptr = &intern->u.file.zresource, *retval = NULL;
2105 int result;
2106 int num_args = pass_num_args + (arg2 ? 2 : 1);
2107
2108 zval ***params = (zval***)safe_emalloc(num_args, sizeof(zval**), 0);
2109
2110 params[0] = &zresource_ptr;
2111
2112 if (arg2) {
2113 params[1] = &arg2;
2114 }
2115
2116 zend_get_parameters_array_ex(pass_num_args, params+(arg2 ? 2 : 1));
2117
2118 ZVAL_STRING(&z_fname, func_ptr->common.function_name, 0);
2119
2120 fci.size = sizeof(fci);
2121 fci.function_table = EG(function_table);
2122 fci.object_ptr = NULL;
2123 fci.function_name = &z_fname;
2124 fci.retval_ptr_ptr = &retval;
2125 fci.param_count = num_args;
2126 fci.params = params;
2127 fci.no_separation = 1;
2128 fci.symbol_table = NULL;
2129
2130 fcic.initialized = 1;
2131 fcic.function_handler = func_ptr;
2132 fcic.calling_scope = NULL;
2133 fcic.called_scope = NULL;
2134 fcic.object_ptr = NULL;
2135
2136 result = zend_call_function(&fci, &fcic TSRMLS_CC);
2137
2138 if (result == FAILURE || retval == NULL) {
2139 RETVAL_FALSE;
2140 } else {
2141 ZVAL_ZVAL(return_value, retval, 1, 1);
2142 }
2143
2144 efree(params);
2145 return result;
2146 } /* }}} */
2147
2148 #define FileFunctionCall(func_name, pass_num_args, arg2) /* {{{ */ \
2149 { \
2150 zend_function *func_ptr; \
2151 int ret; \
2152 ret = zend_hash_find(EG(function_table), #func_name, sizeof(#func_name), (void **) &func_ptr); \
2153 if (ret != SUCCESS) { \
2154 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Internal error, function '%s' not found. Please report", #func_name); \
2155 return; \
2156 } \
2157 spl_filesystem_file_call(intern, func_ptr, pass_num_args, return_value, arg2 TSRMLS_CC); \
2158 } /* }}} */
2159
spl_filesystem_file_read_csv(spl_filesystem_object * intern,char delimiter,char enclosure,char escape,zval * return_value TSRMLS_DC)2160 static int spl_filesystem_file_read_csv(spl_filesystem_object *intern, char delimiter, char enclosure, char escape, zval *return_value TSRMLS_DC) /* {{{ */
2161 {
2162 int ret = SUCCESS;
2163
2164 do {
2165 ret = spl_filesystem_file_read(intern, 1 TSRMLS_CC);
2166 } while (ret == SUCCESS && !intern->u.file.current_line_len && SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_SKIP_EMPTY));
2167
2168 if (ret == SUCCESS) {
2169 size_t buf_len = intern->u.file.current_line_len;
2170 char *buf = estrndup(intern->u.file.current_line, buf_len);
2171
2172 if (intern->u.file.current_zval) {
2173 zval_ptr_dtor(&intern->u.file.current_zval);
2174 }
2175 ALLOC_INIT_ZVAL(intern->u.file.current_zval);
2176
2177 php_fgetcsv(intern->u.file.stream, delimiter, enclosure, escape, buf_len, buf, intern->u.file.current_zval TSRMLS_CC);
2178 if (return_value) {
2179 if (Z_TYPE_P(return_value) != IS_NULL) {
2180 zval_dtor(return_value);
2181 ZVAL_NULL(return_value);
2182 }
2183 ZVAL_ZVAL(return_value, intern->u.file.current_zval, 1, 0);
2184 }
2185 }
2186 return ret;
2187 }
2188 /* }}} */
2189
spl_filesystem_file_read_line_ex(zval * this_ptr,spl_filesystem_object * intern,int silent TSRMLS_DC)2190 static int spl_filesystem_file_read_line_ex(zval * this_ptr, spl_filesystem_object *intern, int silent TSRMLS_DC) /* {{{ */
2191 {
2192 zval *retval = NULL;
2193
2194 /* 1) use fgetcsv? 2) overloaded call the function, 3) do it directly */
2195 if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV) || intern->u.file.func_getCurr->common.scope != spl_ce_SplFileObject) {
2196 if (php_stream_eof(intern->u.file.stream)) {
2197 if (!silent) {
2198 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot read from file %s", intern->file_name);
2199 }
2200 return FAILURE;
2201 }
2202 if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV)) {
2203 return spl_filesystem_file_read_csv(intern, intern->u.file.delimiter, intern->u.file.enclosure, intern->u.file.escape, NULL TSRMLS_CC);
2204 } else {
2205 zend_call_method_with_0_params(&this_ptr, Z_OBJCE_P(getThis()), &intern->u.file.func_getCurr, "getCurrentLine", &retval);
2206 }
2207 if (retval) {
2208 if (intern->u.file.current_line || intern->u.file.current_zval) {
2209 intern->u.file.current_line_num++;
2210 }
2211 spl_filesystem_file_free_line(intern TSRMLS_CC);
2212 if (Z_TYPE_P(retval) == IS_STRING) {
2213 intern->u.file.current_line = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
2214 intern->u.file.current_line_len = Z_STRLEN_P(retval);
2215 } else {
2216 MAKE_STD_ZVAL(intern->u.file.current_zval);
2217 ZVAL_ZVAL(intern->u.file.current_zval, retval, 1, 0);
2218 }
2219 zval_ptr_dtor(&retval);
2220 return SUCCESS;
2221 } else {
2222 return FAILURE;
2223 }
2224 } else {
2225 return spl_filesystem_file_read(intern, silent TSRMLS_CC);
2226 }
2227 } /* }}} */
2228
spl_filesystem_file_is_empty_line(spl_filesystem_object * intern TSRMLS_DC)2229 static int spl_filesystem_file_is_empty_line(spl_filesystem_object *intern TSRMLS_DC) /* {{{ */
2230 {
2231 if (intern->u.file.current_line) {
2232 return intern->u.file.current_line_len == 0;
2233 } else if (intern->u.file.current_zval) {
2234 switch(Z_TYPE_P(intern->u.file.current_zval)) {
2235 case IS_STRING:
2236 return Z_STRLEN_P(intern->u.file.current_zval) == 0;
2237 case IS_ARRAY:
2238 if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV)
2239 && zend_hash_num_elements(Z_ARRVAL_P(intern->u.file.current_zval)) == 1) {
2240 zval ** first = Z_ARRVAL_P(intern->u.file.current_zval)->pListHead->pData;
2241
2242 return Z_TYPE_PP(first) == IS_STRING && Z_STRLEN_PP(first) == 0;
2243 }
2244 return zend_hash_num_elements(Z_ARRVAL_P(intern->u.file.current_zval)) == 0;
2245 case IS_NULL:
2246 return 1;
2247 default:
2248 return 0;
2249 }
2250 } else {
2251 return 1;
2252 }
2253 }
2254 /* }}} */
2255
spl_filesystem_file_read_line(zval * this_ptr,spl_filesystem_object * intern,int silent TSRMLS_DC)2256 static int spl_filesystem_file_read_line(zval * this_ptr, spl_filesystem_object *intern, int silent TSRMLS_DC) /* {{{ */
2257 {
2258 int ret = spl_filesystem_file_read_line_ex(this_ptr, intern, silent TSRMLS_CC);
2259
2260 while (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_SKIP_EMPTY) && ret == SUCCESS && spl_filesystem_file_is_empty_line(intern TSRMLS_CC)) {
2261 spl_filesystem_file_free_line(intern TSRMLS_CC);
2262 ret = spl_filesystem_file_read_line_ex(this_ptr, intern, silent TSRMLS_CC);
2263 }
2264
2265 return ret;
2266 }
2267 /* }}} */
2268
spl_filesystem_file_rewind(zval * this_ptr,spl_filesystem_object * intern TSRMLS_DC)2269 static void spl_filesystem_file_rewind(zval * this_ptr, spl_filesystem_object *intern TSRMLS_DC) /* {{{ */
2270 {
2271 if(!intern->u.file.stream) {
2272 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized");
2273 return;
2274 }
2275 if (-1 == php_stream_rewind(intern->u.file.stream)) {
2276 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot rewind file %s", intern->file_name);
2277 } else {
2278 spl_filesystem_file_free_line(intern TSRMLS_CC);
2279 intern->u.file.current_line_num = 0;
2280 }
2281 if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_AHEAD)) {
2282 spl_filesystem_file_read_line(this_ptr, intern, 1 TSRMLS_CC);
2283 }
2284 } /* }}} */
2285
2286 /* {{{ proto void SplFileObject::__construct(string filename [, string mode = 'r' [, bool use_include_path [, resource context]]]])
2287 Construct a new file object */
SPL_METHOD(SplFileObject,__construct)2288 SPL_METHOD(SplFileObject, __construct)
2289 {
2290 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2291 zend_bool use_include_path = 0;
2292 char *p1, *p2;
2293 char *tmp_path;
2294 int tmp_path_len;
2295 zend_error_handling error_handling;
2296
2297 zend_replace_error_handling(EH_THROW, spl_ce_RuntimeException, &error_handling TSRMLS_CC);
2298
2299 intern->u.file.open_mode = NULL;
2300 intern->u.file.open_mode_len = 0;
2301
2302 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|sbr!",
2303 &intern->file_name, &intern->file_name_len,
2304 &intern->u.file.open_mode, &intern->u.file.open_mode_len,
2305 &use_include_path, &intern->u.file.zcontext) == FAILURE) {
2306 intern->u.file.open_mode = NULL;
2307 intern->file_name = NULL;
2308 zend_restore_error_handling(&error_handling TSRMLS_CC);
2309 return;
2310 }
2311
2312 if (intern->u.file.open_mode == NULL) {
2313 intern->u.file.open_mode = "r";
2314 intern->u.file.open_mode_len = 1;
2315 }
2316
2317 if (spl_filesystem_file_open(intern, use_include_path, 0 TSRMLS_CC) == SUCCESS) {
2318 tmp_path_len = strlen(intern->u.file.stream->orig_path);
2319
2320 if (tmp_path_len > 1 && IS_SLASH_AT(intern->u.file.stream->orig_path, tmp_path_len-1)) {
2321 tmp_path_len--;
2322 }
2323
2324 tmp_path = estrndup(intern->u.file.stream->orig_path, tmp_path_len);
2325
2326 p1 = strrchr(tmp_path, '/');
2327 #if defined(PHP_WIN32) || defined(NETWARE)
2328 p2 = strrchr(tmp_path, '\\');
2329 #else
2330 p2 = 0;
2331 #endif
2332 if (p1 || p2) {
2333 intern->_path_len = (p1 > p2 ? p1 : p2) - tmp_path;
2334 } else {
2335 intern->_path_len = 0;
2336 }
2337
2338 efree(tmp_path);
2339
2340 intern->_path = estrndup(intern->u.file.stream->orig_path, intern->_path_len);
2341 }
2342
2343 zend_restore_error_handling(&error_handling TSRMLS_CC);
2344
2345 } /* }}} */
2346
2347 /* {{{ proto void SplTempFileObject::__construct([int max_memory])
2348 Construct a new temp file object */
SPL_METHOD(SplTempFileObject,__construct)2349 SPL_METHOD(SplTempFileObject, __construct)
2350 {
2351 long max_memory = PHP_STREAM_MAX_MEM;
2352 char tmp_fname[48];
2353 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2354 zend_error_handling error_handling;
2355
2356 zend_replace_error_handling(EH_THROW, spl_ce_RuntimeException, &error_handling TSRMLS_CC);
2357
2358 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &max_memory) == FAILURE) {
2359 zend_restore_error_handling(&error_handling TSRMLS_CC);
2360 return;
2361 }
2362
2363 if (max_memory < 0) {
2364 intern->file_name = "php://memory";
2365 intern->file_name_len = 12;
2366 } else if (ZEND_NUM_ARGS()) {
2367 intern->file_name_len = slprintf(tmp_fname, sizeof(tmp_fname), "php://temp/maxmemory:%ld", max_memory);
2368 intern->file_name = tmp_fname;
2369 } else {
2370 intern->file_name = "php://temp";
2371 intern->file_name_len = 10;
2372 }
2373 intern->u.file.open_mode = "wb";
2374 intern->u.file.open_mode_len = 1;
2375 intern->u.file.zcontext = NULL;
2376
2377 if (spl_filesystem_file_open(intern, 0, 0 TSRMLS_CC) == SUCCESS) {
2378 intern->_path_len = 0;
2379 intern->_path = estrndup("", 0);
2380 }
2381 zend_restore_error_handling(&error_handling TSRMLS_CC);
2382 } /* }}} */
2383
2384 /* {{{ proto void SplFileObject::rewind()
2385 Rewind the file and read the first line */
SPL_METHOD(SplFileObject,rewind)2386 SPL_METHOD(SplFileObject, rewind)
2387 {
2388 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2389
2390 if (zend_parse_parameters_none() == FAILURE) {
2391 return;
2392 }
2393
2394 spl_filesystem_file_rewind(getThis(), intern TSRMLS_CC);
2395 } /* }}} */
2396
2397 /* {{{ proto void SplFileObject::eof()
2398 Return whether end of file is reached */
SPL_METHOD(SplFileObject,eof)2399 SPL_METHOD(SplFileObject, eof)
2400 {
2401 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2402
2403 if (zend_parse_parameters_none() == FAILURE) {
2404 return;
2405 }
2406
2407 if(!intern->u.file.stream) {
2408 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized");
2409 return;
2410 }
2411
2412 RETURN_BOOL(php_stream_eof(intern->u.file.stream));
2413 } /* }}} */
2414
2415 /* {{{ proto void SplFileObject::valid()
2416 Return !eof() */
SPL_METHOD(SplFileObject,valid)2417 SPL_METHOD(SplFileObject, valid)
2418 {
2419 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2420
2421 if (zend_parse_parameters_none() == FAILURE) {
2422 return;
2423 }
2424
2425 if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_AHEAD)) {
2426 RETURN_BOOL(intern->u.file.current_line || intern->u.file.current_zval);
2427 } else {
2428 if(!intern->u.file.stream) {
2429 RETURN_FALSE;
2430 }
2431 RETVAL_BOOL(!php_stream_eof(intern->u.file.stream));
2432 }
2433 } /* }}} */
2434
2435 /* {{{ proto string SplFileObject::fgets()
2436 Rturn next line from file */
SPL_METHOD(SplFileObject,fgets)2437 SPL_METHOD(SplFileObject, fgets)
2438 {
2439 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2440
2441 if (zend_parse_parameters_none() == FAILURE) {
2442 return;
2443 }
2444
2445 if(!intern->u.file.stream) {
2446 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized");
2447 return;
2448 }
2449
2450 if (spl_filesystem_file_read(intern, 0 TSRMLS_CC) == FAILURE) {
2451 RETURN_FALSE;
2452 }
2453 RETURN_STRINGL(intern->u.file.current_line, intern->u.file.current_line_len, 1);
2454 } /* }}} */
2455
2456 /* {{{ proto string SplFileObject::current()
2457 Return current line from file */
SPL_METHOD(SplFileObject,current)2458 SPL_METHOD(SplFileObject, current)
2459 {
2460 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2461
2462 if (zend_parse_parameters_none() == FAILURE) {
2463 return;
2464 }
2465
2466 if(!intern->u.file.stream) {
2467 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized");
2468 return;
2469 }
2470
2471 if (!intern->u.file.current_line && !intern->u.file.current_zval) {
2472 spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC);
2473 }
2474 if (intern->u.file.current_line && (!SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV) || !intern->u.file.current_zval)) {
2475 RETURN_STRINGL(intern->u.file.current_line, intern->u.file.current_line_len, 1);
2476 } else if (intern->u.file.current_zval) {
2477 RETURN_ZVAL(intern->u.file.current_zval, 1, 0);
2478 }
2479 RETURN_FALSE;
2480 } /* }}} */
2481
2482 /* {{{ proto int SplFileObject::key()
2483 Return line number */
SPL_METHOD(SplFileObject,key)2484 SPL_METHOD(SplFileObject, key)
2485 {
2486 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2487
2488 if (zend_parse_parameters_none() == FAILURE) {
2489 return;
2490 }
2491
2492 /* Do not read the next line to support correct counting with fgetc()
2493 if (!intern->current_line) {
2494 spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC);
2495 } */
2496 RETURN_LONG(intern->u.file.current_line_num);
2497 } /* }}} */
2498
2499 /* {{{ proto void SplFileObject::next()
2500 Read next line */
SPL_METHOD(SplFileObject,next)2501 SPL_METHOD(SplFileObject, next)
2502 {
2503 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2504
2505 if (zend_parse_parameters_none() == FAILURE) {
2506 return;
2507 }
2508
2509 spl_filesystem_file_free_line(intern TSRMLS_CC);
2510 if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_AHEAD)) {
2511 spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC);
2512 }
2513 intern->u.file.current_line_num++;
2514 } /* }}} */
2515
2516 /* {{{ proto void SplFileObject::setFlags(int flags)
2517 Set file handling flags */
SPL_METHOD(SplFileObject,setFlags)2518 SPL_METHOD(SplFileObject, setFlags)
2519 {
2520 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2521
2522 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &intern->flags) == FAILURE) {
2523 return;
2524 }
2525 } /* }}} */
2526
2527 /* {{{ proto int SplFileObject::getFlags()
2528 Get file handling flags */
SPL_METHOD(SplFileObject,getFlags)2529 SPL_METHOD(SplFileObject, getFlags)
2530 {
2531 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2532
2533 if (zend_parse_parameters_none() == FAILURE) {
2534 return;
2535 }
2536
2537 RETURN_LONG(intern->flags & SPL_FILE_OBJECT_MASK);
2538 } /* }}} */
2539
2540 /* {{{ proto void SplFileObject::setMaxLineLen(int max_len)
2541 Set maximum line length */
SPL_METHOD(SplFileObject,setMaxLineLen)2542 SPL_METHOD(SplFileObject, setMaxLineLen)
2543 {
2544 long max_len;
2545
2546 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2547
2548 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &max_len) == FAILURE) {
2549 return;
2550 }
2551
2552 if (max_len < 0) {
2553 zend_throw_exception_ex(spl_ce_DomainException, 0 TSRMLS_CC, "Maximum line length must be greater than or equal zero");
2554 return;
2555 }
2556
2557 intern->u.file.max_line_len = max_len;
2558 } /* }}} */
2559
2560 /* {{{ proto int SplFileObject::getMaxLineLen()
2561 Get maximum line length */
SPL_METHOD(SplFileObject,getMaxLineLen)2562 SPL_METHOD(SplFileObject, getMaxLineLen)
2563 {
2564 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2565
2566 if (zend_parse_parameters_none() == FAILURE) {
2567 return;
2568 }
2569
2570 RETURN_LONG((long)intern->u.file.max_line_len);
2571 } /* }}} */
2572
2573 /* {{{ proto bool SplFileObject::hasChildren()
2574 Return false */
SPL_METHOD(SplFileObject,hasChildren)2575 SPL_METHOD(SplFileObject, hasChildren)
2576 {
2577 if (zend_parse_parameters_none() == FAILURE) {
2578 return;
2579 }
2580
2581 RETURN_FALSE;
2582 } /* }}} */
2583
2584 /* {{{ proto bool SplFileObject::getChildren()
2585 Read NULL */
SPL_METHOD(SplFileObject,getChildren)2586 SPL_METHOD(SplFileObject, getChildren)
2587 {
2588 if (zend_parse_parameters_none() == FAILURE) {
2589 return;
2590 }
2591 /* return NULL */
2592 } /* }}} */
2593
2594 /* {{{ FileFunction */
2595 #define FileFunction(func_name) \
2596 SPL_METHOD(SplFileObject, func_name) \
2597 { \
2598 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); \
2599 FileFunctionCall(func_name, ZEND_NUM_ARGS(), NULL); \
2600 }
2601 /* }}} */
2602
2603 /* {{{ proto array SplFileObject::fgetcsv([string delimiter [, string enclosure [, escape = '\\']]])
2604 Return current line as csv */
SPL_METHOD(SplFileObject,fgetcsv)2605 SPL_METHOD(SplFileObject, fgetcsv)
2606 {
2607 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2608 char delimiter = intern->u.file.delimiter, enclosure = intern->u.file.enclosure, escape = intern->u.file.escape;
2609 char *delim = NULL, *enclo = NULL, *esc = NULL;
2610 int d_len = 0, e_len = 0, esc_len = 0;
2611
2612 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sss", &delim, &d_len, &enclo, &e_len, &esc, &esc_len) == SUCCESS) {
2613
2614 if(!intern->u.file.stream) {
2615 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized");
2616 return;
2617 }
2618
2619 switch(ZEND_NUM_ARGS())
2620 {
2621 case 3:
2622 if (esc_len != 1) {
2623 php_error_docref(NULL TSRMLS_CC, E_WARNING, "escape must be a character");
2624 RETURN_FALSE;
2625 }
2626 escape = esc[0];
2627 /* no break */
2628 case 2:
2629 if (e_len != 1) {
2630 php_error_docref(NULL TSRMLS_CC, E_WARNING, "enclosure must be a character");
2631 RETURN_FALSE;
2632 }
2633 enclosure = enclo[0];
2634 /* no break */
2635 case 1:
2636 if (d_len != 1) {
2637 php_error_docref(NULL TSRMLS_CC, E_WARNING, "delimiter must be a character");
2638 RETURN_FALSE;
2639 }
2640 delimiter = delim[0];
2641 /* no break */
2642 case 0:
2643 break;
2644 }
2645 spl_filesystem_file_read_csv(intern, delimiter, enclosure, escape, return_value TSRMLS_CC);
2646 }
2647 }
2648 /* }}} */
2649
2650 /* {{{ proto int SplFileObject::fputcsv(array fields, [string delimiter [, string enclosure [, string escape]]])
2651 Output a field array as a CSV line */
SPL_METHOD(SplFileObject,fputcsv)2652 SPL_METHOD(SplFileObject, fputcsv)
2653 {
2654 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2655 char delimiter = intern->u.file.delimiter, enclosure = intern->u.file.enclosure, escape = intern->u.file.escape;
2656 char *delim = NULL, *enclo = NULL, *esc = NULL;
2657 int d_len = 0, e_len = 0, esc_len = 0, ret;
2658 zval *fields = NULL;
2659
2660 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|sss", &fields, &delim, &d_len, &enclo, &e_len, &esc, &esc_len) == SUCCESS) {
2661 switch(ZEND_NUM_ARGS())
2662 {
2663 case 4:
2664 if (esc_len != 1) {
2665 php_error_docref(NULL TSRMLS_CC, E_WARNING, "escape must be a character");
2666 RETURN_FALSE;
2667 }
2668 escape = esc[0];
2669 /* no break */
2670 case 3:
2671 if (e_len != 1) {
2672 php_error_docref(NULL TSRMLS_CC, E_WARNING, "enclosure must be a character");
2673 RETURN_FALSE;
2674 }
2675 enclosure = enclo[0];
2676 /* no break */
2677 case 2:
2678 if (d_len != 1) {
2679 php_error_docref(NULL TSRMLS_CC, E_WARNING, "delimiter must be a character");
2680 RETURN_FALSE;
2681 }
2682 delimiter = delim[0];
2683 /* no break */
2684 case 1:
2685 case 0:
2686 break;
2687 }
2688 ret = php_fputcsv(intern->u.file.stream, fields, delimiter, enclosure, escape TSRMLS_CC);
2689 RETURN_LONG(ret);
2690 }
2691 }
2692 /* }}} */
2693
2694 /* {{{ proto void SplFileObject::setCsvControl([string delimiter = ',' [, string enclosure = '"' [, string escape = '\\']]])
2695 Set the delimiter, enclosure and escape character used in fgetcsv */
SPL_METHOD(SplFileObject,setCsvControl)2696 SPL_METHOD(SplFileObject, setCsvControl)
2697 {
2698 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2699 char delimiter = ',', enclosure = '"', escape='\\';
2700 char *delim = NULL, *enclo = NULL, *esc = NULL;
2701 int d_len = 0, e_len = 0, esc_len = 0;
2702
2703 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sss", &delim, &d_len, &enclo, &e_len, &esc, &esc_len) == SUCCESS) {
2704 switch(ZEND_NUM_ARGS())
2705 {
2706 case 3:
2707 if (esc_len != 1) {
2708 php_error_docref(NULL TSRMLS_CC, E_WARNING, "escape must be a character");
2709 RETURN_FALSE;
2710 }
2711 escape = esc[0];
2712 /* no break */
2713 case 2:
2714 if (e_len != 1) {
2715 php_error_docref(NULL TSRMLS_CC, E_WARNING, "enclosure must be a character");
2716 RETURN_FALSE;
2717 }
2718 enclosure = enclo[0];
2719 /* no break */
2720 case 1:
2721 if (d_len != 1) {
2722 php_error_docref(NULL TSRMLS_CC, E_WARNING, "delimiter must be a character");
2723 RETURN_FALSE;
2724 }
2725 delimiter = delim[0];
2726 /* no break */
2727 case 0:
2728 break;
2729 }
2730 intern->u.file.delimiter = delimiter;
2731 intern->u.file.enclosure = enclosure;
2732 intern->u.file.escape = escape;
2733 }
2734 }
2735 /* }}} */
2736
2737 /* {{{ proto array SplFileObject::getCsvControl()
2738 Get the delimiter, enclosure and escape character used in fgetcsv */
SPL_METHOD(SplFileObject,getCsvControl)2739 SPL_METHOD(SplFileObject, getCsvControl)
2740 {
2741 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2742 char delimiter[2], enclosure[2], escape[2];
2743
2744 array_init(return_value);
2745
2746 delimiter[0] = intern->u.file.delimiter;
2747 delimiter[1] = '\0';
2748 enclosure[0] = intern->u.file.enclosure;
2749 enclosure[1] = '\0';
2750 escape[0] = intern->u.file.escape;
2751 escape[1] = '\0';
2752
2753 add_next_index_string(return_value, delimiter, 1);
2754 add_next_index_string(return_value, enclosure, 1);
2755 add_next_index_string(return_value, escape, 1);
2756 }
2757 /* }}} */
2758
2759 /* {{{ proto bool SplFileObject::flock(int operation [, int &wouldblock])
2760 Portable file locking */
2761 FileFunction(flock)
2762 /* }}} */
2763
2764 /* {{{ proto bool SplFileObject::fflush()
2765 Flush the file */
SPL_METHOD(SplFileObject,fflush)2766 SPL_METHOD(SplFileObject, fflush)
2767 {
2768 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2769
2770 if(!intern->u.file.stream) {
2771 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized");
2772 return;
2773 }
2774
2775 RETURN_BOOL(!php_stream_flush(intern->u.file.stream));
2776 } /* }}} */
2777
2778 /* {{{ proto int SplFileObject::ftell()
2779 Return current file position */
SPL_METHOD(SplFileObject,ftell)2780 SPL_METHOD(SplFileObject, ftell)
2781 {
2782 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2783 long ret;
2784
2785 if(!intern->u.file.stream) {
2786 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized");
2787 return;
2788 }
2789
2790 ret = php_stream_tell(intern->u.file.stream);
2791
2792 if (ret == -1) {
2793 RETURN_FALSE;
2794 } else {
2795 RETURN_LONG(ret);
2796 }
2797 } /* }}} */
2798
2799 /* {{{ proto int SplFileObject::fseek(int pos [, int whence = SEEK_SET])
2800 Return current file position */
SPL_METHOD(SplFileObject,fseek)2801 SPL_METHOD(SplFileObject, fseek)
2802 {
2803 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2804 long pos, whence = SEEK_SET;
2805
2806 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &pos, &whence) == FAILURE) {
2807 return;
2808 }
2809
2810 if(!intern->u.file.stream) {
2811 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized");
2812 return;
2813 }
2814
2815 spl_filesystem_file_free_line(intern TSRMLS_CC);
2816 RETURN_LONG(php_stream_seek(intern->u.file.stream, pos, whence));
2817 } /* }}} */
2818
2819 /* {{{ proto int SplFileObject::fgetc()
2820 Get a character form the file */
SPL_METHOD(SplFileObject,fgetc)2821 SPL_METHOD(SplFileObject, fgetc)
2822 {
2823 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2824 char buf[2];
2825 int result;
2826
2827 if(!intern->u.file.stream) {
2828 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized");
2829 return;
2830 }
2831
2832 spl_filesystem_file_free_line(intern TSRMLS_CC);
2833
2834 result = php_stream_getc(intern->u.file.stream);
2835
2836 if (result == EOF) {
2837 RETVAL_FALSE;
2838 } else {
2839 if (result == '\n') {
2840 intern->u.file.current_line_num++;
2841 }
2842 buf[0] = result;
2843 buf[1] = '\0';
2844
2845 RETURN_STRINGL(buf, 1, 1);
2846 }
2847 } /* }}} */
2848
2849 /* {{{ proto string SplFileObject::fgetss([string allowable_tags])
2850 Get a line from file pointer and strip HTML tags */
SPL_METHOD(SplFileObject,fgetss)2851 SPL_METHOD(SplFileObject, fgetss)
2852 {
2853 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2854 zval *arg2 = NULL;
2855 MAKE_STD_ZVAL(arg2);
2856
2857 if(!intern->u.file.stream) {
2858 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized");
2859 return;
2860 }
2861
2862 if (intern->u.file.max_line_len > 0) {
2863 ZVAL_LONG(arg2, intern->u.file.max_line_len);
2864 } else {
2865 ZVAL_LONG(arg2, 1024);
2866 }
2867
2868 spl_filesystem_file_free_line(intern TSRMLS_CC);
2869 intern->u.file.current_line_num++;
2870
2871 FileFunctionCall(fgetss, ZEND_NUM_ARGS(), arg2);
2872
2873 zval_ptr_dtor(&arg2);
2874 } /* }}} */
2875
2876 /* {{{ proto int SplFileObject::fpassthru()
2877 Output all remaining data from a file pointer */
SPL_METHOD(SplFileObject,fpassthru)2878 SPL_METHOD(SplFileObject, fpassthru)
2879 {
2880 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2881
2882 if(!intern->u.file.stream) {
2883 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized");
2884 return;
2885 }
2886
2887 RETURN_LONG(php_stream_passthru(intern->u.file.stream));
2888 } /* }}} */
2889
2890 /* {{{ proto bool SplFileObject::fscanf(string format [, string ...])
2891 Implements a mostly ANSI compatible fscanf() */
SPL_METHOD(SplFileObject,fscanf)2892 SPL_METHOD(SplFileObject, fscanf)
2893 {
2894 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2895
2896 if(!intern->u.file.stream) {
2897 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized");
2898 return;
2899 }
2900
2901 spl_filesystem_file_free_line(intern TSRMLS_CC);
2902 intern->u.file.current_line_num++;
2903
2904 FileFunctionCall(fscanf, ZEND_NUM_ARGS(), NULL);
2905 }
2906 /* }}} */
2907
2908 /* {{{ proto mixed SplFileObject::fwrite(string str [, int length])
2909 Binary-safe file write */
SPL_METHOD(SplFileObject,fwrite)2910 SPL_METHOD(SplFileObject, fwrite)
2911 {
2912 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2913 char *str;
2914 int str_len;
2915 long length = 0;
2916
2917 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &str, &str_len, &length) == FAILURE) {
2918 return;
2919 }
2920
2921 if(!intern->u.file.stream) {
2922 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized");
2923 return;
2924 }
2925
2926 if (ZEND_NUM_ARGS() > 1) {
2927 str_len = MAX(0, MIN(length, str_len));
2928 }
2929 if (!str_len) {
2930 RETURN_LONG(0);
2931 }
2932
2933 RETURN_LONG(php_stream_write(intern->u.file.stream, str, str_len));
2934 } /* }}} */
2935
SPL_METHOD(SplFileObject,fread)2936 SPL_METHOD(SplFileObject, fread)
2937 {
2938 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2939 long length = 0;
2940
2941 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &length) == FAILURE) {
2942 return;
2943 }
2944
2945 if(!intern->u.file.stream) {
2946 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized");
2947 return;
2948 }
2949
2950 if (length <= 0) {
2951 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than 0");
2952 RETURN_FALSE;
2953 }
2954 if (length > INT_MAX) {
2955 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be no more than %d", INT_MAX);
2956 RETURN_FALSE;
2957 }
2958
2959 Z_STRVAL_P(return_value) = emalloc(length + 1);
2960 Z_STRLEN_P(return_value) = php_stream_read(intern->u.file.stream, Z_STRVAL_P(return_value), length);
2961
2962 /* needed because recv/read/gzread doesnt put a null at the end*/
2963 Z_STRVAL_P(return_value)[Z_STRLEN_P(return_value)] = 0;
2964 Z_TYPE_P(return_value) = IS_STRING;
2965 }
2966
2967 /* {{{ proto bool SplFileObject::fstat()
2968 Stat() on a filehandle */
2969 FileFunction(fstat)
2970 /* }}} */
2971
2972 /* {{{ proto bool SplFileObject::ftruncate(int size)
2973 Truncate file to 'size' length */
SPL_METHOD(SplFileObject,ftruncate)2974 SPL_METHOD(SplFileObject, ftruncate)
2975 {
2976 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2977 long size;
2978
2979 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &size) == FAILURE) {
2980 return;
2981 }
2982
2983 if(!intern->u.file.stream) {
2984 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized");
2985 return;
2986 }
2987
2988 if (!php_stream_truncate_supported(intern->u.file.stream)) {
2989 zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Can't truncate file %s", intern->file_name);
2990 RETURN_FALSE;
2991 }
2992
2993 RETURN_BOOL(0 == php_stream_truncate_set_size(intern->u.file.stream, size));
2994 } /* }}} */
2995
2996 /* {{{ proto void SplFileObject::seek(int line_pos)
2997 Seek to specified line */
SPL_METHOD(SplFileObject,seek)2998 SPL_METHOD(SplFileObject, seek)
2999 {
3000 spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
3001 long line_pos;
3002
3003 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &line_pos) == FAILURE) {
3004 return;
3005 }
3006 if(!intern->u.file.stream) {
3007 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized");
3008 return;
3009 }
3010
3011 if (line_pos < 0) {
3012 zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Can't seek file %s to negative line %ld", intern->file_name, line_pos);
3013 RETURN_FALSE;
3014 }
3015
3016 spl_filesystem_file_rewind(getThis(), intern TSRMLS_CC);
3017
3018 while(intern->u.file.current_line_num < line_pos) {
3019 if (spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC) == FAILURE) {
3020 break;
3021 }
3022 }
3023 } /* }}} */
3024
3025 /* {{{ Function/Class/Method definitions */
3026 ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object___construct, 0, 0, 1)
3027 ZEND_ARG_INFO(0, file_name)
3028 ZEND_ARG_INFO(0, open_mode)
3029 ZEND_ARG_INFO(0, use_include_path)
3030 ZEND_ARG_INFO(0, context)
3031 ZEND_END_ARG_INFO()
3032
3033 ZEND_BEGIN_ARG_INFO(arginfo_file_object_setFlags, 0)
3034 ZEND_ARG_INFO(0, flags)
3035 ZEND_END_ARG_INFO()
3036
3037 ZEND_BEGIN_ARG_INFO(arginfo_file_object_setMaxLineLen, 0)
3038 ZEND_ARG_INFO(0, max_len)
3039 ZEND_END_ARG_INFO()
3040
3041 ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fgetcsv, 0, 0, 0)
3042 ZEND_ARG_INFO(0, delimiter)
3043 ZEND_ARG_INFO(0, enclosure)
3044 ZEND_ARG_INFO(0, escape)
3045 ZEND_END_ARG_INFO()
3046
3047 ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fputcsv, 0, 0, 1)
3048 ZEND_ARG_INFO(0, fields)
3049 ZEND_ARG_INFO(0, delimiter)
3050 ZEND_ARG_INFO(0, enclosure)
3051 ZEND_ARG_INFO(0, escape)
3052 ZEND_END_ARG_INFO()
3053
3054 ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_flock, 0, 0, 1)
3055 ZEND_ARG_INFO(0, operation)
3056 ZEND_ARG_INFO(1, wouldblock)
3057 ZEND_END_ARG_INFO()
3058
3059 ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fseek, 0, 0, 1)
3060 ZEND_ARG_INFO(0, pos)
3061 ZEND_ARG_INFO(0, whence)
3062 ZEND_END_ARG_INFO()
3063
3064 ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fgetss, 0, 0, 0)
3065 ZEND_ARG_INFO(0, allowable_tags)
3066 ZEND_END_ARG_INFO()
3067
3068 ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fscanf, 0, 0, 1)
3069 ZEND_ARG_INFO(0, format)
3070 ZEND_ARG_VARIADIC_INFO(1, vars)
3071 ZEND_END_ARG_INFO()
3072
3073 ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fwrite, 0, 0, 1)
3074 ZEND_ARG_INFO(0, str)
3075 ZEND_ARG_INFO(0, length)
3076 ZEND_END_ARG_INFO()
3077
3078 ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fread, 0, 0, 1)
3079 ZEND_ARG_INFO(0, length)
3080 ZEND_END_ARG_INFO()
3081
3082 ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_ftruncate, 0, 0, 1)
3083 ZEND_ARG_INFO(0, size)
3084 ZEND_END_ARG_INFO()
3085
3086 ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_seek, 0, 0, 1)
3087 ZEND_ARG_INFO(0, line_pos)
3088 ZEND_END_ARG_INFO()
3089
3090 static const zend_function_entry spl_SplFileObject_functions[] = {
3091 SPL_ME(SplFileObject, __construct, arginfo_file_object___construct, ZEND_ACC_PUBLIC)
3092 SPL_ME(SplFileObject, rewind, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
3093 SPL_ME(SplFileObject, eof, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
3094 SPL_ME(SplFileObject, valid, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
3095 SPL_ME(SplFileObject, fgets, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
3096 SPL_ME(SplFileObject, fgetcsv, arginfo_file_object_fgetcsv, ZEND_ACC_PUBLIC)
3097 SPL_ME(SplFileObject, fputcsv, arginfo_file_object_fputcsv, ZEND_ACC_PUBLIC)
3098 SPL_ME(SplFileObject, setCsvControl, arginfo_file_object_fgetcsv, ZEND_ACC_PUBLIC)
3099 SPL_ME(SplFileObject, getCsvControl, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
3100 SPL_ME(SplFileObject, flock, arginfo_file_object_flock, ZEND_ACC_PUBLIC)
3101 SPL_ME(SplFileObject, fflush, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
3102 SPL_ME(SplFileObject, ftell, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
3103 SPL_ME(SplFileObject, fseek, arginfo_file_object_fseek, ZEND_ACC_PUBLIC)
3104 SPL_ME(SplFileObject, fgetc, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
3105 SPL_ME(SplFileObject, fpassthru, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
3106 SPL_ME(SplFileObject, fgetss, arginfo_file_object_fgetss, ZEND_ACC_PUBLIC)
3107 SPL_ME(SplFileObject, fscanf, arginfo_file_object_fscanf, ZEND_ACC_PUBLIC)
3108 SPL_ME(SplFileObject, fwrite, arginfo_file_object_fwrite, ZEND_ACC_PUBLIC)
3109 SPL_ME(SplFileObject, fread, arginfo_file_object_fread, ZEND_ACC_PUBLIC)
3110 SPL_ME(SplFileObject, fstat, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
3111 SPL_ME(SplFileObject, ftruncate, arginfo_file_object_ftruncate, ZEND_ACC_PUBLIC)
3112 SPL_ME(SplFileObject, current, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
3113 SPL_ME(SplFileObject, key, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
3114 SPL_ME(SplFileObject, next, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
3115 SPL_ME(SplFileObject, setFlags, arginfo_file_object_setFlags, ZEND_ACC_PUBLIC)
3116 SPL_ME(SplFileObject, getFlags, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
3117 SPL_ME(SplFileObject, setMaxLineLen, arginfo_file_object_setMaxLineLen, ZEND_ACC_PUBLIC)
3118 SPL_ME(SplFileObject, getMaxLineLen, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
3119 SPL_ME(SplFileObject, hasChildren, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
3120 SPL_ME(SplFileObject, getChildren, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
3121 SPL_ME(SplFileObject, seek, arginfo_file_object_seek, ZEND_ACC_PUBLIC)
3122 /* mappings */
3123 SPL_MA(SplFileObject, getCurrentLine, SplFileObject, fgets, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
3124 SPL_MA(SplFileObject, __toString, SplFileObject, current, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
3125 PHP_FE_END
3126 };
3127
3128 ZEND_BEGIN_ARG_INFO_EX(arginfo_temp_file_object___construct, 0, 0, 0)
3129 ZEND_ARG_INFO(0, max_memory)
3130 ZEND_END_ARG_INFO()
3131
3132 static const zend_function_entry spl_SplTempFileObject_functions[] = {
3133 SPL_ME(SplTempFileObject, __construct, arginfo_temp_file_object___construct, ZEND_ACC_PUBLIC)
3134 PHP_FE_END
3135 };
3136 /* }}} */
3137
3138 /* {{{ PHP_MINIT_FUNCTION(spl_directory)
3139 */
PHP_MINIT_FUNCTION(spl_directory)3140 PHP_MINIT_FUNCTION(spl_directory)
3141 {
3142 REGISTER_SPL_STD_CLASS_EX(SplFileInfo, spl_filesystem_object_new, spl_SplFileInfo_functions);
3143 memcpy(&spl_filesystem_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
3144 spl_filesystem_object_handlers.clone_obj = spl_filesystem_object_clone;
3145 spl_filesystem_object_handlers.cast_object = spl_filesystem_object_cast;
3146 spl_filesystem_object_handlers.get_debug_info = spl_filesystem_object_get_debug_info;
3147 spl_ce_SplFileInfo->serialize = zend_class_serialize_deny;
3148 spl_ce_SplFileInfo->unserialize = zend_class_unserialize_deny;
3149
3150 REGISTER_SPL_SUB_CLASS_EX(DirectoryIterator, SplFileInfo, spl_filesystem_object_new, spl_DirectoryIterator_functions);
3151 zend_class_implements(spl_ce_DirectoryIterator TSRMLS_CC, 1, zend_ce_iterator);
3152 REGISTER_SPL_IMPLEMENTS(DirectoryIterator, SeekableIterator);
3153
3154 spl_ce_DirectoryIterator->get_iterator = spl_filesystem_dir_get_iterator;
3155
3156 REGISTER_SPL_SUB_CLASS_EX(FilesystemIterator, DirectoryIterator, spl_filesystem_object_new, spl_FilesystemIterator_functions);
3157
3158 REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "CURRENT_MODE_MASK", SPL_FILE_DIR_CURRENT_MODE_MASK);
3159 REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "CURRENT_AS_PATHNAME", SPL_FILE_DIR_CURRENT_AS_PATHNAME);
3160 REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "CURRENT_AS_FILEINFO", SPL_FILE_DIR_CURRENT_AS_FILEINFO);
3161 REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "CURRENT_AS_SELF", SPL_FILE_DIR_CURRENT_AS_SELF);
3162 REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "KEY_MODE_MASK", SPL_FILE_DIR_KEY_MODE_MASK);
3163 REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "KEY_AS_PATHNAME", SPL_FILE_DIR_KEY_AS_PATHNAME);
3164 REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "FOLLOW_SYMLINKS", SPL_FILE_DIR_FOLLOW_SYMLINKS);
3165 REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "KEY_AS_FILENAME", SPL_FILE_DIR_KEY_AS_FILENAME);
3166 REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "NEW_CURRENT_AND_KEY", SPL_FILE_DIR_KEY_AS_FILENAME|SPL_FILE_DIR_CURRENT_AS_FILEINFO);
3167 REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "OTHER_MODE_MASK", SPL_FILE_DIR_OTHERS_MASK);
3168 REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "SKIP_DOTS", SPL_FILE_DIR_SKIPDOTS);
3169 REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "UNIX_PATHS", SPL_FILE_DIR_UNIXPATHS);
3170
3171 spl_ce_FilesystemIterator->get_iterator = spl_filesystem_tree_get_iterator;
3172
3173 REGISTER_SPL_SUB_CLASS_EX(RecursiveDirectoryIterator, FilesystemIterator, spl_filesystem_object_new, spl_RecursiveDirectoryIterator_functions);
3174 REGISTER_SPL_IMPLEMENTS(RecursiveDirectoryIterator, RecursiveIterator);
3175
3176 memcpy(&spl_filesystem_object_check_handlers, &spl_filesystem_object_handlers, sizeof(zend_object_handlers));
3177 spl_filesystem_object_check_handlers.get_method = spl_filesystem_object_get_method_check;
3178
3179 #ifdef HAVE_GLOB
3180 REGISTER_SPL_SUB_CLASS_EX(GlobIterator, FilesystemIterator, spl_filesystem_object_new_check, spl_GlobIterator_functions);
3181 REGISTER_SPL_IMPLEMENTS(GlobIterator, Countable);
3182 #endif
3183
3184 REGISTER_SPL_SUB_CLASS_EX(SplFileObject, SplFileInfo, spl_filesystem_object_new_check, spl_SplFileObject_functions);
3185 REGISTER_SPL_IMPLEMENTS(SplFileObject, RecursiveIterator);
3186 REGISTER_SPL_IMPLEMENTS(SplFileObject, SeekableIterator);
3187
3188 REGISTER_SPL_CLASS_CONST_LONG(SplFileObject, "DROP_NEW_LINE", SPL_FILE_OBJECT_DROP_NEW_LINE);
3189 REGISTER_SPL_CLASS_CONST_LONG(SplFileObject, "READ_AHEAD", SPL_FILE_OBJECT_READ_AHEAD);
3190 REGISTER_SPL_CLASS_CONST_LONG(SplFileObject, "SKIP_EMPTY", SPL_FILE_OBJECT_SKIP_EMPTY);
3191 REGISTER_SPL_CLASS_CONST_LONG(SplFileObject, "READ_CSV", SPL_FILE_OBJECT_READ_CSV);
3192
3193 REGISTER_SPL_SUB_CLASS_EX(SplTempFileObject, SplFileObject, spl_filesystem_object_new_check, spl_SplTempFileObject_functions);
3194 return SUCCESS;
3195 }
3196 /* }}} */
3197
3198 /*
3199 * Local variables:
3200 * tab-width: 4
3201 * c-basic-offset: 4
3202 * End:
3203 * vim600: noet sw=4 ts=4 fdm=marker
3204 * vim<600: noet sw=4 ts=4
3205 */
3206