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