LTP GCOV extension - code coverage report
Current view: directory - ext/spl - spl_directory.c
Test: PHP Code Coverage
Date: 2007-04-10 Instrumented lines: 951
Code covered: 2.9 % Executed lines: 28
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 5                                                        |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1997-2007 The PHP Group                                |
       6                 :    +----------------------------------------------------------------------+
       7                 :    | This source file is subject to version 3.01 of the PHP license,      |
       8                 :    | that is bundled with this package in the file LICENSE, and is        |
       9                 :    | available through the world-wide-web at the following url:           |
      10                 :    | http://www.php.net/license/3_01.txt                                  |
      11                 :    | If you did not receive a copy of the PHP license and are unable to   |
      12                 :    | obtain it through the world-wide-web, please send a note to          |
      13                 :    | license@php.net so we can mail you a copy immediately.               |
      14                 :    +----------------------------------------------------------------------+
      15                 :    | Author: Marcus Boerger <helly@php.net>                               |
      16                 :    +----------------------------------------------------------------------+
      17                 :  */
      18                 : 
      19                 : /* $Id: spl_directory.c,v 1.45.2.27.2.20 2007/04/09 15:34:55 dmitry Exp $ */
      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                 : /* declare the class handlers */
      48                 : static zend_object_handlers spl_filesystem_object_handlers;
      49                 : 
      50                 : /* decalre the class entry */
      51                 : PHPAPI zend_class_entry *spl_ce_SplFileInfo;
      52                 : PHPAPI zend_class_entry *spl_ce_DirectoryIterator;
      53                 : PHPAPI zend_class_entry *spl_ce_RecursiveDirectoryIterator;
      54                 : PHPAPI zend_class_entry *spl_ce_SplFileObject;
      55                 : PHPAPI zend_class_entry *spl_ce_SplTempFileObject;
      56                 : 
      57                 : static void spl_filesystem_file_free_line(spl_filesystem_object *intern TSRMLS_DC) /* {{{ */
      58               0 : {
      59               0 :         if (intern->u.file.current_line) {
      60               0 :                 efree(intern->u.file.current_line);
      61               0 :                 intern->u.file.current_line = NULL;
      62                 :         }
      63               0 :         if (intern->u.file.current_zval) {
      64               0 :                 zval_ptr_dtor(&intern->u.file.current_zval);
      65               0 :                 intern->u.file.current_zval = NULL;
      66                 :         }
      67               0 : } /* }}} */
      68                 : 
      69                 : static void spl_filesystem_object_free_storage(void *object TSRMLS_DC) /* {{{ */
      70               0 : {
      71               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)object;
      72                 : 
      73               0 :         if (intern->oth_handler && intern->oth_handler->dtor) {
      74               0 :                 intern->oth_handler->dtor(intern TSRMLS_CC);
      75                 :         }
      76                 :         
      77               0 :         zend_object_std_dtor(&intern->std TSRMLS_CC);
      78                 :         
      79               0 :         if (intern->path) {
      80               0 :                 efree(intern->path);
      81                 :         }
      82               0 :         if (intern->file_name) {
      83               0 :                 efree(intern->file_name);
      84                 :         }
      85               0 :         switch(intern->type) {
      86                 :         case SPL_FS_INFO:
      87               0 :                 break;
      88                 :         case SPL_FS_DIR:
      89               0 :                 if (intern->u.dir.dirp) {
      90               0 :                         php_stream_close(intern->u.dir.dirp);
      91                 :                 }
      92               0 :                 if (intern->u.dir.sub_path) {
      93               0 :                         efree(intern->u.dir.sub_path);
      94                 :                 }               
      95               0 :                 break;
      96                 :         case SPL_FS_FILE:
      97               0 :                 if (intern->u.file.stream) {
      98               0 :                         if (intern->u.file.zcontext) {
      99                 : /*                              zend_list_delref(Z_RESVAL_P(intern->zcontext));*/
     100                 :                         }
     101               0 :                         if (!intern->u.file.stream->is_persistent) {
     102               0 :                                 php_stream_free(intern->u.file.stream, PHP_STREAM_FREE_CLOSE);
     103                 :                         } else {
     104               0 :                                 php_stream_free(intern->u.file.stream, PHP_STREAM_FREE_CLOSE_PERSISTENT);
     105                 :                         }
     106               0 :                         if (intern->u.file.open_mode) {
     107               0 :                                 efree(intern->u.file.open_mode);
     108                 :                         }
     109                 :                 }
     110               0 :                 spl_filesystem_file_free_line(intern TSRMLS_CC);
     111                 :                 break;
     112                 :         }
     113               0 :         efree(object);
     114               0 : } /* }}} */
     115                 : 
     116                 : /* {{{ spl_ce_dir_object_new */
     117                 : /* creates the object by 
     118                 :    - allocating memory 
     119                 :    - initializing the object members
     120                 :    - storing the object
     121                 :    - setting it's handlers
     122                 : 
     123                 :    called from 
     124                 :    - clone
     125                 :    - new
     126                 :  */
     127                 : static zend_object_value spl_filesystem_object_new_ex(zend_class_entry *class_type, spl_filesystem_object **obj TSRMLS_DC)
     128               0 : {
     129                 :         zend_object_value retval;
     130                 :         spl_filesystem_object *intern;
     131                 :         zval *tmp;
     132                 : 
     133               0 :         intern = emalloc(sizeof(spl_filesystem_object));
     134               0 :         memset(intern, 0, sizeof(spl_filesystem_object));
     135                 :         /* intern->type = SPL_FS_INFO; done by set 0 */
     136               0 :         intern->file_class = spl_ce_SplFileObject;
     137               0 :         intern->info_class = spl_ce_SplFileInfo;
     138               0 :         if (obj) *obj = intern;
     139                 : 
     140               0 :         zend_object_std_init(&intern->std, class_type TSRMLS_CC);
     141               0 :         zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
     142                 : 
     143               0 :         retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) spl_filesystem_object_free_storage, NULL TSRMLS_CC);
     144               0 :         retval.handlers = &spl_filesystem_object_handlers;
     145               0 :         return retval;
     146                 : }
     147                 : /* }}} */
     148                 : 
     149                 : /* {{{ spl_filesystem_object_new */
     150                 : /* See spl_filesystem_object_new_ex */
     151                 : static zend_object_value spl_filesystem_object_new(zend_class_entry *class_type TSRMLS_DC)
     152               0 : {
     153               0 :         return spl_filesystem_object_new_ex(class_type, NULL TSRMLS_CC);
     154                 : }
     155                 : /* }}} */
     156                 : 
     157                 : static inline void spl_filesystem_object_get_file_name(spl_filesystem_object *intern TSRMLS_DC) /* {{{ */
     158               0 : {
     159               0 :         if (!intern->file_name) {
     160               0 :                 switch (intern->type) {
     161                 :                 case SPL_FS_INFO:
     162                 :                 case SPL_FS_FILE:
     163               0 :                         php_error_docref(NULL TSRMLS_CC, E_ERROR, "Object not initialized");
     164               0 :                         break;
     165                 :                 case SPL_FS_DIR:
     166               0 :                         intern->file_name_len = spprintf(&intern->file_name, 0, "%s%c%s", intern->path, DEFAULT_SLASH, intern->u.dir.entry.d_name);
     167                 :                         break;
     168                 :                 }
     169                 :         }
     170               0 : } /* }}} */
     171                 : 
     172                 : /* {{{ spl_filesystem_dir_open */
     173                 : /* open a directory resource */
     174                 : static void spl_filesystem_dir_open(spl_filesystem_object* intern, char *path TSRMLS_DC)
     175               0 : {
     176               0 :         intern->type = SPL_FS_DIR;
     177               0 :         intern->path_len = strlen(path);
     178               0 :         intern->u.dir.dirp = php_stream_opendir(path, ENFORCE_SAFE_MODE|REPORT_ERRORS, NULL);
     179                 : 
     180               0 :         if (intern->path_len && (path[intern->path_len-1] == '/'
     181                 : #if defined(PHP_WIN32) || defined(NETWARE)
     182                 :                 || path[intern->path_len-1] == '\\'
     183                 : #endif
     184                 :         )) {
     185               0 :                 intern->path = estrndup(path, --intern->path_len);
     186                 :         } else {
     187               0 :                 intern->path = estrndup(path, intern->path_len);
     188                 :         }
     189               0 :         intern->u.dir.index = 0;
     190                 : 
     191               0 :         if (intern->u.dir.dirp == NULL) {
     192                 :                 /* throw exception: should've been already happened */
     193               0 :                 intern->u.dir.entry.d_name[0] = '\0';
     194                 :         } else {
     195               0 :                 if (!php_stream_readdir(intern->u.dir.dirp, &intern->u.dir.entry)) {
     196               0 :                         intern->u.dir.entry.d_name[0] = '\0';
     197                 :                 }
     198                 :         }
     199               0 : }
     200                 : /* }}} */
     201                 : 
     202                 : static int spl_filesystem_file_open(spl_filesystem_object *intern, int use_include_path, int silent TSRMLS_DC) /* {{{ */
     203               0 : {
     204               0 :         intern->type = SPL_FS_FILE;
     205               0 :         intern->u.file.context = php_stream_context_from_zval(intern->u.file.zcontext, 0);
     206               0 :         intern->u.file.stream = php_stream_open_wrapper_ex(intern->file_name, intern->u.file.open_mode, (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, intern->u.file.context);
     207                 : 
     208               0 :         if (!intern->file_name_len || !intern->u.file.stream) {
     209               0 :                 if (!EG(exception)) {
     210               0 :                         zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot open file '%s'", intern->file_name_len ? intern->file_name : "");
     211                 :                 }
     212               0 :                 intern->file_name = NULL; /* until here it is not a copy */
     213               0 :                 intern->u.file.open_mode = NULL;
     214               0 :                 return FAILURE;
     215                 :         }
     216                 : 
     217               0 :         if (intern->u.file.zcontext) {
     218               0 :                 zend_list_addref(Z_RESVAL_P(intern->u.file.zcontext));
     219                 :         }
     220                 : 
     221               0 :         if (intern->file_name[intern->file_name_len-1] == '/'
     222                 : #if defined(PHP_WIN32) || defined(NETWARE)
     223                 :           ||intern->file_name[intern->file_name_len-1] == '\\'
     224                 : #endif
     225                 :         ) {
     226               0 :                 intern->file_name_len--;
     227                 :         }
     228                 : 
     229               0 :         intern->file_name = estrndup(intern->file_name, intern->file_name_len);
     230               0 :         intern->u.file.open_mode = estrndup(intern->u.file.open_mode, intern->u.file.open_mode_len);
     231                 : 
     232                 :         /* avoid reference counting in debug mode, thus do it manually */
     233               0 :         ZVAL_RESOURCE(&intern->u.file.zresource, php_stream_get_resource_id(intern->u.file.stream));
     234               0 :         intern->u.file.zresource.refcount = 1;
     235                 :         
     236               0 :         intern->u.file.delimiter = ',';
     237               0 :         intern->u.file.enclosure = '"';
     238                 : 
     239               0 :         zend_hash_find(&intern->std.ce->function_table, "getcurrentline", sizeof("getcurrentline"), (void **) &intern->u.file.func_getCurr);
     240                 : 
     241               0 :         return SUCCESS;
     242                 : } /* }}} */
     243                 : 
     244                 : /* {{{ spl_filesystem_object_clone */
     245                 : /* Local zend_object_value creation (on stack)
     246                 :    Load the 'other' object 
     247                 :    Create a new empty object (See spl_filesystem_object_new_ex)
     248                 :    Open the directory
     249                 :    Clone other members (properties)
     250                 :  */
     251                 : static zend_object_value spl_filesystem_object_clone(zval *zobject TSRMLS_DC)
     252               0 : {
     253                 :         zend_object_value new_obj_val;
     254                 :         zend_object *old_object;
     255                 :         zend_object *new_object;
     256               0 :         zend_object_handle handle = Z_OBJ_HANDLE_P(zobject);
     257                 :         spl_filesystem_object *intern;
     258                 :         spl_filesystem_object *source;
     259                 : 
     260               0 :         old_object = zend_objects_get_address(zobject TSRMLS_CC);
     261               0 :         source = (spl_filesystem_object*)old_object;
     262                 : 
     263               0 :         new_obj_val = spl_filesystem_object_new_ex(old_object->ce, &intern TSRMLS_CC);
     264               0 :         new_object = &intern->std;
     265                 : 
     266               0 :         switch (source->type) {
     267                 :         case SPL_FS_INFO:
     268               0 :                 intern->path_len = source->path_len;
     269               0 :                 intern->path = estrndup(source->path, source->path_len);
     270               0 :                 intern->file_name_len = source->file_name_len;
     271               0 :                 intern->file_name = estrndup(source->file_name, intern->file_name_len);
     272               0 :                 break;
     273                 :         case SPL_FS_DIR:
     274               0 :                 spl_filesystem_dir_open(intern, source->path TSRMLS_CC);
     275               0 :                 break;
     276                 :         case SPL_FS_FILE:
     277               0 :                 php_error_docref(NULL TSRMLS_CC, E_ERROR, "An object of class %s cannot be cloned", old_object->ce->name);
     278                 :                 break;
     279                 :         }
     280                 :         
     281               0 :         intern->file_class = source->file_class;
     282               0 :         intern->info_class = source->info_class;
     283               0 :         intern->flags = source->flags;
     284               0 :         intern->oth = source->oth;
     285               0 :         intern->oth_handler = source->oth_handler;
     286                 : 
     287               0 :         zend_objects_clone_members(new_object, new_obj_val, old_object, handle TSRMLS_CC);
     288                 : 
     289               0 :         if (intern->oth_handler && intern->oth_handler->clone) {
     290               0 :                 intern->oth_handler->clone(source, intern TSRMLS_CC);
     291                 :         }
     292                 : 
     293               0 :         return new_obj_val;
     294                 : }
     295                 : /* }}} */
     296                 : 
     297                 : void spl_filesystem_info_set_filename(spl_filesystem_object *intern, char *path, int len, int use_copy TSRMLS_DC) /* {{{ */
     298               0 : {
     299                 :         char *p1, *p2;
     300                 : 
     301               0 :         intern->file_name = use_copy ? estrndup(path, len) : path;
     302               0 :         intern->file_name_len = len;
     303                 : 
     304               0 :         p1 = strrchr(path, '/');
     305                 : #if defined(PHP_WIN32) || defined(NETWARE)
     306                 :         p2 = strrchr(path, '\\');
     307                 : #else
     308               0 :         p2 = 0;
     309                 : #endif
     310               0 :         if (p1 || p2) {
     311               0 :                 intern->path_len = (p1 > p2 ? p1 : p2) - path;
     312                 :         } else {
     313               0 :                 intern->path_len = 0;
     314                 :         }
     315               0 :         intern->path = estrndup(path, intern->path_len);
     316               0 : } /* }}} */
     317                 : 
     318                 : static spl_filesystem_object * spl_filesystem_object_create_info(spl_filesystem_object *source, char *file_path, int file_path_len, int use_copy, zend_class_entry *ce, zval *return_value TSRMLS_DC) /* {{{ */
     319               0 : {
     320                 :         spl_filesystem_object *intern;
     321                 :         zval *arg1;
     322                 : 
     323               0 :         if (!file_path || !file_path_len) {
     324                 : #if defined(PHP_WIN32)
     325                 :                 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot create SplFileInfo for empty path");
     326                 :                 if (file_path && !use_copy)
     327                 :                 {
     328                 :                         efree(file_path);
     329                 :                 }
     330                 :                 return NULL;
     331                 : #else
     332               0 :                 if (file_path && !use_copy) {
     333               0 :                         efree(file_path);
     334                 :                 }
     335               0 :                 use_copy = 1;
     336               0 :                 file_path_len = 1;
     337               0 :                 file_path = "/";
     338                 : #endif
     339                 :         }
     340                 : 
     341               0 :         php_set_error_handling(EH_THROW, spl_ce_RuntimeException TSRMLS_CC);
     342                 : 
     343               0 :         ce = ce ? ce : source->info_class;
     344               0 :         return_value->value.obj = spl_filesystem_object_new_ex(ce, &intern TSRMLS_CC);
     345               0 :         Z_TYPE_P(return_value) = IS_OBJECT;
     346                 : 
     347               0 :         if (ce->constructor->common.scope != spl_ce_SplFileInfo) {
     348               0 :                 MAKE_STD_ZVAL(arg1);
     349               0 :                 ZVAL_STRINGL(arg1, file_path, file_path_len, use_copy);
     350               0 :                 zend_call_method_with_1_params(&return_value, ce, &ce->constructor, "__construct", NULL, arg1);
     351               0 :                 zval_ptr_dtor(&arg1);
     352                 :         } else {
     353               0 :                 spl_filesystem_info_set_filename(intern, file_path, file_path_len, use_copy TSRMLS_CC);
     354                 :         }
     355                 :         
     356               0 :         php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
     357                 :         
     358               0 :         return intern;
     359                 : } /* }}} */
     360                 : 
     361                 : static spl_filesystem_object * spl_filesystem_object_create_type(int ht, spl_filesystem_object *source, int type, zend_class_entry *ce, zval *return_value TSRMLS_DC) /* {{{ */
     362               0 : {
     363                 :         spl_filesystem_object *intern;
     364               0 :         zend_bool use_include_path = 0;
     365                 :         zval *arg1, *arg2;
     366                 : 
     367               0 :         php_set_error_handling(EH_THROW, spl_ce_RuntimeException TSRMLS_CC);
     368                 : 
     369               0 :         switch (source->type) {
     370                 :         case SPL_FS_INFO:
     371                 :         case SPL_FS_FILE:
     372               0 :                 break;
     373                 :         case SPL_FS_DIR:
     374               0 :                 if (!source->u.dir.entry.d_name[0]) {
     375               0 :                         zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Could not open file");
     376               0 :                         php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
     377               0 :                         return NULL;
     378                 :                 }
     379                 :         }
     380                 : 
     381               0 :         switch (type) {
     382                 :         case SPL_FS_INFO:
     383               0 :                 ce = ce ? ce : source->info_class;
     384               0 :                 return_value->value.obj = spl_filesystem_object_new_ex(ce, &intern TSRMLS_CC);
     385               0 :                 Z_TYPE_P(return_value) = IS_OBJECT;
     386                 : 
     387               0 :                 spl_filesystem_object_get_file_name(source TSRMLS_CC);
     388               0 :                 if (ce->constructor->common.scope != spl_ce_SplFileInfo) {
     389               0 :                         MAKE_STD_ZVAL(arg1);
     390               0 :                         ZVAL_STRINGL(arg1, source->file_name, source->file_name_len, 1);
     391               0 :                         zend_call_method_with_1_params(&return_value, ce, &ce->constructor, "__construct", NULL, arg1);
     392               0 :                         zval_ptr_dtor(&arg1);
     393                 :                 } else {
     394               0 :                         intern->file_name = estrndup(source->file_name, source->file_name_len);
     395               0 :                         intern->file_name_len = source->file_name_len;
     396               0 :                         intern->path = estrndup(source->path, source->path_len);
     397               0 :                         intern->path_len = source->path_len;
     398                 :                 }
     399               0 :                 break;
     400                 :         case SPL_FS_FILE:
     401               0 :                 ce = ce ? ce : source->file_class;
     402               0 :                 return_value->value.obj = spl_filesystem_object_new_ex(ce, &intern TSRMLS_CC);
     403               0 :                 Z_TYPE_P(return_value) = IS_OBJECT;
     404                 :         
     405               0 :                 spl_filesystem_object_get_file_name(source TSRMLS_CC);
     406                 : 
     407               0 :                 if (ce->constructor->common.scope != spl_ce_SplFileObject) {
     408               0 :                         MAKE_STD_ZVAL(arg1);
     409               0 :                         MAKE_STD_ZVAL(arg2);
     410               0 :                         ZVAL_STRINGL(arg1, source->file_name, source->file_name_len, 1);
     411               0 :                         ZVAL_STRINGL(arg2, "r", 1, 1);
     412               0 :                         zend_call_method_with_2_params(&return_value, ce, &ce->constructor, "__construct", NULL, arg1, arg2);
     413               0 :                         zval_ptr_dtor(&arg1);
     414               0 :                         zval_ptr_dtor(&arg2);
     415                 :                 } else {
     416               0 :                         intern->file_name = source->file_name;
     417               0 :                         intern->file_name_len = source->file_name_len;
     418               0 :                         intern->path = estrndup(source->path, source->path_len);
     419               0 :                         intern->path_len = source->path_len;
     420                 :                 
     421               0 :                         intern->u.file.open_mode = "r";
     422               0 :                         intern->u.file.open_mode_len = 1;
     423                 :                 
     424               0 :                         if (ht && zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sbr", 
     425                 :                                         &intern->u.file.open_mode, &intern->u.file.open_mode_len, 
     426                 :                                         &use_include_path, &intern->u.file.zcontext) == FAILURE) {
     427               0 :                                 php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
     428               0 :                                 intern->u.file.open_mode = NULL;
     429               0 :                                 zval_dtor(return_value);
     430               0 :                                 Z_TYPE_P(return_value) = IS_NULL;
     431               0 :                                 return NULL;
     432                 :                         }
     433                 :                 
     434               0 :                         if (spl_filesystem_file_open(intern, use_include_path, 0 TSRMLS_CC) == FAILURE) {
     435               0 :                                 php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
     436               0 :                                 zval_dtor(return_value);
     437               0 :                                 Z_TYPE_P(return_value) = IS_NULL;
     438               0 :                                 return NULL;
     439                 :                         }
     440                 :                 }
     441               0 :                 break;
     442                 :         case SPL_FS_DIR:        
     443               0 :                 php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
     444               0 :                 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Operation not supported");
     445               0 :                 return NULL;
     446                 :         }
     447               0 :         php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
     448               0 :         return NULL;
     449                 : } /* }}} */
     450                 : 
     451                 : static inline int spl_filesystem_is_dot(const char * d_name) /* {{{ */
     452               0 : {
     453               0 :         return !strcmp(d_name, ".") || !strcmp(d_name, "..");
     454                 : }
     455                 : /* }}} */
     456                 : 
     457                 : static int spl_filesystem_is_invalid_or_dot(const char * d_name) /* {{{ */
     458               0 : {
     459               0 :         return d_name[0] == '\0' || spl_filesystem_is_dot(d_name);
     460                 : }
     461                 : /* }}} */
     462                 : 
     463                 : /* {{{ proto void DirectoryIterator::__construct(string path)
     464                 :  Cronstructs a new dir iterator from a path. */
     465                 : SPL_METHOD(DirectoryIterator, __construct)
     466               0 : {
     467                 :         spl_filesystem_object *intern;
     468                 :         char *path;
     469                 :         int len;
     470                 : 
     471               0 :         php_set_error_handling(EH_THROW, spl_ce_RuntimeException TSRMLS_CC);
     472                 : 
     473               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &path, &len) == FAILURE) {
     474               0 :                 php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
     475               0 :                 return;
     476                 :         }
     477                 : 
     478               0 :         if (!len) {
     479               0 :                 php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
     480               0 :                 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Directory name must not be empty.");
     481               0 :                 return;
     482                 :         }
     483                 : 
     484               0 :         intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     485               0 :         spl_filesystem_dir_open(intern, path TSRMLS_CC);
     486               0 :         intern->u.dir.is_recursive = instanceof_function(intern->std.ce, spl_ce_RecursiveDirectoryIterator TSRMLS_CC) ? 1 : 0;
     487               0 :         intern->flags = 0;
     488                 : 
     489               0 :         php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
     490                 : }
     491                 : /* }}} */
     492                 : 
     493                 : /* {{{ proto void DirectoryIterator::rewind()
     494                 :    Rewind dir back to the start */
     495                 : SPL_METHOD(DirectoryIterator, rewind)
     496               0 : {
     497               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     498                 : 
     499               0 :         intern->u.dir.index = 0;
     500               0 :         if (intern->u.dir.dirp) {
     501               0 :                 php_stream_rewinddir(intern->u.dir.dirp);
     502                 :         }
     503               0 :         if (!intern->u.dir.dirp || !php_stream_readdir(intern->u.dir.dirp, &intern->u.dir.entry)) {
     504               0 :                 intern->u.dir.entry.d_name[0] = '\0';
     505                 :         }
     506               0 : }
     507                 : /* }}} */
     508                 : 
     509                 : /* {{{ proto string DirectoryIterator::key()
     510                 :    Return current dir entry */
     511                 : SPL_METHOD(DirectoryIterator, key)
     512               0 : {
     513               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     514                 : 
     515               0 :         if (intern->u.dir.dirp) {
     516               0 :                 RETURN_LONG(intern->u.dir.index);
     517                 :         } else {
     518               0 :                 RETURN_FALSE;
     519                 :         }
     520                 : }
     521                 : /* }}} */
     522                 : 
     523                 : /* {{{ proto DirectoryIterator DirectoryIterator::current()
     524                 :    Return this (needed for Iterator interface) */
     525                 : SPL_METHOD(DirectoryIterator, current)
     526               0 : {
     527               0 :         RETURN_ZVAL(getThis(), 1, 0);
     528                 : }
     529                 : /* }}} */
     530                 : 
     531                 : /* {{{ proto void DirectoryIterator::next()
     532                 :    Move to next entry */
     533                 : SPL_METHOD(DirectoryIterator, next)
     534               0 : {
     535               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     536                 : 
     537               0 :         intern->u.dir.index++;
     538               0 :         if (!intern->u.dir.dirp || !php_stream_readdir(intern->u.dir.dirp, &intern->u.dir.entry)) {
     539               0 :                 intern->u.dir.entry.d_name[0] = '\0';
     540                 :         }
     541               0 :         if (intern->file_name) {
     542               0 :                 efree(intern->file_name);
     543               0 :                 intern->file_name = NULL;
     544                 :         }
     545               0 : }
     546                 : /* }}} */
     547                 : 
     548                 : /* {{{ proto string DirectoryIterator::valid()
     549                 :    Check whether dir contains more entries */
     550                 : SPL_METHOD(DirectoryIterator, valid)
     551               0 : {
     552               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     553                 : 
     554               0 :         RETURN_BOOL(intern->u.dir.entry.d_name[0] != '\0');
     555                 : }
     556                 : /* }}} */
     557                 : 
     558                 : /* {{{ proto string SplFileInfo::getPath()
     559                 :    Return the path */
     560                 : SPL_METHOD(SplFileInfo, getPath)
     561               0 : {
     562               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     563                 : 
     564               0 :         RETURN_STRING(intern->path, 1);
     565                 : }
     566                 : /* }}} */
     567                 : 
     568                 : /* {{{ proto string SplFileInfo::getFilename()
     569                 :    Return filename only */
     570                 : SPL_METHOD(SplFileInfo, getFilename)
     571               0 : {
     572               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     573                 : 
     574               0 :         if (intern->path_len && intern->path_len < intern->file_name_len) {
     575               0 :                 RETURN_STRINGL(intern->file_name + intern->path_len + 1, intern->file_name_len - (intern->path_len + 1), 1);
     576                 :         } else {
     577               0 :                 RETURN_STRINGL(intern->file_name, intern->file_name_len, 1);
     578                 :         }
     579                 : }
     580                 : /* }}} */
     581                 : 
     582                 : /* {{{ proto string DirectoryIterator::getFilename()
     583                 :    Return filename of current dir entry */
     584                 : SPL_METHOD(DirectoryIterator, getFilename)
     585               0 : {
     586               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     587                 : 
     588               0 :         RETURN_STRING(intern->u.dir.entry.d_name, 1);
     589                 : }
     590                 : /* }}} */
     591                 : 
     592                 : /* {{{ proto string SplFileInfo::getBasename([string $suffix]) U
     593                 :    Returns filename component of path */
     594                 : SPL_METHOD(SplFileInfo, getBasename)
     595               0 : {
     596               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     597               0 :         char *fname, *suffix = 0;
     598                 :         size_t flen;
     599               0 :         int slen = 0;
     600                 : 
     601               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &suffix, &slen) == FAILURE) {
     602               0 :                 return;
     603                 :         }
     604                 : 
     605               0 :         if (intern->path_len && intern->path_len < intern->file_name_len) {
     606               0 :                 fname = intern->file_name + intern->path_len + 1;
     607               0 :                 flen = intern->file_name_len - (intern->path_len + 1);
     608                 :         } else {
     609               0 :                 fname = intern->file_name;
     610               0 :                 flen = intern->file_name_len;
     611                 :         }
     612                 : 
     613               0 :         php_basename(fname, flen, suffix, slen, &fname, &flen TSRMLS_CC);
     614                 : 
     615               0 :         RETURN_STRINGL(fname, flen, 0);
     616                 : }
     617                 : /* }}}*/   
     618                 : 
     619                 : /* {{{ proto string DirectoryIterator::getBasename([string $suffix]) U
     620                 :    Returns filename component of current dir entry */
     621                 : SPL_METHOD(DirectoryIterator, getBasename)
     622               0 : {
     623               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     624               0 :         char *suffix = 0, *fname;
     625               0 :         int slen = 0;
     626                 :         size_t flen;
     627                 :         
     628               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &suffix, &slen) == FAILURE) {
     629               0 :                 return;
     630                 :         }
     631                 : 
     632               0 :         php_basename(intern->u.dir.entry.d_name, strlen(intern->u.dir.entry.d_name), suffix, slen, &fname, &flen TSRMLS_CC);
     633                 : 
     634               0 :         RETURN_STRINGL(fname, flen, 0);
     635                 : }
     636                 : /* }}} */
     637                 : 
     638                 : /* {{{ proto string SplFileInfo::getPathname()
     639                 :    Return path and filename */
     640                 : SPL_METHOD(SplFileInfo, getPathname)
     641               0 : {
     642               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     643                 : 
     644               0 :         switch (intern->type) {
     645                 :         case SPL_FS_INFO:
     646                 :         case SPL_FS_FILE:
     647               0 :                 RETURN_STRINGL(intern->file_name, intern->file_name_len, 1);
     648                 :         case SPL_FS_DIR:
     649               0 :                 if (intern->u.dir.entry.d_name[0]) {
     650               0 :                         spl_filesystem_object_get_file_name(intern TSRMLS_CC);
     651               0 :                         RETURN_STRINGL(intern->file_name, intern->file_name_len, 1);
     652                 :                 }
     653                 :         }
     654               0 :         RETURN_BOOL(0);
     655                 : }
     656                 : /* }}} */
     657                 : 
     658                 : /* {{{ proto string RecursiveDirectoryIterator::key()
     659                 :    Return getPathname() or getFilename() depending on flags */
     660                 : SPL_METHOD(RecursiveDirectoryIterator, key)
     661               0 : {
     662               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     663                 : 
     664               0 :         if (intern->flags & SPL_FILE_DIR_KEY_AS_FILENAME) {
     665               0 :                 RETURN_STRING(intern->u.dir.entry.d_name, 1);
     666                 :         } else {
     667               0 :                 spl_filesystem_object_get_file_name(intern TSRMLS_CC);
     668               0 :                 RETURN_STRINGL(intern->file_name, intern->file_name_len, 1);
     669                 :         }
     670                 : }
     671                 : /* }}} */
     672                 : 
     673                 : /* {{{ proto string RecursiveDirectoryIterator::current()
     674                 :    Return getFilename(), getFileInfo() or $this depending on flags */
     675                 : SPL_METHOD(RecursiveDirectoryIterator, current)
     676               0 : {
     677               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     678                 : 
     679               0 :         if (intern->flags & SPL_FILE_DIR_CURRENT_AS_PATHNAME) {
     680               0 :                 spl_filesystem_object_get_file_name(intern TSRMLS_CC);
     681               0 :                 RETURN_STRINGL(intern->file_name, intern->file_name_len, 1);
     682               0 :         } else if (intern->flags & SPL_FILE_DIR_CURRENT_AS_FILEINFO) {
     683               0 :                 spl_filesystem_object_get_file_name(intern TSRMLS_CC);
     684               0 :                 spl_filesystem_object_create_type(0, intern, SPL_FS_INFO, NULL, return_value TSRMLS_CC);
     685                 :         } else {
     686               0 :                 RETURN_ZVAL(getThis(), 1, 0);
     687                 :                 /*RETURN_STRING(intern->u.dir.entry.d_name, 1);*/
     688                 :         }
     689                 : }
     690                 : /* }}} */
     691                 : 
     692                 : /* {{{ proto bool DirectoryIterator::isDot()
     693                 :    Returns true if current entry is '.' or  '..' */
     694                 : SPL_METHOD(DirectoryIterator, isDot)
     695               0 : {
     696               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     697                 : 
     698               0 :         RETURN_BOOL(spl_filesystem_is_dot(intern->u.dir.entry.d_name));
     699                 : }
     700                 : /* }}} */
     701                 : 
     702                 : /* {{{ proto void SplFileInfo::__construct(string file_name)
     703                 :  Cronstructs a new SplFileInfo from a path. */
     704                 : /* php_set_error_handling() is used to throw exceptions in case
     705                 :    the constructor fails. Here we use this to ensure the object
     706                 :    has a valid directory resource.
     707                 :    
     708                 :    When the constructor gets called the object is already created 
     709                 :    by the engine, so we must only call 'additional' initializations.
     710                 :  */
     711                 : SPL_METHOD(SplFileInfo, __construct)
     712               0 : {
     713                 :         spl_filesystem_object *intern;
     714                 :         char *path;
     715                 :         int len;
     716                 : 
     717               0 :         php_set_error_handling(EH_THROW, spl_ce_RuntimeException TSRMLS_CC);
     718                 : 
     719               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &path, &len) == FAILURE) {
     720               0 :                 php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
     721               0 :                 return;
     722                 :         }
     723                 : 
     724               0 :         intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     725                 :         
     726               0 :         spl_filesystem_info_set_filename(intern, path, len, 1 TSRMLS_CC);
     727                 :         
     728                 :         /* intern->type = SPL_FS_INFO; already set */
     729                 : 
     730               0 :         php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
     731                 : }
     732                 : /* }}} */
     733                 : 
     734                 : /* {{{ FileInfoFunction */
     735                 : #define FileInfoFunction(func_name, func_num) \
     736                 : SPL_METHOD(SplFileInfo, func_name) \
     737                 : { \
     738                 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); \
     739                 :  \
     740                 :         php_set_error_handling(EH_THROW, spl_ce_RuntimeException TSRMLS_CC);\
     741                 :         spl_filesystem_object_get_file_name(intern TSRMLS_CC); \
     742                 :         php_stat(intern->file_name, intern->file_name_len, func_num, return_value TSRMLS_CC); \
     743                 :         php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);\
     744                 : }
     745                 : /* }}} */
     746                 : 
     747                 : /* {{{ proto int SplFileInfo::getPerms()
     748                 :    Get file permissions */
     749               0 : FileInfoFunction(getPerms, FS_PERMS)
     750                 : /* }}} */
     751                 : 
     752                 : /* {{{ proto int SplFileInfo::getInode()
     753                 :    Get file inode */
     754               0 : FileInfoFunction(getInode, FS_INODE)
     755                 : /* }}} */
     756                 : 
     757                 : /* {{{ proto int SplFileInfo::getSize()
     758                 :    Get file size */
     759               0 : FileInfoFunction(getSize, FS_SIZE)
     760                 : /* }}} */
     761                 : 
     762                 : /* {{{ proto int SplFileInfo::getOwner()
     763                 :    Get file owner */
     764               0 : FileInfoFunction(getOwner, FS_OWNER)
     765                 : /* }}} */
     766                 : 
     767                 : /* {{{ proto int SplFileInfo::getGroup()
     768                 :    Get file group */
     769               0 : FileInfoFunction(getGroup, FS_GROUP)
     770                 : /* }}} */
     771                 : 
     772                 : /* {{{ proto int SplFileInfo::getATime()
     773                 :    Get last access time of file */
     774               0 : FileInfoFunction(getATime, FS_ATIME)
     775                 : /* }}} */
     776                 : 
     777                 : /* {{{ proto int SplFileInfo::getMTime()
     778                 :    Get last modification time of file */
     779               0 : FileInfoFunction(getMTime, FS_MTIME)
     780                 : /* }}} */
     781                 : 
     782                 : /* {{{ proto int SplFileInfo::getCTime()
     783                 :    Get inode modification time of file */
     784               0 : FileInfoFunction(getCTime, FS_CTIME)
     785                 : /* }}} */
     786                 : 
     787                 : /* {{{ proto string SplFileInfo::getType()
     788                 :    Get file type */
     789               0 : FileInfoFunction(getType, FS_TYPE)
     790                 : /* }}} */
     791                 : 
     792                 : /* {{{ proto bool SplFileInfo::isWritable()
     793                 :    Returns true if file can be written */
     794               0 : FileInfoFunction(isWritable, FS_IS_W)
     795                 : /* }}} */
     796                 : 
     797                 : /* {{{ proto bool SplFileInfo::isReadable()
     798                 :    Returns true if file can be read */
     799               0 : FileInfoFunction(isReadable, FS_IS_R)
     800                 : /* }}} */
     801                 : 
     802                 : /* {{{ proto bool SplFileInfo::isExecutable()
     803                 :    Returns true if file is executable */
     804               0 : FileInfoFunction(isExecutable, FS_IS_X)
     805                 : /* }}} */
     806                 : 
     807                 : /* {{{ proto bool SplFileInfo::isFile()
     808                 :    Returns true if file is a regular file */
     809               0 : FileInfoFunction(isFile, FS_IS_FILE)
     810                 : /* }}} */
     811                 : 
     812                 : /* {{{ proto bool SplFileInfo::isDir()
     813                 :    Returns true if file is directory */
     814               0 : FileInfoFunction(isDir, FS_IS_DIR)
     815                 : /* }}} */
     816                 : 
     817                 : /* {{{ proto bool SplFileInfo::isLink()
     818                 :    Returns true if file is symbolic link */
     819               0 : FileInfoFunction(isLink, FS_IS_LINK)
     820                 : /* }}} */
     821                 : 
     822                 : /* {{{ proto string SplFileInfo::getLinkTarget() U
     823                 :    Return the target of a symbolic link */
     824                 : SPL_METHOD(SplFileInfo, getLinkTarget)
     825               0 : {
     826               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     827                 :         int ret;
     828                 :         char buff[MAXPATHLEN];
     829                 : 
     830               0 :         php_set_error_handling(EH_THROW, spl_ce_RuntimeException TSRMLS_CC);
     831                 : 
     832               0 :         ret = readlink(intern->file_name, buff, MAXPATHLEN-1);
     833                 : 
     834               0 :         if (ret == -1) {
     835               0 :                 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Unable to read link %s, error: %s", intern->file_name, strerror(errno));
     836               0 :                 RETVAL_FALSE;
     837                 :         } else {
     838                 :                 /* Append NULL to the end of the string */
     839               0 :                 buff[ret] = '\0';
     840                 : 
     841               0 :                 RETVAL_STRINGL(buff, ret, 1);
     842                 :         }
     843               0 :         php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
     844               0 : }
     845                 : /* }}} */
     846                 : 
     847                 : #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
     848                 : /* {{{ proto string SplFileInfo::getRealPath()
     849                 :    Return the resolved path */
     850                 : SPL_METHOD(SplFileInfo, getRealPath)
     851               0 : {
     852               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     853                 :         char buff[MAXPATHLEN];
     854                 : 
     855               0 :         php_set_error_handling(EH_THROW, spl_ce_RuntimeException TSRMLS_CC);
     856                 : 
     857               0 :         if (VCWD_REALPATH(intern->file_name, buff)) {
     858                 : #ifdef ZTS
     859                 :                 if (VCWD_ACCESS(buff, F_OK)) {
     860                 :                         RETVAL_FALSE;
     861                 :                 } else
     862                 : #endif
     863               0 :                 RETVAL_STRING(buff, 1);
     864                 :         } else {
     865               0 :                 RETVAL_FALSE;
     866                 :         }
     867               0 :         php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
     868               0 : }
     869                 : /* }}} */
     870                 : #endif
     871                 : 
     872                 : /* {{{ proto SplFileObject SplFileInfo::openFile([string mode = 'r' [, bool use_include_path  [, resource context]]])
     873                 :    Open the current file */
     874                 : SPL_METHOD(SplFileInfo, openFile)
     875               0 : {
     876               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     877                 : 
     878               0 :         spl_filesystem_object_create_type(ht, intern, SPL_FS_FILE, NULL, return_value TSRMLS_CC);
     879               0 : }
     880                 : /* }}} */
     881                 : 
     882                 : /* {{{ proto void SplFileInfo::setFileClass([string class_name])
     883                 :    Class to use in openFile() */
     884                 : SPL_METHOD(SplFileInfo, setFileClass)
     885               0 : {
     886               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     887               0 :         zend_class_entry *ce = spl_ce_SplFileObject;
     888                 :         
     889               0 :         php_set_error_handling(EH_THROW, spl_ce_UnexpectedValueException TSRMLS_CC);
     890                 : 
     891               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == SUCCESS) {
     892               0 :                 intern->file_class = ce;
     893                 :         }
     894                 : 
     895               0 :         php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
     896               0 : }
     897                 : /* }}} */
     898                 : 
     899                 : /* {{{ proto void SplFileInfo::setInfoClass([string class_name])
     900                 :    Class to use in getFileInfo(), getPathInfo() */
     901                 : SPL_METHOD(SplFileInfo, setInfoClass)
     902               0 : {
     903               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     904               0 :         zend_class_entry *ce = spl_ce_SplFileInfo;
     905                 :         
     906               0 :         php_set_error_handling(EH_THROW, spl_ce_UnexpectedValueException TSRMLS_CC);
     907                 : 
     908               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == SUCCESS) {
     909               0 :                 intern->info_class = ce;
     910                 :         }
     911                 : 
     912               0 :         php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
     913               0 : }
     914                 : /* }}} */
     915                 : 
     916                 : /* {{{ proto SplFileInfo SplFileInfo::getFileInfo([string $class_name])
     917                 :    Get/copy file info */
     918                 : SPL_METHOD(SplFileInfo, getFileInfo)
     919               0 : {
     920               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     921               0 :         zend_class_entry *ce = intern->info_class;
     922                 :         
     923               0 :         php_set_error_handling(EH_THROW, spl_ce_UnexpectedValueException TSRMLS_CC);
     924                 : 
     925               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == SUCCESS) {
     926               0 :                 spl_filesystem_object_create_type(ht, intern, SPL_FS_INFO, ce, return_value TSRMLS_CC);
     927                 :         }
     928                 : 
     929               0 :         php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
     930               0 : }
     931                 : /* }}} */
     932                 : 
     933                 : /* {{{ proto SplFileInfo SplFileInfo::getPathInfo([string $class_name])
     934                 :    Get/copy file info */
     935                 : SPL_METHOD(SplFileInfo, getPathInfo)
     936               0 : {
     937               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     938               0 :         zend_class_entry *ce = intern->info_class;
     939                 :         
     940               0 :         php_set_error_handling(EH_THROW, spl_ce_UnexpectedValueException TSRMLS_CC);
     941                 : 
     942               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == SUCCESS) {
     943               0 :                 spl_filesystem_object_create_info(intern, intern->path, intern->path_len, 1, ce, return_value TSRMLS_CC);
     944                 :         }
     945                 : 
     946               0 :         php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
     947               0 : }
     948                 : /* }}} */
     949                 : 
     950                 : /* {{{ proto void RecursiveDirectoryIterator::__construct(string path [, int flags])
     951                 :  Cronstructs a new dir iterator from a path. */
     952                 : SPL_METHOD(RecursiveDirectoryIterator, __construct)
     953               0 : {
     954                 :         spl_filesystem_object *intern;
     955                 :         char *path;
     956                 :         int len;
     957               0 :         long flags = SPL_FILE_DIR_CURRENT_AS_FILEINFO;
     958                 : 
     959               0 :         php_set_error_handling(EH_THROW, spl_ce_UnexpectedValueException TSRMLS_CC);
     960                 : 
     961               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &path, &len, &flags) == FAILURE) {
     962               0 :                 php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
     963               0 :                 return;
     964                 :         }
     965                 : 
     966               0 :         intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     967               0 :         spl_filesystem_dir_open(intern, path TSRMLS_CC);
     968               0 :         intern->u.dir.is_recursive = instanceof_function(intern->std.ce, spl_ce_RecursiveDirectoryIterator TSRMLS_CC) ? 1 : 0;
     969               0 :         intern->flags = flags;
     970                 : 
     971               0 :         php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
     972                 : }
     973                 : /* }}} */
     974                 : 
     975                 : /* {{{ proto void RecursiveDirectoryIterator::rewind()
     976                 :    Rewind dir back to the start */
     977                 : SPL_METHOD(RecursiveDirectoryIterator, rewind)
     978               0 : {
     979               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     980                 : 
     981               0 :         intern->u.dir.index = 0;
     982               0 :         if (intern->u.dir.dirp) {
     983               0 :                 php_stream_rewinddir(intern->u.dir.dirp);
     984                 :         }
     985                 :         do {
     986               0 :                 if (!intern->u.dir.dirp || !php_stream_readdir(intern->u.dir.dirp, &intern->u.dir.entry)) {
     987               0 :                         intern->u.dir.entry.d_name[0] = '\0';
     988                 :                 }
     989               0 :         } while (spl_filesystem_is_dot(intern->u.dir.entry.d_name));
     990               0 : }
     991                 : /* }}} */
     992                 : 
     993                 : /* {{{ proto void RecursiveDirectoryIterator::next()
     994                 :    Move to next entry */
     995                 : SPL_METHOD(RecursiveDirectoryIterator, next)
     996               0 : {
     997               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     998                 : 
     999               0 :         intern->u.dir.index++;
    1000                 :         do {
    1001               0 :                 if (!intern->u.dir.dirp || !php_stream_readdir(intern->u.dir.dirp, &intern->u.dir.entry)) {
    1002               0 :                         intern->u.dir.entry.d_name[0] = '\0';
    1003                 :                 }
    1004               0 :         } while (spl_filesystem_is_dot(intern->u.dir.entry.d_name));
    1005               0 :         if (intern->file_name) {
    1006               0 :                 efree(intern->file_name);
    1007               0 :                 intern->file_name = NULL;
    1008                 :         }
    1009               0 : }
    1010                 : /* }}} */
    1011                 : 
    1012                 : /* {{{ proto bool RecursiveDirectoryIterator::hasChildren([bool $allow_links = false])
    1013                 :    Returns whether current entry is a directory and not '.' or '..' */
    1014                 : SPL_METHOD(RecursiveDirectoryIterator, hasChildren)
    1015               0 : {
    1016               0 :         zend_bool allow_links = 0;
    1017               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1018                 :         
    1019               0 :         if (spl_filesystem_is_invalid_or_dot(intern->u.dir.entry.d_name)) {
    1020               0 :                 RETURN_BOOL(0);
    1021                 :         } else {
    1022               0 :                 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &allow_links) == FAILURE) {
    1023               0 :                         return;
    1024                 :                 }
    1025               0 :                 spl_filesystem_object_get_file_name(intern TSRMLS_CC);
    1026               0 :                 if (!allow_links) {
    1027               0 :                         php_stat(intern->file_name, intern->file_name_len, FS_IS_LINK, return_value TSRMLS_CC);
    1028               0 :                         if (zend_is_true(return_value)) {
    1029               0 :                                 RETURN_BOOL(0);
    1030                 :                         }
    1031                 :                 }
    1032               0 :                 php_stat(intern->file_name, intern->file_name_len, FS_IS_DIR, return_value TSRMLS_CC);
    1033                 :     }
    1034                 : }
    1035                 : /* }}} */
    1036                 : 
    1037                 : /* {{{ proto RecursiveDirectoryIterator DirectoryIterator::getChildren()
    1038                 :    Returns an iterator for the current entry if it is a directory */
    1039                 : SPL_METHOD(RecursiveDirectoryIterator, getChildren)
    1040               0 : {
    1041                 :         zval zpath;
    1042               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1043                 :         spl_filesystem_object *subdir;
    1044                 :         
    1045               0 :         spl_filesystem_object_get_file_name(intern TSRMLS_CC);
    1046                 : 
    1047               0 :         INIT_PZVAL(&zpath);
    1048               0 :         ZVAL_STRINGL(&zpath, intern->file_name, intern->file_name_len, 0);
    1049                 : 
    1050               0 :         spl_instantiate_arg_ex1(spl_ce_RecursiveDirectoryIterator, &return_value, 0, &zpath TSRMLS_CC);
    1051                 :         
    1052               0 :         subdir = (spl_filesystem_object*)zend_object_store_get_object(return_value TSRMLS_CC);
    1053               0 :         if (subdir) {
    1054               0 :                 if (intern->u.dir.sub_path && intern->u.dir.sub_path[0]) {
    1055               0 :                         subdir->u.dir.sub_path_len = spprintf(&subdir->u.dir.sub_path, 0, "%s%c%s", intern->u.dir.sub_path, DEFAULT_SLASH, intern->u.dir.entry.d_name);
    1056                 :                 } else {
    1057               0 :                         subdir->u.dir.sub_path_len = strlen(intern->u.dir.entry.d_name);
    1058               0 :                         subdir->u.dir.sub_path = estrndup(intern->u.dir.entry.d_name, subdir->u.dir.sub_path_len);
    1059                 :                 }
    1060               0 :                 subdir->info_class = intern->info_class;
    1061               0 :                 subdir->file_class = intern->file_class;
    1062               0 :                 subdir->flags = intern->flags;
    1063               0 :                 subdir->oth = intern->oth;
    1064                 :         }
    1065               0 : }
    1066                 : /* }}} */
    1067                 : 
    1068                 : /* {{{ proto void RecursiveDirectoryIterator::getSubPath()
    1069                 :    Get sub path */
    1070                 : SPL_METHOD(RecursiveDirectoryIterator, getSubPath)
    1071               0 : {
    1072               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1073                 : 
    1074               0 :         if (intern->u.dir.sub_path) {
    1075               0 :                 RETURN_STRINGL(intern->u.dir.sub_path, intern->u.dir.sub_path_len, 1);
    1076                 :         } else {
    1077               0 :                 RETURN_STRINGL("", 0, 1);
    1078                 :         }
    1079                 : }
    1080                 : /* }}} */
    1081                 : 
    1082                 : /* {{{ proto void RecursiveDirectoryIterator::getSubPathname()
    1083                 :    Get sub path and file name */
    1084                 : SPL_METHOD(RecursiveDirectoryIterator, getSubPathname)
    1085               0 : {
    1086               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1087                 :         char *sub_name;
    1088                 :         int len;
    1089                 : 
    1090               0 :         if (intern->u.dir.sub_path) {
    1091               0 :                 len = spprintf(&sub_name, 0, "%s%c%s", intern->u.dir.sub_path, DEFAULT_SLASH, intern->u.dir.entry.d_name);
    1092               0 :                 RETURN_STRINGL(sub_name, len, 0);
    1093                 :         } else {
    1094               0 :                 RETURN_STRING(intern->u.dir.entry.d_name, 1);
    1095                 :         }
    1096                 : }
    1097                 : /* }}} */
    1098                 : 
    1099                 : /* define an overloaded iterator structure */
    1100                 : typedef struct {
    1101                 :         zend_object_iterator  intern;
    1102                 :         zval                  *current;
    1103                 :         spl_filesystem_object *object;
    1104                 : } spl_filesystem_dir_it;
    1105                 : 
    1106                 : /* forward declarations to the iterator handlers */
    1107                 : static void spl_filesystem_dir_it_dtor(zend_object_iterator *iter TSRMLS_DC);
    1108                 : static int spl_filesystem_dir_it_valid(zend_object_iterator *iter TSRMLS_DC);
    1109                 : static void spl_filesystem_dir_it_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC);
    1110                 : static int spl_filesystem_dir_it_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC);
    1111                 : static void spl_filesystem_dir_it_move_forward(zend_object_iterator *iter TSRMLS_DC);
    1112                 : static void spl_filesystem_dir_it_rewind(zend_object_iterator *iter TSRMLS_DC);
    1113                 : 
    1114                 : /* iterator handler table */
    1115                 : zend_object_iterator_funcs spl_filesystem_dir_it_funcs = {
    1116                 :         spl_filesystem_dir_it_dtor,
    1117                 :         spl_filesystem_dir_it_valid,
    1118                 :         spl_filesystem_dir_it_current_data,
    1119                 :         spl_filesystem_dir_it_current_key,
    1120                 :         spl_filesystem_dir_it_move_forward,
    1121                 :         spl_filesystem_dir_it_rewind
    1122                 : };
    1123                 : 
    1124                 : /* {{{ spl_ce_dir_get_iterator */
    1125                 : zend_object_iterator *spl_filesystem_dir_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
    1126               0 : {
    1127                 :         spl_filesystem_dir_it *iterator;
    1128                 :         spl_filesystem_object *dir_object;
    1129                 : 
    1130               0 :         if (by_ref) {
    1131               0 :                 zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
    1132                 :         }
    1133               0 :         iterator   = emalloc(sizeof(spl_filesystem_dir_it));
    1134               0 :         dir_object = (spl_filesystem_object*)zend_object_store_get_object(object TSRMLS_CC);
    1135                 : 
    1136               0 :         object->refcount += 2;;
    1137               0 :         iterator->intern.data = (void*)object;
    1138               0 :         iterator->intern.funcs = &spl_filesystem_dir_it_funcs;
    1139               0 :         iterator->current = object;
    1140               0 :         iterator->object = dir_object;
    1141                 :         
    1142               0 :         return (zend_object_iterator*)iterator;
    1143                 : }
    1144                 : /* }}} */
    1145                 : 
    1146                 : /* {{{ spl_filesystem_dir_it_dtor */
    1147                 : static void spl_filesystem_dir_it_dtor(zend_object_iterator *iter TSRMLS_DC)
    1148               0 : {
    1149               0 :         spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter;
    1150                 : 
    1151               0 :         zval_ptr_dtor(&iterator->current);
    1152               0 :         zval_ptr_dtor((zval**)&iterator->intern.data);
    1153                 : 
    1154               0 :         efree(iterator);
    1155               0 : }
    1156                 : /* }}} */
    1157                 :         
    1158                 : /* {{{ spl_filesystem_dir_it_valid */
    1159                 : static int spl_filesystem_dir_it_valid(zend_object_iterator *iter TSRMLS_DC)
    1160               0 : {
    1161               0 :         spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter;
    1162               0 :         spl_filesystem_object *object   = iterator->object;
    1163                 : 
    1164               0 :         return object->u.dir.entry.d_name[0] != '\0' ? SUCCESS : FAILURE;
    1165                 : }
    1166                 : /* }}} */
    1167                 : 
    1168                 : 
    1169                 : /* {{{ spl_filesystem_dir_it_current_data */
    1170                 : static void spl_filesystem_dir_it_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC)
    1171               0 : {
    1172               0 :         spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter;
    1173                 :         
    1174               0 :         *data = &iterator->current;
    1175               0 : }
    1176                 : /* }}} */
    1177                 : 
    1178                 : /* {{{ spl_filesystem_dir_it_current_key */
    1179                 : static int spl_filesystem_dir_it_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
    1180               0 : {
    1181               0 :         spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter;
    1182               0 :         spl_filesystem_object *object   = iterator->object;
    1183                 :         
    1184               0 :         *int_key = object->u.dir.index;
    1185               0 :         return HASH_KEY_IS_LONG;
    1186                 : }
    1187                 : /* }}} */
    1188                 : 
    1189                 : /* {{{ spl_filesystem_dir_it_move_forward */
    1190                 : static void spl_filesystem_dir_it_move_forward(zend_object_iterator *iter TSRMLS_DC)
    1191               0 : {
    1192               0 :         spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter;
    1193               0 :         spl_filesystem_object *object   = iterator->object;
    1194                 :         
    1195               0 :         object->u.dir.index++;
    1196               0 :         if (!object->u.dir.dirp || !php_stream_readdir(object->u.dir.dirp, &object->u.dir.entry)) {
    1197               0 :                 object->u.dir.entry.d_name[0] = '\0';
    1198                 :         }
    1199               0 :         if (object->file_name) {
    1200               0 :                 efree(object->file_name);
    1201               0 :                 object->file_name = NULL;
    1202                 :         }
    1203               0 : }
    1204                 : /* }}} */
    1205                 : 
    1206                 : /* {{{ spl_filesystem_dir_it_rewind */
    1207                 : static void spl_filesystem_dir_it_rewind(zend_object_iterator *iter TSRMLS_DC)
    1208               0 : {
    1209               0 :         spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter;
    1210               0 :         spl_filesystem_object *object   = iterator->object;
    1211                 :         
    1212               0 :         object->u.dir.index = 0;
    1213               0 :         if (object->u.dir.dirp) {
    1214               0 :                 php_stream_rewinddir(object->u.dir.dirp);
    1215                 :         }
    1216               0 :         if (!object->u.dir.dirp || !php_stream_readdir(object->u.dir.dirp, &object->u.dir.entry)) {
    1217               0 :                 object->u.dir.entry.d_name[0] = '\0';
    1218                 :         }
    1219               0 : }
    1220                 : /* }}} */
    1221                 : 
    1222                 : /* {{{ spl_filesystem_tree_it_dtor */
    1223                 : static void spl_filesystem_tree_it_dtor(zend_object_iterator *iter TSRMLS_DC)
    1224               0 : {
    1225               0 :         spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter;
    1226                 : 
    1227               0 :         if (iterator->current) {
    1228               0 :                 zval_ptr_dtor(&iterator->current);
    1229                 :         }
    1230               0 :         zval_ptr_dtor((zval**)&iterator->intern.data);
    1231                 : 
    1232               0 :         efree(iterator);
    1233               0 : }
    1234                 : /* }}} */
    1235                 :         
    1236                 : /* {{{ spl_filesystem_tree_it_current_data */
    1237                 : static void spl_filesystem_tree_it_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC)
    1238               0 : {
    1239               0 :         spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter;
    1240               0 :         spl_filesystem_object *object   = iterator->object;
    1241                 : 
    1242               0 :         if (object->flags & SPL_FILE_DIR_CURRENT_AS_PATHNAME) {
    1243               0 :                 if (!iterator->current) {
    1244               0 :                         ALLOC_INIT_ZVAL(iterator->current);
    1245               0 :                         spl_filesystem_object_get_file_name(object TSRMLS_CC);
    1246               0 :                         ZVAL_STRINGL(iterator->current, object->file_name, object->file_name_len, 1);
    1247                 :                 }
    1248               0 :                 *data = &iterator->current;
    1249               0 :         } else if (object->flags & SPL_FILE_DIR_CURRENT_AS_FILEINFO) {
    1250               0 :                 if (!iterator->current) {
    1251               0 :                         ALLOC_INIT_ZVAL(iterator->current);
    1252               0 :                         spl_filesystem_object_get_file_name(object TSRMLS_CC);
    1253               0 :                         spl_filesystem_object_create_type(0, object, SPL_FS_INFO, NULL, iterator->current TSRMLS_CC);
    1254                 :                 }
    1255               0 :                 *data = &iterator->current;
    1256                 :         } else {
    1257               0 :                 *data = (zval**)&iterator->intern.data;
    1258                 :         }
    1259               0 : }
    1260                 : /* }}} */
    1261                 : 
    1262                 : /* {{{ spl_filesystem_tree_it_current_key */
    1263                 : static int spl_filesystem_tree_it_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
    1264               0 : {
    1265               0 :         spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter;
    1266               0 :         spl_filesystem_object *object   = iterator->object;
    1267                 :         
    1268               0 :         if (object->flags & SPL_FILE_DIR_KEY_AS_FILENAME) {
    1269               0 :                 *str_key_len = strlen(object->u.dir.entry.d_name) + 1;
    1270               0 :                 *str_key = estrndup(object->u.dir.entry.d_name, *str_key_len - 1);
    1271                 :         } else {
    1272               0 :                 spl_filesystem_object_get_file_name(object TSRMLS_CC);
    1273               0 :                 *str_key_len = object->file_name_len + 1;
    1274               0 :                 *str_key = estrndup(object->file_name, object->file_name_len);
    1275                 :         }
    1276               0 :         return HASH_KEY_IS_STRING;
    1277                 : }
    1278                 : /* }}} */
    1279                 : 
    1280                 : /* {{{ spl_filesystem_tree_it_move_forward */
    1281                 : static void spl_filesystem_tree_it_move_forward(zend_object_iterator *iter TSRMLS_DC)
    1282               0 : {
    1283               0 :         spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter;
    1284               0 :         spl_filesystem_object *object   = iterator->object;
    1285                 :         
    1286               0 :         object->u.dir.index++;
    1287                 :         do {
    1288               0 :                 if (!object->u.dir.dirp || !php_stream_readdir(object->u.dir.dirp, &object->u.dir.entry)) {
    1289               0 :                         object->u.dir.entry.d_name[0] = '\0';
    1290                 :                 }
    1291               0 :         } while (spl_filesystem_is_dot(object->u.dir.entry.d_name));
    1292               0 :         if (object->file_name) {
    1293               0 :                 efree(object->file_name);
    1294               0 :                 object->file_name = NULL;
    1295                 :         }
    1296               0 :         if (iterator->current) {
    1297               0 :                 zval_ptr_dtor(&iterator->current);
    1298               0 :                 iterator->current = NULL;
    1299                 :         }
    1300               0 : }
    1301                 : /* }}} */
    1302                 : 
    1303                 : /* {{{ spl_filesystem_tree_it_rewind */
    1304                 : static void spl_filesystem_tree_it_rewind(zend_object_iterator *iter TSRMLS_DC)
    1305               0 : {
    1306               0 :         spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter;
    1307               0 :         spl_filesystem_object *object   = iterator->object;
    1308                 :         
    1309               0 :         object->u.dir.index = 0;
    1310               0 :         if (object->u.dir.dirp) {
    1311               0 :                 php_stream_rewinddir(object->u.dir.dirp);
    1312                 :         }
    1313                 :         do {
    1314               0 :                 if (!object->u.dir.dirp || !php_stream_readdir(object->u.dir.dirp, &object->u.dir.entry)) {
    1315               0 :                         object->u.dir.entry.d_name[0] = '\0';
    1316                 :                 }
    1317               0 :         } while (spl_filesystem_is_dot(object->u.dir.entry.d_name));
    1318               0 :         if (iterator->current) {
    1319               0 :                 zval_ptr_dtor(&iterator->current);
    1320               0 :                 iterator->current = NULL;
    1321                 :         }
    1322               0 : }
    1323                 : /* }}} */
    1324                 : 
    1325                 : /* iterator handler table */
    1326                 : zend_object_iterator_funcs spl_filesystem_tree_it_funcs = {
    1327                 :         spl_filesystem_tree_it_dtor,
    1328                 :         spl_filesystem_dir_it_valid,
    1329                 :         spl_filesystem_tree_it_current_data,
    1330                 :         spl_filesystem_tree_it_current_key,
    1331                 :         spl_filesystem_tree_it_move_forward,
    1332                 :         spl_filesystem_tree_it_rewind
    1333                 : };
    1334                 : 
    1335                 : /* {{{ spl_ce_dir_get_iterator */
    1336                 : zend_object_iterator *spl_filesystem_tree_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
    1337               0 : {
    1338                 :         spl_filesystem_dir_it *iterator;
    1339                 :         spl_filesystem_object *dir_object;
    1340                 : 
    1341               0 :         if (by_ref) {
    1342               0 :                 zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
    1343                 :         }
    1344               0 :         iterator   = emalloc(sizeof(spl_filesystem_dir_it));
    1345               0 :         dir_object = (spl_filesystem_object*)zend_object_store_get_object(object TSRMLS_CC);
    1346                 : 
    1347               0 :         object->refcount++;
    1348               0 :         iterator->intern.data = (void*)object;
    1349               0 :         iterator->intern.funcs = &spl_filesystem_tree_it_funcs;
    1350               0 :         iterator->current = NULL;
    1351               0 :         iterator->object = dir_object;
    1352                 :         
    1353               0 :         return (zend_object_iterator*)iterator;
    1354                 : }
    1355                 : /* }}} */
    1356                 : 
    1357                 : /* {{{ spl_filesystem_object_cast */
    1358                 : static int spl_filesystem_object_cast(zval *readobj, zval *writeobj, int type TSRMLS_DC)
    1359               0 : {
    1360               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(readobj TSRMLS_CC);
    1361                 : 
    1362               0 :         if (type == IS_STRING) {
    1363               0 :                 switch (intern->type) {
    1364                 :                 case SPL_FS_INFO:
    1365                 :                 case SPL_FS_FILE:
    1366               0 :                         ZVAL_STRINGL(writeobj, intern->file_name, intern->file_name_len, 1);
    1367               0 :                         return SUCCESS;
    1368                 :                 case SPL_FS_DIR:
    1369               0 :                         ZVAL_STRING(writeobj, intern->u.dir.entry.d_name, 1);
    1370               0 :                         return SUCCESS;
    1371                 :                 }
    1372                 :         }
    1373               0 :         ZVAL_NULL(writeobj);
    1374               0 :         return FAILURE;
    1375                 : }
    1376                 : /* }}} */
    1377                 : 
    1378                 : /* declare method parameters */
    1379                 : /* supply a name and default to call by parameter */
    1380                 : static
    1381                 : ZEND_BEGIN_ARG_INFO(arginfo_info___construct, 0) 
    1382                 :         ZEND_ARG_INFO(0, file_name)
    1383                 : ZEND_END_ARG_INFO()
    1384                 : 
    1385                 : static
    1386                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_info_openFile, 0, 0, 0)
    1387                 :         ZEND_ARG_INFO(0, open_mode)
    1388                 :         ZEND_ARG_INFO(0, use_include_path)
    1389                 :         ZEND_ARG_INFO(0, context)
    1390                 : ZEND_END_ARG_INFO()
    1391                 : 
    1392                 : static
    1393                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_info_optinalFileClass, 0, 0, 0)
    1394                 :         ZEND_ARG_INFO(0, class_name)
    1395                 : ZEND_END_ARG_INFO()
    1396                 : 
    1397                 : static
    1398                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_optinalSuffix, 0, 0, 0)
    1399                 :         ZEND_ARG_INFO(0, suffix)
    1400                 : ZEND_END_ARG_INFO()
    1401                 : 
    1402                 : /* the method table */
    1403                 : /* each method can have its own parameters and visibility */
    1404                 : static zend_function_entry spl_SplFileInfo_functions[] = {
    1405                 :         SPL_ME(SplFileInfo,       __construct,   arginfo_info___construct, ZEND_ACC_PUBLIC)
    1406                 :         SPL_ME(SplFileInfo,       getPath,       NULL, ZEND_ACC_PUBLIC)
    1407                 :         SPL_ME(SplFileInfo,       getFilename,   NULL, ZEND_ACC_PUBLIC)
    1408                 :         SPL_ME(SplFileInfo,       getBasename,   arginfo_optinalSuffix, ZEND_ACC_PUBLIC)
    1409                 :         SPL_ME(SplFileInfo,       getPathname,   NULL, ZEND_ACC_PUBLIC)
    1410                 :         SPL_ME(SplFileInfo,       getPerms,      NULL, ZEND_ACC_PUBLIC)
    1411                 :         SPL_ME(SplFileInfo,       getInode,      NULL, ZEND_ACC_PUBLIC)
    1412                 :         SPL_ME(SplFileInfo,       getSize,       NULL, ZEND_ACC_PUBLIC)
    1413                 :         SPL_ME(SplFileInfo,       getOwner,      NULL, ZEND_ACC_PUBLIC)
    1414                 :         SPL_ME(SplFileInfo,       getGroup,      NULL, ZEND_ACC_PUBLIC)
    1415                 :         SPL_ME(SplFileInfo,       getATime,      NULL, ZEND_ACC_PUBLIC)
    1416                 :         SPL_ME(SplFileInfo,       getMTime,      NULL, ZEND_ACC_PUBLIC)
    1417                 :         SPL_ME(SplFileInfo,       getCTime,      NULL, ZEND_ACC_PUBLIC)
    1418                 :         SPL_ME(SplFileInfo,       getType,       NULL, ZEND_ACC_PUBLIC)
    1419                 :         SPL_ME(SplFileInfo,       isWritable,    NULL, ZEND_ACC_PUBLIC)
    1420                 :         SPL_ME(SplFileInfo,       isReadable,    NULL, ZEND_ACC_PUBLIC)
    1421                 :         SPL_ME(SplFileInfo,       isExecutable,  NULL, ZEND_ACC_PUBLIC)
    1422                 :         SPL_ME(SplFileInfo,       isFile,        NULL, ZEND_ACC_PUBLIC)
    1423                 :         SPL_ME(SplFileInfo,       isDir,         NULL, ZEND_ACC_PUBLIC)
    1424                 :         SPL_ME(SplFileInfo,       isLink,        NULL, ZEND_ACC_PUBLIC)
    1425                 :         SPL_ME(SplFileInfo,       getLinkTarget, NULL, ZEND_ACC_PUBLIC)
    1426                 : #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
    1427                 :         SPL_ME(SplFileInfo,       getRealPath,   NULL, ZEND_ACC_PUBLIC)
    1428                 : #endif
    1429                 :         SPL_ME(SplFileInfo,       getFileInfo,   arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC)
    1430                 :         SPL_ME(SplFileInfo,       getPathInfo,   arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC)
    1431                 :         SPL_ME(SplFileInfo,       openFile,      arginfo_info_openFile,         ZEND_ACC_PUBLIC)
    1432                 :         SPL_ME(SplFileInfo,       setFileClass,  arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC)
    1433                 :         SPL_ME(SplFileInfo,       setInfoClass,  arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC)
    1434                 :         SPL_MA(SplFileInfo,       __toString, SplFileInfo, getPathname, NULL, ZEND_ACC_PUBLIC)
    1435                 :         {NULL, NULL, NULL}
    1436                 : };
    1437                 : 
    1438                 : static
    1439                 : ZEND_BEGIN_ARG_INFO(arginfo_dir___construct, 0) 
    1440                 :         ZEND_ARG_INFO(0, path)
    1441                 : ZEND_END_ARG_INFO()
    1442                 : 
    1443                 : /* the method table */
    1444                 : /* each method can have its own parameters and visibility */
    1445                 : static zend_function_entry spl_DirectoryIterator_functions[] = {
    1446                 :         SPL_ME(DirectoryIterator, __construct,   arginfo_dir___construct, ZEND_ACC_PUBLIC)
    1447                 :         SPL_ME(DirectoryIterator, getFilename,   NULL, ZEND_ACC_PUBLIC)
    1448                 :         SPL_ME(DirectoryIterator, getBasename,   arginfo_optinalSuffix, ZEND_ACC_PUBLIC)
    1449                 :         SPL_ME(DirectoryIterator, isDot,         NULL, ZEND_ACC_PUBLIC)
    1450                 :         SPL_ME(DirectoryIterator, rewind,        NULL, ZEND_ACC_PUBLIC)
    1451                 :         SPL_ME(DirectoryIterator, valid,         NULL, ZEND_ACC_PUBLIC)
    1452                 :         SPL_ME(DirectoryIterator, key,           NULL, ZEND_ACC_PUBLIC)
    1453                 :         SPL_ME(DirectoryIterator, current,       NULL, ZEND_ACC_PUBLIC)
    1454                 :         SPL_ME(DirectoryIterator, next,          NULL, ZEND_ACC_PUBLIC)
    1455                 :         SPL_MA(DirectoryIterator, __toString, DirectoryIterator, getFilename, NULL, ZEND_ACC_PUBLIC)
    1456                 :         {NULL, NULL, NULL}
    1457                 : };
    1458                 : 
    1459                 : static
    1460                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_r_dir___construct, 0, 0, 1) 
    1461                 :         ZEND_ARG_INFO(0, path)
    1462                 :         ZEND_ARG_INFO(0, flags)
    1463                 : ZEND_END_ARG_INFO()
    1464                 : 
    1465                 : static
    1466                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_r_dir_hasChildren, 0, 0, 0)
    1467                 :         ZEND_ARG_INFO(0, allow_links)
    1468                 : ZEND_END_ARG_INFO()
    1469                 : 
    1470                 : static zend_function_entry spl_RecursiveDirectoryIterator_functions[] = {
    1471                 :         SPL_ME(RecursiveDirectoryIterator, __construct,   arginfo_r_dir___construct, ZEND_ACC_PUBLIC)
    1472                 :         SPL_ME(RecursiveDirectoryIterator, rewind,        NULL, ZEND_ACC_PUBLIC)
    1473                 :         SPL_ME(RecursiveDirectoryIterator, next,          NULL, ZEND_ACC_PUBLIC)
    1474                 :         SPL_ME(RecursiveDirectoryIterator, key,           NULL, ZEND_ACC_PUBLIC)
    1475                 :         SPL_ME(RecursiveDirectoryIterator, current,       NULL, ZEND_ACC_PUBLIC)
    1476                 :         SPL_ME(RecursiveDirectoryIterator, hasChildren,   arginfo_r_dir_hasChildren, ZEND_ACC_PUBLIC)
    1477                 :         SPL_ME(RecursiveDirectoryIterator, getChildren,   NULL, ZEND_ACC_PUBLIC)
    1478                 :         SPL_ME(RecursiveDirectoryIterator, getSubPath,    NULL, ZEND_ACC_PUBLIC)
    1479                 :         SPL_ME(RecursiveDirectoryIterator, getSubPathname,NULL, ZEND_ACC_PUBLIC)
    1480                 :         {NULL, NULL, NULL}
    1481                 : };
    1482                 : 
    1483                 : static int spl_filesystem_file_read(spl_filesystem_object *intern, int silent TSRMLS_DC) /* {{{ */
    1484               0 : {
    1485                 :         char *buf;
    1486               0 :         size_t line_len = 0;
    1487                 :         int len;
    1488               0 :         long line_add = (intern->u.file.current_line || intern->u.file.current_zval) ? 1 : 0;
    1489                 : 
    1490               0 :         spl_filesystem_file_free_line(intern TSRMLS_CC);
    1491                 :         
    1492               0 :         if (php_stream_eof(intern->u.file.stream)) {
    1493               0 :                 if (!silent) {
    1494               0 :                         zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot read from file %s", intern->file_name);
    1495                 :                 }
    1496               0 :                 return FAILURE;
    1497                 :         }
    1498                 : 
    1499               0 :         if (intern->u.file.max_line_len > 0) {
    1500               0 :                 buf = safe_emalloc((intern->u.file.max_line_len + 1), sizeof(char), 0);
    1501               0 :                 if (php_stream_get_line(intern->u.file.stream, buf, intern->u.file.max_line_len, &line_len) == NULL) {
    1502               0 :                         efree(buf);
    1503               0 :                         buf = NULL;
    1504                 :                 } else {
    1505               0 :                         buf[line_len] = '\0';
    1506                 :                 }
    1507                 :         } else {
    1508               0 :                 buf = php_stream_get_line(intern->u.file.stream, NULL, 0, &line_len);
    1509                 :         }
    1510                 : 
    1511               0 :         if (!buf) {
    1512               0 :                 intern->u.file.current_line = estrdup("");
    1513               0 :                 intern->u.file.current_line_len = 0;
    1514                 :         } else {
    1515               0 :                 if (intern->flags & SPL_FILE_OBJECT_DROP_NEW_LINE) {
    1516               0 :                         line_len = strcspn(buf, "\r\n");
    1517               0 :                         buf[line_len] = '\0';
    1518                 :                 }
    1519                 :         
    1520               0 :                 if (PG(magic_quotes_runtime)) {
    1521               0 :                         buf = php_addslashes(buf, line_len, &len, 1 TSRMLS_CC);
    1522               0 :                         line_len = len;
    1523                 :                 }
    1524                 :         
    1525               0 :                 intern->u.file.current_line = buf;
    1526               0 :                 intern->u.file.current_line_len = line_len;
    1527                 :         }
    1528               0 :         intern->u.file.current_line_num += line_add;
    1529                 : 
    1530               0 :         return SUCCESS;
    1531                 : } /* }}} */
    1532                 : 
    1533                 : static int spl_filesystem_file_call(spl_filesystem_object *intern, zend_function *func_ptr, int pass_num_args, zval *return_value, zval *arg2 TSRMLS_DC) /* {{{ */
    1534               0 : {
    1535                 :         zend_fcall_info fci;
    1536                 :         zend_fcall_info_cache fcic;
    1537                 :         zval z_fname;
    1538               0 :         zval * zresource_ptr = &intern->u.file.zresource, *retval;
    1539                 :         int result;
    1540               0 :         int num_args = pass_num_args + (arg2 ? 2 : 1);
    1541                 : 
    1542               0 :         zval ***params = (zval***)safe_emalloc(num_args, sizeof(zval**), 0);
    1543                 : 
    1544               0 :         params[0] = &zresource_ptr;
    1545                 :         
    1546               0 :         if (arg2) {
    1547               0 :                 params[1] = &arg2;
    1548                 :         }
    1549                 : 
    1550               0 :         zend_get_parameters_array_ex(pass_num_args, params+(arg2 ? 2 : 1));
    1551                 : 
    1552               0 :         ZVAL_STRING(&z_fname, func_ptr->common.function_name, 0);
    1553                 : 
    1554               0 :         fci.size = sizeof(fci);
    1555               0 :         fci.function_table = EG(function_table);
    1556               0 :         fci.object_pp = NULL;
    1557               0 :         fci.function_name = &z_fname;
    1558               0 :         fci.retval_ptr_ptr = &retval;
    1559               0 :         fci.param_count = num_args;
    1560               0 :         fci.params = params;
    1561               0 :         fci.no_separation = 1;
    1562               0 :         fci.symbol_table = NULL;
    1563                 : 
    1564               0 :         fcic.initialized = 1;
    1565               0 :         fcic.function_handler = func_ptr;
    1566               0 :         fcic.calling_scope = NULL;
    1567               0 :         fcic.object_pp = NULL;
    1568                 : 
    1569               0 :         result = zend_call_function(&fci, &fcic TSRMLS_CC);
    1570                 :         
    1571               0 :         ZVAL_ZVAL(return_value, retval, 1, 1);
    1572                 : 
    1573               0 :         efree(params);
    1574               0 :         return result;
    1575                 : } /* }}} */
    1576                 : 
    1577                 : #define FileFunctionCall(func_name, pass_num_args, arg2) \
    1578                 : { \
    1579                 :         zend_function *func_ptr; \
    1580                 :         zend_hash_find(EG(function_table), #func_name, sizeof(#func_name), (void **) &func_ptr); \
    1581                 :         spl_filesystem_file_call(intern, func_ptr, pass_num_args, return_value, arg2 TSRMLS_CC); \
    1582                 : }
    1583                 : 
    1584                 : static int spl_filesystem_file_read_csv(spl_filesystem_object *intern, char delimiter, char enclosure, zval *return_value TSRMLS_DC) /* {{{ */
    1585               0 : {
    1586               0 :         int ret = SUCCESS;
    1587                 :         
    1588                 :         do {
    1589               0 :                 ret = spl_filesystem_file_read(intern, 1 TSRMLS_CC);
    1590               0 :         } while (ret == SUCCESS && !intern->u.file.current_line_len && (intern->flags & SPL_FILE_OBJECT_SKIP_EMPTY));
    1591                 :         
    1592               0 :         if (ret == SUCCESS) {
    1593               0 :                 size_t buf_len = intern->u.file.current_line_len;
    1594               0 :                 char *buf = estrndup(intern->u.file.current_line, buf_len);
    1595                 : 
    1596               0 :                 if (intern->u.file.current_zval) {
    1597               0 :                         zval_ptr_dtor(&intern->u.file.current_zval);
    1598                 :                 }
    1599               0 :                 ALLOC_INIT_ZVAL(intern->u.file.current_zval);
    1600                 : 
    1601               0 :                 php_fgetcsv(intern->u.file.stream, delimiter, enclosure, buf_len, buf, intern->u.file.current_zval TSRMLS_CC);
    1602               0 :                 if (return_value) {
    1603               0 :                         if (Z_TYPE_P(return_value) != IS_NULL) {
    1604               0 :                                 zval_dtor(return_value);
    1605               0 :                                 ZVAL_NULL(return_value);
    1606                 :                         }
    1607               0 :                         ZVAL_ZVAL(return_value, intern->u.file.current_zval, 1, 0);
    1608                 :                 }
    1609                 :         }
    1610               0 :         return ret;
    1611                 : }
    1612                 : /* }}} */
    1613                 : 
    1614                 : static int spl_filesystem_file_read_line_ex(zval * this_ptr, spl_filesystem_object *intern, int silent TSRMLS_DC) /* {{{ */
    1615               0 : {
    1616               0 :         zval *retval = NULL;
    1617                 : 
    1618                 :         /* 1) use fgetcsv? 2) overloaded call the function, 3) do it directly */
    1619               0 :         if (intern->flags & SPL_FILE_OBJECT_READ_CSV || intern->u.file.func_getCurr->common.scope != spl_ce_SplFileObject) {
    1620               0 :                 if (php_stream_eof(intern->u.file.stream)) {
    1621               0 :                         if (!silent) {
    1622               0 :                                 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot read from file %s", intern->file_name);
    1623                 :                         }
    1624               0 :                         return FAILURE;
    1625                 :                 }
    1626               0 :                 if (intern->flags & SPL_FILE_OBJECT_READ_CSV) {
    1627               0 :                         return spl_filesystem_file_read_csv(intern, intern->u.file.delimiter, intern->u.file.enclosure, NULL TSRMLS_CC);
    1628                 :                 } else {
    1629               0 :                         zend_call_method_with_0_params(&this_ptr, Z_OBJCE_P(getThis()), &intern->u.file.func_getCurr, "getCurrentLine", &retval);
    1630                 :                 }
    1631               0 :                 if (retval) {
    1632               0 :                         if (intern->u.file.current_line || intern->u.file.current_zval) {
    1633               0 :                                 intern->u.file.current_line_num++;
    1634                 :                         }
    1635               0 :                         spl_filesystem_file_free_line(intern TSRMLS_CC);
    1636               0 :                         if (Z_TYPE_P(retval) == IS_STRING) {
    1637               0 :                                 intern->u.file.current_line = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
    1638               0 :                                 intern->u.file.current_line_len = Z_STRLEN_P(retval);
    1639                 :                         } else {
    1640               0 :                                 MAKE_STD_ZVAL(intern->u.file.current_zval);
    1641               0 :                                 ZVAL_ZVAL(intern->u.file.current_zval, retval, 1, 0);
    1642                 :                         }
    1643               0 :                         zval_ptr_dtor(&retval);
    1644               0 :                         return SUCCESS;
    1645                 :                 } else {
    1646               0 :                         return FAILURE;
    1647                 :                 }
    1648                 :         } else {
    1649               0 :                 return spl_filesystem_file_read(intern, silent TSRMLS_CC);
    1650                 :         }
    1651                 : } /* }}} */
    1652                 : 
    1653                 : static int spl_filesystem_file_is_empty_line(spl_filesystem_object *intern TSRMLS_DC) /* {{{ */
    1654               0 : {
    1655               0 :         if (intern->u.file.current_line) {
    1656               0 :                 return intern->u.file.current_line_len == 0;
    1657               0 :         } else if (intern->u.file.current_zval) {
    1658               0 :                 switch(Z_TYPE_P(intern->u.file.current_zval)) {
    1659                 :                 case IS_STRING:
    1660               0 :                         return Z_STRLEN_P(intern->u.file.current_zval) == 0;
    1661                 :                 case IS_ARRAY:
    1662               0 :                         if ((intern->flags & SPL_FILE_OBJECT_READ_CSV) 
    1663                 :                         && zend_hash_num_elements(Z_ARRVAL_P(intern->u.file.current_zval)) == 1) {
    1664               0 :                                 zval ** first = Z_ARRVAL_P(intern->u.file.current_zval)->pListHead->pData;
    1665                 :                                         
    1666               0 :                                 return Z_TYPE_PP(first) == IS_STRING && Z_STRLEN_PP(first) == 0;
    1667                 :                         }
    1668               0 :                         return zend_hash_num_elements(Z_ARRVAL_P(intern->u.file.current_zval)) == 0;
    1669                 :                 case IS_NULL:
    1670               0 :                         return 1;
    1671                 :                 default:
    1672               0 :                         return 0;
    1673                 :                 }
    1674                 :         } else {
    1675               0 :                 return 1;
    1676                 :         }
    1677                 : }
    1678                 : /* }}} */
    1679                 : 
    1680                 : static int spl_filesystem_file_read_line(zval * this_ptr, spl_filesystem_object *intern, int silent TSRMLS_DC) /* {{{ */
    1681               0 : {
    1682               0 :         int ret = spl_filesystem_file_read_line_ex(this_ptr, intern, silent TSRMLS_CC);
    1683                 : 
    1684               0 :         while ((intern->flags & SPL_FILE_OBJECT_SKIP_EMPTY) && ret == SUCCESS && spl_filesystem_file_is_empty_line(intern TSRMLS_CC)) {
    1685               0 :                 spl_filesystem_file_free_line(intern TSRMLS_CC);
    1686               0 :                 ret = spl_filesystem_file_read_line_ex(this_ptr, intern, silent TSRMLS_CC);
    1687                 :         }
    1688                 :         
    1689               0 :         return ret;
    1690                 : }
    1691                 : /* }}} */
    1692                 : 
    1693                 : static void spl_filesystem_file_rewind(zval * this_ptr, spl_filesystem_object *intern TSRMLS_DC) /* {{{ */
    1694               0 : {
    1695               0 :         if (-1 == php_stream_rewind(intern->u.file.stream)) {
    1696               0 :                 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot rewind file %s", intern->file_name);
    1697                 :         } else {
    1698               0 :                 spl_filesystem_file_free_line(intern TSRMLS_CC);
    1699               0 :                 intern->u.file.current_line_num = 0;
    1700                 :         }
    1701               0 :         if (intern->flags & SPL_FILE_OBJECT_READ_AHEAD) {
    1702               0 :                 spl_filesystem_file_read_line(this_ptr, intern, 1 TSRMLS_CC);
    1703                 :         }
    1704               0 : } /* }}} */
    1705                 : 
    1706                 : /* {{{ proto void SplFileObject::__construct(string filename [, string mode = 'r' [, bool use_include_path  [, resource context]]]])
    1707                 :    Construct a new file object */
    1708                 : SPL_METHOD(SplFileObject, __construct)
    1709               0 : {
    1710               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1711               0 :         zend_bool use_include_path = 0;
    1712                 :         char *p1, *p2;
    1713                 : 
    1714               0 :         php_set_error_handling(EH_THROW, spl_ce_RuntimeException TSRMLS_CC);
    1715                 : 
    1716               0 :         intern->u.file.open_mode = "r";
    1717               0 :         intern->u.file.open_mode_len = 1;
    1718                 : 
    1719               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|sbr", 
    1720                 :                         &intern->file_name, &intern->file_name_len,
    1721                 :                         &intern->u.file.open_mode, &intern->u.file.open_mode_len, 
    1722                 :                         &use_include_path, &intern->u.file.zcontext) == FAILURE) {
    1723               0 :                 php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
    1724               0 :                 return;
    1725                 :         }
    1726                 :         
    1727               0 :         if (spl_filesystem_file_open(intern, use_include_path, 0 TSRMLS_CC) == SUCCESS) {
    1728               0 :                 p1 = strrchr(intern->file_name, '/');
    1729                 : #if defined(PHP_WIN32) || defined(NETWARE)
    1730                 :                 p2 = strrchr(intern->file_name, '\\');
    1731                 : #else
    1732               0 :                 p2 = 0;
    1733                 : #endif
    1734               0 :                 if (p1 || p2) {
    1735               0 :                         intern->path_len = (p1 > p2 ? p1 : p2) - intern->file_name;
    1736                 :                 } else {
    1737               0 :                         intern->path_len = 0;
    1738                 :                 }
    1739               0 :                 intern->path = estrndup(intern->file_name, intern->path_len);
    1740                 :         }
    1741                 : 
    1742               0 :         php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
    1743                 : } /* }}} */
    1744                 : 
    1745                 : /* {{{ proto void SplTempFileObject::__construct([int max_memory])
    1746                 :    Construct a new temp file object */
    1747                 : SPL_METHOD(SplTempFileObject, __construct)
    1748               0 : {
    1749               0 :         long max_memory = PHP_STREAM_MAX_MEM;
    1750                 :         char tmp_fname[48];
    1751               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1752                 : 
    1753               0 :         php_set_error_handling(EH_THROW, spl_ce_RuntimeException TSRMLS_CC);
    1754                 : 
    1755               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &max_memory) == FAILURE) {
    1756               0 :                 php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
    1757               0 :                 return;
    1758                 :         }
    1759                 : 
    1760               0 :         if (max_memory < 0) {
    1761               0 :                 intern->file_name = "php://memory";
    1762               0 :                 intern->file_name_len = 12;
    1763               0 :         } else if (ZEND_NUM_ARGS()) {
    1764               0 :                 intern->file_name_len = slprintf(tmp_fname, sizeof(tmp_fname), "php://temp/maxmemory:%ld", max_memory);
    1765               0 :                 intern->file_name = tmp_fname;
    1766                 :         } else {
    1767               0 :                 intern->file_name = "php://temp";
    1768               0 :                 intern->file_name_len = 10;
    1769                 :         }
    1770               0 :         intern->u.file.open_mode = "wb";
    1771               0 :         intern->u.file.open_mode_len = 1;
    1772               0 :         intern->u.file.zcontext = NULL;
    1773                 :         
    1774               0 :         if (spl_filesystem_file_open(intern, 0, 0 TSRMLS_CC) == SUCCESS) {
    1775               0 :                 intern->path_len = 0;
    1776               0 :                 intern->path = estrndup("", 0);
    1777                 :         }
    1778                 : 
    1779               0 :         php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
    1780                 : } /* }}} */
    1781                 : 
    1782                 : /* {{{ proto void SplFileObject::rewind()
    1783                 :    Rewind the file and read the first line */
    1784                 : SPL_METHOD(SplFileObject, rewind)
    1785               0 : {
    1786               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1787                 : 
    1788               0 :         spl_filesystem_file_rewind(getThis(), intern TSRMLS_CC);
    1789               0 : } /* }}} */
    1790                 : 
    1791                 : /* {{{ proto void SplFileObject::eof()
    1792                 :    Return whether end of file is reached */
    1793                 : SPL_METHOD(SplFileObject, eof)
    1794               0 : {
    1795               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1796                 : 
    1797               0 :         RETURN_BOOL(php_stream_eof(intern->u.file.stream));
    1798                 : } /* }}} */
    1799                 : 
    1800                 : /* {{{ proto void SplFileObject::valid()
    1801                 :    Return !eof() */
    1802                 : SPL_METHOD(SplFileObject, valid)
    1803               0 : {
    1804               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1805                 : 
    1806               0 :         if (intern->flags & SPL_FILE_OBJECT_READ_AHEAD) {
    1807               0 :                 RETURN_BOOL(intern->u.file.current_line || intern->u.file.current_zval);
    1808                 :         } else {
    1809               0 :                 RETVAL_BOOL(!php_stream_eof(intern->u.file.stream));
    1810                 :         }
    1811                 : } /* }}} */
    1812                 : 
    1813                 : /* {{{ proto string SplFileObject::fgets()
    1814                 :    Rturn next line from file */
    1815                 : SPL_METHOD(SplFileObject, fgets)
    1816               0 : {
    1817               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1818                 : 
    1819               0 :         if (spl_filesystem_file_read(intern, 0 TSRMLS_CC) == FAILURE) {
    1820               0 :                 RETURN_FALSE;
    1821                 :         }
    1822               0 :         RETURN_STRINGL(intern->u.file.current_line, intern->u.file.current_line_len, 1);
    1823                 : } /* }}} */
    1824                 : 
    1825                 : /* {{{ proto string SplFileObject::current()
    1826                 :    Return current line from file */
    1827                 : SPL_METHOD(SplFileObject, current)
    1828               0 : {
    1829               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1830                 : 
    1831               0 :         if (!intern->u.file.current_line && !intern->u.file.current_zval) {
    1832               0 :                 spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC);
    1833                 :         }
    1834               0 :         if (intern->u.file.current_line && (!(intern->flags & SPL_FILE_OBJECT_READ_CSV) || !intern->u.file.current_zval)) {
    1835               0 :                 RETURN_STRINGL(intern->u.file.current_line, intern->u.file.current_line_len, 1);
    1836               0 :         } else if (intern->u.file.current_zval) {
    1837               0 :                 RETURN_ZVAL(intern->u.file.current_zval, 1, 0);
    1838                 :         }
    1839               0 :         RETURN_FALSE;
    1840                 : } /* }}} */
    1841                 : 
    1842                 : /* {{{ proto int SplFileObject::key()
    1843                 :    Return line number */
    1844                 : SPL_METHOD(SplFileObject, key)
    1845               0 : {
    1846               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1847                 : 
    1848                 : /*      Do not read the next line to support correct counting with fgetc()
    1849                 :         if (!intern->current_line) {
    1850                 :                 spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC);
    1851                 :         } */
    1852               0 :         RETURN_LONG(intern->u.file.current_line_num);
    1853                 : } /* }}} */
    1854                 : 
    1855                 : /* {{{ proto void SplFileObject::next()
    1856                 :    Read next line */
    1857                 : SPL_METHOD(SplFileObject, next)
    1858               0 : {
    1859               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1860                 : 
    1861               0 :         spl_filesystem_file_free_line(intern TSRMLS_CC);
    1862               0 :         if (intern->flags & SPL_FILE_OBJECT_READ_AHEAD) {
    1863               0 :                 spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC);
    1864                 :         }
    1865               0 :         intern->u.file.current_line_num++;
    1866               0 : } /* }}} */
    1867                 : 
    1868                 : /* {{{ proto void SplFileObject::setFlags(int flags)
    1869                 :    Set file handling flags */
    1870                 : SPL_METHOD(SplFileObject, setFlags)
    1871               0 : {
    1872               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1873                 : 
    1874               0 :         zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &intern->flags);
    1875               0 : } /* }}} */
    1876                 : 
    1877                 : /* {{{ proto int SplFileObject::getFlags()
    1878                 :    Get file handling flags */
    1879                 : SPL_METHOD(SplFileObject, getFlags)
    1880               0 : {
    1881               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1882                 : 
    1883               0 :         RETURN_LONG(intern->flags);
    1884                 : } /* }}} */
    1885                 : 
    1886                 : /* {{{ proto void SplFileObject::setMaxLineLen(int max_len)
    1887                 :    Set maximum line length */
    1888                 : SPL_METHOD(SplFileObject, setMaxLineLen)
    1889               0 : {
    1890                 :         long max_len;
    1891                 : 
    1892               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1893                 : 
    1894               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &max_len) == FAILURE) {
    1895               0 :                 return;
    1896                 :         }
    1897                 : 
    1898               0 :         if (max_len < 0) {
    1899               0 :                 zend_throw_exception_ex(spl_ce_DomainException, 0 TSRMLS_CC, "Maximum line length must be greater than or equal zero");
    1900               0 :                 return;
    1901                 :         }
    1902                 :         
    1903               0 :         intern->u.file.max_line_len = max_len;
    1904                 : } /* }}} */
    1905                 : 
    1906                 : /* {{{ proto int SplFileObject::getMaxLineLen()
    1907                 :    Get maximum line length */
    1908                 : SPL_METHOD(SplFileObject, getMaxLineLen)
    1909               0 : {
    1910               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1911                 : 
    1912               0 :         RETURN_LONG((long)intern->u.file.max_line_len);
    1913                 : } /* }}} */
    1914                 : 
    1915                 : /* {{{ proto bool SplFileObject::hasChildren()
    1916                 :    Return false */
    1917                 : SPL_METHOD(SplFileObject, hasChildren)
    1918               0 : {
    1919               0 :         RETURN_FALSE;
    1920                 : } /* }}} */
    1921                 : 
    1922                 : /* {{{ proto bool SplFileObject::getChildren()
    1923                 :    Read NULL */
    1924                 : SPL_METHOD(SplFileObject, getChildren)
    1925               0 : {
    1926                 :         /* return NULL */
    1927               0 : } /* }}} */
    1928                 : 
    1929                 : /* {{{ FileFunction */
    1930                 : #define FileFunction(func_name) \
    1931                 : SPL_METHOD(SplFileObject, func_name) \
    1932                 : { \
    1933                 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); \
    1934                 :         FileFunctionCall(func_name, ZEND_NUM_ARGS(), NULL); \
    1935                 : }
    1936                 : /* }}} */
    1937                 : 
    1938                 : /* {{{ proto array SplFileObject::fgetcsv([string delimiter [, string enclosure]])
    1939                 :    Return current line as csv */
    1940                 : SPL_METHOD(SplFileObject, fgetcsv)
    1941               0 : {
    1942               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1943               0 :         char delimiter = intern->u.file.delimiter, enclosure = intern->u.file.enclosure;
    1944                 :         char *delim, *enclo;
    1945                 :         int d_len, e_len;
    1946                 :         
    1947               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ss", &delim, &d_len, &enclo, &e_len) == SUCCESS) {
    1948               0 :                 switch(ZEND_NUM_ARGS())
    1949                 :                 {
    1950                 :                         case 2:
    1951               0 :                                 if (e_len != 1) {
    1952               0 :                                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "enclosure must be a character");
    1953               0 :                                         RETURN_FALSE;
    1954                 :                                 }
    1955               0 :                                 enclosure = enclo[0];
    1956                 :                                 /* no break */
    1957                 :                         case 1:
    1958               0 :                                 if (d_len != 1) {
    1959               0 :                                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "delimiter must be a character");
    1960               0 :                                         RETURN_FALSE;
    1961                 :                                 }
    1962               0 :                                 delimiter = delim[0];
    1963                 :                                 /* no break */
    1964                 :                         case 0:
    1965                 :                                 break;
    1966                 :                 }
    1967               0 :                 spl_filesystem_file_read_csv(intern, delimiter, enclosure, return_value TSRMLS_CC);
    1968                 :         }
    1969                 : }
    1970                 : /* }}} */
    1971                 : 
    1972                 : /* {{{ proto void SplFileObject::setCsvControl([string delimiter = ',' [, string enclosure = '"']])
    1973                 :    Set the delimiter and enclosure character used in fgetcsv */
    1974                 : SPL_METHOD(SplFileObject, setCsvControl)
    1975               0 : {
    1976               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1977               0 :         char delimiter = ',', enclosure = '"';
    1978                 :         char *delim, *enclo;
    1979                 :         int d_len, e_len;
    1980                 :         
    1981               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ss", &delim, &d_len, &enclo, &e_len) == SUCCESS) {
    1982               0 :                 switch(ZEND_NUM_ARGS())
    1983                 :                 {
    1984                 :                         case 2:
    1985               0 :                                 if (e_len != 1) {
    1986               0 :                                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "enclosure must be a character");
    1987               0 :                                         RETURN_FALSE;
    1988                 :                                 }
    1989               0 :                                 enclosure = enclo[0];
    1990                 :                                 /* no break */
    1991                 :                         case 1:
    1992               0 :                                 if (d_len != 1) {
    1993               0 :                                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "delimiter must be a character");
    1994               0 :                                         RETURN_FALSE;
    1995                 :                                 }
    1996               0 :                                 delimiter = delim[0];
    1997                 :                                 /* no break */
    1998                 :                         case 0:
    1999                 :                                 break;
    2000                 :                 }
    2001               0 :                 intern->u.file.delimiter = delimiter;
    2002               0 :                 intern->u.file.enclosure = enclosure;
    2003                 :         }
    2004                 : }
    2005                 : /* }}} */
    2006                 : 
    2007                 : /* {{{ proto array SplFileObject::getCsvControl()
    2008                 :    Get the delimiter and enclosure character used in fgetcsv */
    2009                 : SPL_METHOD(SplFileObject, getCsvControl)
    2010               0 : {
    2011               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2012                 :         char delimiter[2], enclosure[2];
    2013                 : 
    2014               0 :         array_init(return_value);
    2015                 :         
    2016               0 :         delimiter[0] = intern->u.file.delimiter;
    2017               0 :         delimiter[1] = '\0';
    2018               0 :         enclosure[0] = intern->u.file.enclosure;
    2019               0 :         enclosure[1] = '\0';
    2020                 : 
    2021               0 :         add_next_index_string(return_value, delimiter, 1);
    2022               0 :         add_next_index_string(return_value, enclosure, 1);
    2023               0 : }
    2024                 : /* }}} */
    2025                 : 
    2026                 : /* {{{ proto bool SplFileObject::flock(int operation [, int &wouldblock])
    2027                 :    Portable file locking */
    2028               0 : FileFunction(flock)
    2029                 : /* }}} */
    2030                 : 
    2031                 : /* {{{ proto bool SplFileObject::fflush()
    2032                 :    Flush the file */
    2033                 : SPL_METHOD(SplFileObject, fflush)
    2034               0 : {
    2035               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2036                 : 
    2037               0 :         RETURN_BOOL(!php_stream_flush(intern->u.file.stream));
    2038                 : } /* }}} */
    2039                 : 
    2040                 : 
    2041                 : /* {{{ proto int SplFileObject::ftell()
    2042                 :    Return current file position */
    2043                 : SPL_METHOD(SplFileObject, ftell)
    2044               0 : {
    2045               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);      
    2046               0 :         long ret = php_stream_tell(intern->u.file.stream);
    2047                 : 
    2048               0 :         if (ret == -1) {
    2049               0 :                 RETURN_FALSE;
    2050                 :         } else {
    2051               0 :                 RETURN_LONG(ret);
    2052                 :         }
    2053                 : } /* }}} */
    2054                 : 
    2055                 : /* {{{ proto int SplFileObject::fseek(int pos [, int whence = SEEK_SET])
    2056                 :    Return current file position */
    2057                 : SPL_METHOD(SplFileObject, fseek)
    2058               0 : {
    2059               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2060               0 :         long pos, whence = SEEK_SET;
    2061                 : 
    2062               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &pos, &whence) == FAILURE) {
    2063               0 :                 return;
    2064                 :         }
    2065                 : 
    2066               0 :         spl_filesystem_file_free_line(intern TSRMLS_CC);
    2067               0 :         RETURN_LONG(php_stream_seek(intern->u.file.stream, pos, whence));
    2068                 : } /* }}} */
    2069                 : 
    2070                 : /* {{{ proto int SplFileObject::fgetc()
    2071                 :    Get a character form the file */
    2072                 : SPL_METHOD(SplFileObject, fgetc)
    2073               0 : {
    2074               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2075                 :         char buf[2];
    2076                 :         int result;
    2077                 : 
    2078               0 :         spl_filesystem_file_free_line(intern TSRMLS_CC);
    2079                 : 
    2080               0 :         result = php_stream_getc(intern->u.file.stream);
    2081                 : 
    2082               0 :         if (result == EOF) {
    2083               0 :                 RETVAL_FALSE;
    2084                 :         } else {
    2085               0 :                 if (result == '\n') {
    2086               0 :                         intern->u.file.current_line_num++;
    2087                 :                 }
    2088               0 :                 buf[0] = result;
    2089               0 :                 buf[1] = '\0';
    2090                 : 
    2091               0 :                 RETURN_STRINGL(buf, 1, 1);
    2092                 :         }
    2093                 : } /* }}} */
    2094                 : 
    2095                 : /* {{{ proto string SplFileObject::fgetss([string allowable_tags])
    2096                 :    Get a line from file pointer and strip HTML tags */
    2097                 : SPL_METHOD(SplFileObject, fgetss)
    2098               0 : {
    2099               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2100               0 :         zval *arg2 = NULL;
    2101               0 :         MAKE_STD_ZVAL(arg2);
    2102               0 :         ZVAL_LONG(arg2, intern->u.file.max_line_len);
    2103                 : 
    2104               0 :         spl_filesystem_file_free_line(intern TSRMLS_CC);
    2105               0 :         intern->u.file.current_line_num++;
    2106                 : 
    2107               0 :         FileFunctionCall(fgetss, ZEND_NUM_ARGS(), arg2);
    2108                 : 
    2109               0 :         zval_ptr_dtor(&arg2);
    2110               0 : } /* }}} */
    2111                 : 
    2112                 : /* {{{ proto int SplFileObject::fpassthru()
    2113                 :    Output all remaining data from a file pointer */
    2114                 : SPL_METHOD(SplFileObject, fpassthru)
    2115               0 : {
    2116               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2117                 : 
    2118               0 :         RETURN_LONG(php_stream_passthru(intern->u.file.stream));
    2119                 : } /* }}} */
    2120                 : 
    2121                 : /* {{{ proto bool SplFileObject::fscanf(string format [, string ...])
    2122                 :    Implements a mostly ANSI compatible fscanf() */
    2123                 : SPL_METHOD(SplFileObject, fscanf)
    2124               0 : {
    2125               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2126                 : 
    2127               0 :         spl_filesystem_file_free_line(intern TSRMLS_CC);
    2128               0 :         intern->u.file.current_line_num++;
    2129                 : 
    2130               0 :         FileFunctionCall(fscanf, ZEND_NUM_ARGS(), NULL);
    2131               0 : }
    2132                 : /* }}} */
    2133                 : 
    2134                 : /* {{{ proto mixed SplFileObject::fwrite(string str [, int length])
    2135                 :    Binary-safe file write */
    2136                 : SPL_METHOD(SplFileObject, fwrite)
    2137               0 : {
    2138               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2139                 :         char *str;
    2140                 :         int str_len;
    2141                 :         int ret;
    2142               0 :         long length = 0;
    2143                 : 
    2144               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &str, &str_len, &length) == FAILURE) {
    2145               0 :                 return;
    2146                 :         }
    2147                 : 
    2148               0 :         if (ZEND_NUM_ARGS() > 1) {
    2149               0 :                 str_len = MAX(0, MIN(length, str_len));
    2150                 :         }
    2151               0 :         if (!str_len) {
    2152               0 :                 RETURN_LONG(0);
    2153                 :         }
    2154                 : 
    2155               0 :         if (PG(magic_quotes_runtime)) {
    2156               0 :                 str = estrndup(str, str_len);
    2157               0 :                 php_stripslashes(str, &str_len TSRMLS_CC);
    2158               0 :                 ret = php_stream_write(intern->u.file.stream, str, str_len);
    2159               0 :                 efree(str);
    2160               0 :                 RETURN_LONG(ret);
    2161                 :         }
    2162                 : 
    2163               0 :         RETURN_LONG(php_stream_write(intern->u.file.stream, str, str_len));
    2164                 : } /* }}} */
    2165                 : 
    2166                 : /* {{{ proto bool SplFileObject::fstat()
    2167                 :    Stat() on a filehandle */
    2168               0 : FileFunction(fstat)
    2169                 : /* }}} */
    2170                 : 
    2171                 : /* {{{ proto bool SplFileObject::ftruncate(int size)
    2172                 :    Truncate file to 'size' length */
    2173                 : SPL_METHOD(SplFileObject, ftruncate)
    2174               0 : {
    2175               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2176                 :         long size;
    2177                 :         
    2178               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &size) == FAILURE) {
    2179               0 :                 return;
    2180                 :         }
    2181                 : 
    2182               0 :         if (!php_stream_truncate_supported(intern->u.file.stream)) {
    2183               0 :                 zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Can't truncate file %s", intern->file_name);
    2184               0 :                 RETURN_FALSE;
    2185                 :         }
    2186                 :         
    2187               0 :         RETURN_BOOL(0 == php_stream_truncate_set_size(intern->u.file.stream, size));
    2188                 : } /* }}} */
    2189                 : 
    2190                 : /* {{{ proto void SplFileObject::seek(int line_pos)
    2191                 :    Seek to specified line */
    2192                 : SPL_METHOD(SplFileObject, seek)
    2193               0 : {
    2194               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2195                 :         long line_pos;
    2196                 :         
    2197               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &line_pos) == FAILURE) {
    2198               0 :                 return;
    2199                 :         }
    2200               0 :         if (line_pos < 0) {
    2201               0 :                 zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Can't seek file %s to negative line %ld", intern->file_name, line_pos);
    2202               0 :                 RETURN_FALSE;           
    2203                 :         }
    2204                 :         
    2205               0 :         spl_filesystem_file_rewind(getThis(), intern TSRMLS_CC);
    2206                 :         
    2207               0 :         while(intern->u.file.current_line_num < line_pos) {
    2208               0 :                 spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC);
    2209                 :         }
    2210                 : } /* }}} */
    2211                 : 
    2212                 : /* {{{ Function/Class/Method definitions */
    2213                 : static
    2214                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object___construct, 0, 0, 1)
    2215                 :         ZEND_ARG_INFO(0, file_name)
    2216                 :         ZEND_ARG_INFO(0, open_mode)
    2217                 :         ZEND_ARG_INFO(0, use_include_path)
    2218                 :         ZEND_ARG_INFO(0, context)
    2219                 : ZEND_END_ARG_INFO()
    2220                 : 
    2221                 : static
    2222                 : ZEND_BEGIN_ARG_INFO(arginfo_file_object_setFlags, 0) 
    2223                 :         ZEND_ARG_INFO(0, flags)
    2224                 : ZEND_END_ARG_INFO()
    2225                 : 
    2226                 : static
    2227                 : ZEND_BEGIN_ARG_INFO(arginfo_file_object_setMaxLineLen, 0) 
    2228                 :         ZEND_ARG_INFO(0, max_len)
    2229                 : ZEND_END_ARG_INFO()
    2230                 : 
    2231                 : static
    2232                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fgetcsv, 0, 0, 0) 
    2233                 :         ZEND_ARG_INFO(0, delimiter)
    2234                 :         ZEND_ARG_INFO(0, enclosure)
    2235                 : ZEND_END_ARG_INFO()
    2236                 : 
    2237                 : static
    2238                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_flock, 0, 0, 1) 
    2239                 :         ZEND_ARG_INFO(0, operation)
    2240                 :         ZEND_ARG_INFO(1, wouldblock)
    2241                 : ZEND_END_ARG_INFO()
    2242                 : 
    2243                 : static
    2244                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fseek, 0, 0, 1) 
    2245                 :         ZEND_ARG_INFO(0, pos)
    2246                 :         ZEND_ARG_INFO(0, whence)
    2247                 : ZEND_END_ARG_INFO()
    2248                 : 
    2249                 : static
    2250                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fgetss, 0, 0, 0) 
    2251                 :         ZEND_ARG_INFO(0, allowable_tags)
    2252                 : ZEND_END_ARG_INFO()
    2253                 : 
    2254                 : static
    2255                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fscanf, 0, 0, 1) 
    2256                 :         ZEND_ARG_INFO(0, format)
    2257                 : ZEND_END_ARG_INFO()
    2258                 : 
    2259                 : static
    2260                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fwrite, 0, 0, 1) 
    2261                 :         ZEND_ARG_INFO(0, str)
    2262                 :         ZEND_ARG_INFO(0, length)
    2263                 : ZEND_END_ARG_INFO()
    2264                 : 
    2265                 : static
    2266                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_ftruncate, 0, 0, 1) 
    2267                 :         ZEND_ARG_INFO(0, size)
    2268                 : ZEND_END_ARG_INFO()
    2269                 : 
    2270                 : static
    2271                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_seek, 0, 0, 1) 
    2272                 :         ZEND_ARG_INFO(0, line_pos)
    2273                 : ZEND_END_ARG_INFO()
    2274                 : 
    2275                 : static zend_function_entry spl_SplFileObject_functions[] = {
    2276                 :         SPL_ME(SplFileObject, __construct,    arginfo_file_object___construct,   ZEND_ACC_PUBLIC)
    2277                 :         SPL_ME(SplFileObject, rewind,         NULL, ZEND_ACC_PUBLIC)
    2278                 :         SPL_ME(SplFileObject, eof,            NULL, ZEND_ACC_PUBLIC)
    2279                 :         SPL_ME(SplFileObject, valid,          NULL, ZEND_ACC_PUBLIC)
    2280                 :         SPL_ME(SplFileObject, fgets,          NULL, ZEND_ACC_PUBLIC)
    2281                 :         SPL_ME(SplFileObject, fgetcsv,        arginfo_file_object_fgetcsv,       ZEND_ACC_PUBLIC)
    2282                 :         SPL_ME(SplFileObject, setCsvControl,  arginfo_file_object_fgetcsv,       ZEND_ACC_PUBLIC)
    2283                 :         SPL_ME(SplFileObject, getCsvControl,  NULL,                              ZEND_ACC_PUBLIC)
    2284                 :         SPL_ME(SplFileObject, flock,          arginfo_file_object_flock,         ZEND_ACC_PUBLIC)
    2285                 :         SPL_ME(SplFileObject, fflush,         NULL, ZEND_ACC_PUBLIC)
    2286                 :         SPL_ME(SplFileObject, ftell,          NULL, ZEND_ACC_PUBLIC)
    2287                 :         SPL_ME(SplFileObject, fseek,          arginfo_file_object_fseek,         ZEND_ACC_PUBLIC)
    2288                 :         SPL_ME(SplFileObject, fgetc,          NULL, ZEND_ACC_PUBLIC)
    2289                 :         SPL_ME(SplFileObject, fpassthru,      NULL, ZEND_ACC_PUBLIC)
    2290                 :         SPL_ME(SplFileObject, fgetss,         arginfo_file_object_fgetss,        ZEND_ACC_PUBLIC)
    2291                 :         SPL_ME(SplFileObject, fscanf,         arginfo_file_object_fscanf,        ZEND_ACC_PUBLIC)
    2292                 :         SPL_ME(SplFileObject, fwrite,         arginfo_file_object_fwrite,        ZEND_ACC_PUBLIC)
    2293                 :         SPL_ME(SplFileObject, fstat,          NULL, ZEND_ACC_PUBLIC)
    2294                 :         SPL_ME(SplFileObject, ftruncate,      arginfo_file_object_ftruncate,     ZEND_ACC_PUBLIC)
    2295                 :         SPL_ME(SplFileObject, current,        NULL, ZEND_ACC_PUBLIC)
    2296                 :         SPL_ME(SplFileObject, key,            NULL, ZEND_ACC_PUBLIC)
    2297                 :         SPL_ME(SplFileObject, next,           NULL, ZEND_ACC_PUBLIC)
    2298                 :         SPL_ME(SplFileObject, setFlags,       arginfo_file_object_setFlags,      ZEND_ACC_PUBLIC)
    2299                 :         SPL_ME(SplFileObject, getFlags,       NULL, ZEND_ACC_PUBLIC)
    2300                 :         SPL_ME(SplFileObject, setMaxLineLen,  arginfo_file_object_setMaxLineLen, ZEND_ACC_PUBLIC)
    2301                 :         SPL_ME(SplFileObject, getMaxLineLen,  NULL, ZEND_ACC_PUBLIC)
    2302                 :         SPL_ME(SplFileObject, hasChildren,    NULL, ZEND_ACC_PUBLIC)
    2303                 :         SPL_ME(SplFileObject, getChildren,    NULL, ZEND_ACC_PUBLIC)
    2304                 :         SPL_ME(SplFileObject, seek,           arginfo_file_object_seek,          ZEND_ACC_PUBLIC)
    2305                 :         /* mappings */
    2306                 :         SPL_MA(SplFileObject, getCurrentLine, SplFileObject, fgets,      NULL, ZEND_ACC_PUBLIC)
    2307                 :         SPL_MA(SplFileObject, __toString,     SplFileObject, current,    NULL, ZEND_ACC_PUBLIC)
    2308                 :         {NULL, NULL, NULL}
    2309                 : };
    2310                 : 
    2311                 : static
    2312                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_temp_file_object___construct, 0, 0, 0)
    2313                 :         ZEND_ARG_INFO(0, max_memory)
    2314                 : ZEND_END_ARG_INFO()
    2315                 : 
    2316                 : static zend_function_entry spl_SplTempFileObject_functions[] = {
    2317                 :         SPL_ME(SplTempFileObject, __construct, arginfo_temp_file_object___construct,  ZEND_ACC_PUBLIC)
    2318                 :         {NULL, NULL, NULL}
    2319                 : };
    2320                 : /* }}} */
    2321                 : 
    2322                 : /* {{{ PHP_MINIT_FUNCTION(spl_directory)
    2323                 :  */
    2324                 : PHP_MINIT_FUNCTION(spl_directory)
    2325             220 : {
    2326             220 :         REGISTER_SPL_STD_CLASS_EX(SplFileInfo, spl_filesystem_object_new, spl_SplFileInfo_functions);
    2327             220 :         memcpy(&spl_filesystem_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
    2328             220 :         spl_filesystem_object_handlers.clone_obj = spl_filesystem_object_clone;
    2329             220 :         spl_filesystem_object_handlers.cast_object = spl_filesystem_object_cast;
    2330                 : 
    2331             220 :         REGISTER_SPL_SUB_CLASS_EX(DirectoryIterator, SplFileInfo, spl_filesystem_object_new, spl_DirectoryIterator_functions);
    2332             220 :         zend_class_implements(spl_ce_DirectoryIterator TSRMLS_CC, 1, zend_ce_iterator);
    2333                 : 
    2334             220 :         spl_ce_DirectoryIterator->get_iterator = spl_filesystem_dir_get_iterator;
    2335                 : 
    2336             220 :         REGISTER_SPL_SUB_CLASS_EX(RecursiveDirectoryIterator, DirectoryIterator, spl_filesystem_object_new, spl_RecursiveDirectoryIterator_functions);
    2337             220 :         REGISTER_SPL_IMPLEMENTS(RecursiveDirectoryIterator, RecursiveIterator);
    2338                 : 
    2339             220 :         REGISTER_SPL_CLASS_CONST_LONG(RecursiveDirectoryIterator, "CURRENT_MODE_MASK",   SPL_FILE_DIR_CURRENT_MODE_MASK);
    2340             220 :         REGISTER_SPL_CLASS_CONST_LONG(RecursiveDirectoryIterator, "CURRENT_AS_PATHNAME", SPL_FILE_DIR_CURRENT_AS_PATHNAME);
    2341             220 :         REGISTER_SPL_CLASS_CONST_LONG(RecursiveDirectoryIterator, "CURRENT_AS_FILEINFO", SPL_FILE_DIR_CURRENT_AS_FILEINFO);
    2342             220 :         REGISTER_SPL_CLASS_CONST_LONG(RecursiveDirectoryIterator, "CURRENT_AS_SELF",     0);
    2343             220 :         REGISTER_SPL_CLASS_CONST_LONG(RecursiveDirectoryIterator, "KEY_MODE_MASK",       SPL_FILE_DIR_KEY_MODE_MASK);
    2344             220 :         REGISTER_SPL_CLASS_CONST_LONG(RecursiveDirectoryIterator, "KEY_AS_PATHNAME",     0);
    2345             220 :         REGISTER_SPL_CLASS_CONST_LONG(RecursiveDirectoryIterator, "KEY_AS_FILENAME",     SPL_FILE_DIR_KEY_AS_FILENAME);
    2346             220 :         REGISTER_SPL_CLASS_CONST_LONG(RecursiveDirectoryIterator, "NEW_CURRENT_AND_KEY", SPL_FILE_DIR_KEY_AS_FILENAME|SPL_FILE_DIR_CURRENT_AS_FILEINFO);
    2347                 : 
    2348             220 :         spl_ce_RecursiveDirectoryIterator->get_iterator = spl_filesystem_tree_get_iterator;
    2349                 : 
    2350             220 :         REGISTER_SPL_SUB_CLASS_EX(SplFileObject, SplFileInfo, spl_filesystem_object_new, spl_SplFileObject_functions);
    2351             220 :         REGISTER_SPL_IMPLEMENTS(SplFileObject, RecursiveIterator);
    2352             220 :         REGISTER_SPL_IMPLEMENTS(SplFileObject, SeekableIterator);
    2353                 : 
    2354             220 :         REGISTER_SPL_CLASS_CONST_LONG(SplFileObject, "DROP_NEW_LINE", SPL_FILE_OBJECT_DROP_NEW_LINE);
    2355             220 :         REGISTER_SPL_CLASS_CONST_LONG(SplFileObject, "READ_AHEAD",    SPL_FILE_OBJECT_READ_AHEAD);
    2356             220 :         REGISTER_SPL_CLASS_CONST_LONG(SplFileObject, "SKIP_EMPTY",    SPL_FILE_OBJECT_SKIP_EMPTY);
    2357             220 :         REGISTER_SPL_CLASS_CONST_LONG(SplFileObject, "READ_CSV",      SPL_FILE_OBJECT_READ_CSV);
    2358                 :         
    2359             220 :         REGISTER_SPL_SUB_CLASS_EX(SplTempFileObject, SplFileObject, spl_filesystem_object_new, spl_SplTempFileObject_functions);
    2360             220 :         return SUCCESS;
    2361                 : }
    2362                 : /* }}} */
    2363                 : 
    2364                 : 
    2365                 : /*
    2366                 :  * Local variables:
    2367                 :  * tab-width: 4
    2368                 :  * c-basic-offset: 4
    2369                 :  * End:
    2370                 :  * vim600: noet sw=4 ts=4 fdm=marker
    2371                 :  * vim<600: noet sw=4 ts=4
    2372                 :  */

Generated by: LTP GCOV extension version 1.5