PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - standard - dir.c
Test: PHP Code Coverage
Date: 2009-11-23 Instrumented lines: 194
Code covered: 85.6 % Executed lines: 166
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 6                                                        |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1997-2009 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: Thies C. Arntzen <thies@thieso.net>                          |
      16                 :    +----------------------------------------------------------------------+
      17                 :  */
      18                 : 
      19                 : /* $Id: dir.c 286624 2009-08-01 14:45:42Z kalle $ */
      20                 : 
      21                 : /* {{{ includes/startup/misc */
      22                 : 
      23                 : #include "php.h"
      24                 : #include "fopen_wrappers.h"
      25                 : #include "file.h"
      26                 : #include "php_dir.h"
      27                 : #include "php_string.h"
      28                 : #include "php_scandir.h"
      29                 : #include "basic_functions.h"
      30                 : 
      31                 : #ifdef HAVE_DIRENT_H
      32                 : #include <dirent.h>
      33                 : #endif
      34                 : 
      35                 : #if HAVE_UNISTD_H
      36                 : #include <unistd.h>
      37                 : #endif
      38                 : 
      39                 : #include <errno.h>
      40                 : 
      41                 : #ifdef PHP_WIN32
      42                 : #include "win32/readdir.h"
      43                 : #endif
      44                 : 
      45                 : 
      46                 : #ifdef HAVE_GLOB
      47                 : #ifndef PHP_WIN32
      48                 : #include <glob.h>
      49                 : #else
      50                 : #include "win32/glob.h"
      51                 : #endif
      52                 : #endif
      53                 : 
      54                 : typedef struct {
      55                 :         int default_dir;
      56                 : } php_dir_globals;
      57                 : 
      58                 : #ifdef ZTS
      59                 : #define DIRG(v) TSRMG(dir_globals_id, php_dir_globals *, v)
      60                 : int dir_globals_id;
      61                 : #else
      62                 : #define DIRG(v) (dir_globals.v)
      63                 : php_dir_globals dir_globals;
      64                 : #endif
      65                 : 
      66                 : #if 0
      67                 : typedef struct {
      68                 :         int id;
      69                 :         DIR *dir;
      70                 : } php_dir;
      71                 : 
      72                 : static int le_dirp;
      73                 : #endif
      74                 : 
      75                 : static zend_class_entry *dir_class_entry_ptr;
      76                 : 
      77                 : #define FETCH_DIRP() \
      78                 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &id) == FAILURE) { \
      79                 :                 return; \
      80                 :         } \
      81                 :         if (ZEND_NUM_ARGS() == 0) { \
      82                 :                 myself = getThis(); \
      83                 :                 if (myself) { \
      84                 :                         if (zend_hash_find(Z_OBJPROP_P(myself), "handle", sizeof("handle"), (void **)&tmp) == FAILURE) { \
      85                 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find my handle property"); \
      86                 :                                 RETURN_FALSE; \
      87                 :                         } \
      88                 :                         ZEND_FETCH_RESOURCE(dirp, php_stream *, tmp, -1, "Directory", php_file_le_stream()); \
      89                 :                 } else { \
      90                 :                         ZEND_FETCH_RESOURCE(dirp, php_stream *, 0, DIRG(default_dir), "Directory", php_file_le_stream()); \
      91                 :                 } \
      92                 :         } else { \
      93                 :                 dirp = (php_stream *) zend_fetch_resource(&id TSRMLS_CC, -1, "Directory", NULL, 1, php_file_le_stream()); \
      94                 :                 if (!dirp) \
      95                 :                         RETURN_FALSE; \
      96                 :         } 
      97                 : 
      98                 : static const zend_function_entry php_dir_class_functions[] = {
      99                 :         PHP_FALIAS(close,       closedir,       NULL)
     100                 :         PHP_FALIAS(rewind,      rewinddir,      NULL)
     101                 :         PHP_NAMED_FE(read,  php_if_readdir, NULL)
     102                 :         {NULL, NULL, NULL}
     103                 : };
     104                 : 
     105                 : 
     106                 : static void php_set_default_dir(int id TSRMLS_DC)
     107            5282 : {
     108            5282 :         if (DIRG(default_dir)!=-1) {
     109            3139 :                 zend_list_delete(DIRG(default_dir));
     110                 :         }
     111                 : 
     112            5282 :         if (id != -1) {
     113            3169 :                 zend_list_addref(id);
     114                 :         }
     115                 :         
     116            5282 :         DIRG(default_dir) = id;
     117            5282 : }
     118                 : 
     119                 : PHP_RINIT_FUNCTION(dir)
     120           16993 : {
     121           16993 :         DIRG(default_dir) = -1;
     122           16993 :         return SUCCESS;
     123                 : }
     124                 : 
     125                 : PHP_MINIT_FUNCTION(dir)
     126           17007 : {
     127                 :         static char dirsep_str[2], pathsep_str[2];
     128                 :         zend_class_entry dir_class_entry;
     129                 : 
     130           17007 :         INIT_CLASS_ENTRY(dir_class_entry, "Directory", php_dir_class_functions);
     131           17007 :         dir_class_entry_ptr = zend_register_internal_class(&dir_class_entry TSRMLS_CC);
     132                 : 
     133                 : #ifdef ZTS
     134                 :         ts_allocate_id(&dir_globals_id, sizeof(php_dir_globals), NULL, NULL);
     135                 : #endif
     136                 : 
     137           17007 :         dirsep_str[0] = DEFAULT_SLASH;
     138           17007 :         dirsep_str[1] = '\0';
     139           17007 :         REGISTER_STRING_CONSTANT("DIRECTORY_SEPARATOR", dirsep_str, CONST_CS|CONST_PERSISTENT);
     140                 : 
     141           17007 :         pathsep_str[0] = ZEND_PATHS_SEPARATOR;
     142           17007 :         pathsep_str[1] = '\0';
     143           17007 :         REGISTER_STRING_CONSTANT("PATH_SEPARATOR", pathsep_str, CONST_CS|CONST_PERSISTENT);
     144                 : 
     145                 : #ifdef HAVE_GLOB
     146                 : 
     147                 : #ifdef GLOB_BRACE
     148           17007 :         REGISTER_LONG_CONSTANT("GLOB_BRACE", GLOB_BRACE, CONST_CS | CONST_PERSISTENT);
     149                 : #else
     150                 : # define GLOB_BRACE 0
     151                 : #endif
     152                 : 
     153                 : #ifdef GLOB_MARK
     154           17007 :         REGISTER_LONG_CONSTANT("GLOB_MARK", GLOB_MARK, CONST_CS | CONST_PERSISTENT);
     155                 : #else
     156                 : # define GLOB_MARK 0
     157                 : #endif
     158                 : 
     159                 : #ifdef GLOB_NOSORT
     160           17007 :         REGISTER_LONG_CONSTANT("GLOB_NOSORT", GLOB_NOSORT, CONST_CS | CONST_PERSISTENT);
     161                 : #else 
     162                 : # define GLOB_NOSORT 0
     163                 : #endif
     164                 : 
     165                 : #ifdef GLOB_NOCHECK
     166           17007 :         REGISTER_LONG_CONSTANT("GLOB_NOCHECK", GLOB_NOCHECK, CONST_CS | CONST_PERSISTENT);
     167                 : #else 
     168                 : # define GLOB_NOCHECK 0
     169                 : #endif
     170                 : 
     171                 : #ifdef GLOB_NOESCAPE
     172           17007 :         REGISTER_LONG_CONSTANT("GLOB_NOESCAPE", GLOB_NOESCAPE, CONST_CS | CONST_PERSISTENT);
     173                 : #else 
     174                 : # define GLOB_NOESCAPE 0
     175                 : #endif
     176                 : 
     177                 : #ifdef GLOB_ERR
     178           17007 :         REGISTER_LONG_CONSTANT("GLOB_ERR", GLOB_ERR, CONST_CS | CONST_PERSISTENT);
     179                 : #else 
     180                 : # define GLOB_ERR 0
     181                 : #endif
     182                 : 
     183                 : #ifndef GLOB_ONLYDIR
     184                 : # define GLOB_ONLYDIR (1<<30)
     185                 : # define GLOB_EMULATE_ONLYDIR
     186                 : # define GLOB_FLAGMASK (~GLOB_ONLYDIR)
     187                 : #else
     188                 : # define GLOB_FLAGMASK (~0)
     189                 : #endif
     190                 : 
     191                 : /* This is used for checking validity of passed flags (passing invalid flags causes segfault in glob()!! */
     192                 : #define GLOB_AVAILABLE_FLAGS (0 | GLOB_BRACE | GLOB_MARK | GLOB_NOSORT | GLOB_NOCHECK | GLOB_NOESCAPE | GLOB_ERR | GLOB_ONLYDIR)
     193                 : 
     194           17007 :         REGISTER_LONG_CONSTANT("GLOB_ONLYDIR", GLOB_ONLYDIR, CONST_CS | CONST_PERSISTENT);
     195           17007 :         REGISTER_LONG_CONSTANT("GLOB_AVAILABLE_FLAGS", GLOB_AVAILABLE_FLAGS, CONST_CS | CONST_PERSISTENT);
     196                 : 
     197                 : #endif /* HAVE_GLOB */
     198                 : 
     199           17007 :         return SUCCESS;
     200                 : }
     201                 : /* }}} */
     202                 : 
     203                 : /* {{{ internal functions */
     204                 : static void _php_do_opendir(INTERNAL_FUNCTION_PARAMETERS, int createobject)
     205            3311 : {
     206                 :         zval **ppdir;
     207            3311 :         UChar *udir = NULL;
     208                 :         char *dir;
     209                 :         int dir_len, udir_len;
     210            3311 :         zval *zcontext = NULL;
     211            3311 :         php_stream_context *context = NULL;
     212                 :         php_stream *dirp;
     213                 : 
     214            3311 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|r", &ppdir, &zcontext) == FAILURE) {
     215              56 :                 return;
     216                 :         }
     217                 : 
     218            3255 :         RETVAL_FALSE;
     219                 : 
     220            3255 :         if (createobject && Z_TYPE_PP(ppdir) == IS_UNICODE) {
     221                 :                 /* Save for later */
     222              45 :                 udir = eustrndup(Z_USTRVAL_PP(ppdir), Z_USTRLEN_PP(ppdir));
     223              45 :                 udir_len = Z_USTRLEN_PP(ppdir);
     224                 :         }
     225                 : 
     226            3255 :         context = php_stream_context_from_zval(zcontext, 0);
     227            3255 :         if (FAILURE == php_stream_path_param_encode(ppdir, &dir, &dir_len, REPORT_ERRORS, context)) {
     228               0 :                 goto opendir_cleanup;
     229                 :         }
     230                 : 
     231            3255 :         dirp = php_stream_opendir(dir, REPORT_ERRORS, context);
     232            3255 :         if (dirp == NULL) {
     233              86 :                 goto opendir_cleanup;
     234                 :         }
     235                 : 
     236            3169 :         dirp->flags |= PHP_STREAM_FLAG_NO_FCLOSE;
     237                 :                 
     238            3169 :         php_set_default_dir(dirp->rsrc_id TSRMLS_CC);
     239                 : 
     240            3169 :         if (createobject) {
     241              22 :                 object_init_ex(return_value, dir_class_entry_ptr);
     242              22 :                 if (udir) {
     243              22 :                         add_property_unicodel(return_value, "path", udir, udir_len, 0);
     244                 : 
     245                 :                         /* Avoid auto-cleanup */
     246              22 :                         udir = NULL;
     247                 :                 } else {
     248               0 :                         add_property_stringl(return_value, "path", dir, dir_len, 1);
     249                 :                 }
     250              22 :                 add_property_resource(return_value, "handle", dirp->rsrc_id);
     251                 :                 php_stream_auto_cleanup(dirp); /* so we don't get warnings under debug */
     252                 :         } else {
     253            3147 :                 php_stream_to_zval(dirp, return_value);
     254                 :         }
     255                 : 
     256            3255 : opendir_cleanup:
     257            3255 :         if (udir) {
     258              23 :                 efree(udir);
     259                 :         }
     260                 : }
     261                 : /* }}} */
     262                 : 
     263                 : /* {{{ proto mixed opendir(string path[, resource context]) U
     264                 :    Open a directory and return a dir_handle */
     265                 : PHP_FUNCTION(opendir)
     266            3220 : {
     267            3220 :         _php_do_opendir(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
     268            3220 : }
     269                 : /* }}} */
     270                 : 
     271                 : /* {{{ proto object dir(string directory[, resource context]) U
     272                 :    Directory class with properties, handle and class and methods read, rewind and close */
     273                 : PHP_FUNCTION(getdir)
     274              91 : {
     275              91 :         _php_do_opendir(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
     276              91 : }
     277                 : /* }}} */
     278                 : 
     279                 : /* {{{ proto void closedir([resource dir_handle]) U
     280                 :    Close directory connection identified by the dir_handle */
     281                 : PHP_FUNCTION(closedir)
     282            3151 : {
     283            3151 :         zval *id = NULL, **tmp, *myself;
     284                 :         php_stream *dirp;
     285                 :         int rsrc_id;
     286                 : 
     287            3151 :         FETCH_DIRP();
     288                 : 
     289            3122 :         if (!(dirp->flags & PHP_STREAM_FLAG_IS_DIR)) {
     290               1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a valid Directory resource", dirp->rsrc_id);
     291               1 :                 RETURN_FALSE;
     292                 :         }
     293                 : 
     294            3121 :         rsrc_id = dirp->rsrc_id;
     295            3121 :         zend_list_delete(dirp->rsrc_id);
     296                 : 
     297            3121 :         if (rsrc_id == DIRG(default_dir)) {
     298            2113 :                 php_set_default_dir(-1 TSRMLS_CC);
     299                 :         }
     300                 : }
     301                 : /* }}} */
     302                 : 
     303                 : #if defined(HAVE_CHROOT) && !defined(ZTS) && ENABLE_CHROOT_FUNC
     304                 : /* {{{ proto bool chroot(string directory) U
     305                 :    Change root directory */
     306                 : PHP_FUNCTION(chroot)
     307               0 : {
     308                 :         zval **ppstr;
     309                 :         char *str;
     310                 :         int ret, str_len;
     311                 :         
     312               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &ppstr) == FAILURE ||
     313                 :                 php_stream_path_param_encode(ppstr, &str, &str_len, REPORT_ERRORS, FG(default_context)) == FAILURE) {
     314               0 :                 return;
     315                 :         }
     316                 :         
     317               0 :         ret = chroot(str);
     318               0 :         if (ret != 0) {
     319               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (errno %d)", strerror(errno), errno);
     320               0 :                 RETURN_FALSE;
     321                 :         }
     322                 : 
     323               0 :         php_clear_stat_cache(1, NULL, 0 TSRMLS_CC);
     324                 :         
     325               0 :         ret = chdir("/");
     326                 :         
     327               0 :         if (ret != 0) {
     328               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (errno %d)", strerror(errno), errno);
     329               0 :                 RETURN_FALSE;
     330                 :         }
     331                 : 
     332               0 :         RETURN_TRUE;
     333                 : }
     334                 : /* }}} */
     335                 : #endif
     336                 : 
     337                 : /* {{{ proto bool chdir(string directory) U
     338                 :    Change the current directory */
     339                 : PHP_FUNCTION(chdir)
     340             288 : {
     341                 :         zval **ppstr;
     342                 :         char *str;
     343                 :         int ret, str_len;
     344                 :         
     345             288 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &ppstr) == FAILURE ||
     346                 :                 php_stream_path_param_encode(ppstr, &str, &str_len, REPORT_ERRORS, FG(default_context)) == FAILURE) {
     347               2 :                 return;
     348                 :         }
     349             286 :         if (php_check_open_basedir(str TSRMLS_CC)) {
     350               6 :                 RETURN_FALSE;
     351                 :         }
     352             280 :         ret = VCWD_CHDIR(str);
     353             280 :         if (ret != 0) {
     354              23 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (errno %d)", strerror(errno), errno);
     355              23 :                 RETURN_FALSE;
     356                 :         }
     357                 : 
     358             257 :         if (BG(CurrentStatFile) && !IS_ABSOLUTE_PATH(BG(CurrentStatFile), strlen(BG(CurrentStatFile)))) {
     359               1 :                 efree(BG(CurrentStatFile));
     360               1 :                 BG(CurrentStatFile) = NULL;
     361                 :         }
     362             257 :         if (BG(CurrentLStatFile) && !IS_ABSOLUTE_PATH(BG(CurrentLStatFile), strlen(BG(CurrentLStatFile)))) {
     363               0 :                 efree(BG(CurrentLStatFile));
     364               0 :                 BG(CurrentLStatFile) = NULL;
     365                 :         }
     366                 : 
     367             257 :         RETURN_TRUE;
     368                 : }
     369                 : /* }}} */
     370                 : 
     371                 : /* {{{ proto mixed getcwd(void) U
     372                 :    Gets the current directory */
     373                 : PHP_FUNCTION(getcwd)
     374             244 : {
     375                 :         char path[MAXPATHLEN];
     376             244 :         char *ret=NULL;
     377                 :         
     378             244 :         if (zend_parse_parameters_none() == FAILURE) {
     379               1 :                 return;
     380                 :         }
     381                 : 
     382                 : #if HAVE_GETCWD
     383             243 :         ret = VCWD_GETCWD(path, MAXPATHLEN);
     384                 : #elif HAVE_GETWD
     385                 :         ret = VCWD_GETWD(path);
     386                 : #endif
     387                 : 
     388             243 :         if (ret) {
     389             243 :                 RETURN_RT_STRING(path, ZSTR_DUPLICATE);
     390                 :         } else {
     391               0 :                 RETURN_FALSE;
     392                 :         }
     393                 : }
     394                 : /* }}} */
     395                 : 
     396                 : /* {{{ proto void rewinddir([resource dir_handle]) U
     397                 :    Rewind dir_handle back to the start */
     398                 : PHP_FUNCTION(rewinddir)
     399              33 : {
     400              33 :         zval *id = NULL, **tmp, *myself;
     401                 :         php_stream *dirp;
     402                 :         
     403              33 :         FETCH_DIRP();
     404                 : 
     405               4 :         if (!(dirp->flags & PHP_STREAM_FLAG_IS_DIR)) {
     406               1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a valid Directory resource", dirp->rsrc_id);
     407               1 :                 RETURN_FALSE;
     408                 :         }
     409                 : 
     410               3 :         php_stream_rewinddir(dirp);
     411                 : }
     412                 : /* }}} */
     413                 : 
     414                 : /* {{{ proto string readdir([resource dir_handle]) U
     415                 :    Read directory entry from dir_handle */
     416                 : PHP_NAMED_FUNCTION(php_if_readdir)
     417           59177 : {
     418           59177 :         zval *id = NULL, **tmp, *myself;
     419                 :         php_stream *dirp;
     420                 :         php_stream_dirent entry;
     421                 : 
     422           59177 :         FETCH_DIRP();
     423                 : 
     424           59147 :         if (!(dirp->flags & PHP_STREAM_FLAG_IS_DIR)) {
     425               1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a valid Directory resource", dirp->rsrc_id);
     426               1 :                 RETURN_FALSE;
     427                 :         }
     428                 : 
     429           59146 :         if (php_stream_readdir(dirp, &entry)) {
     430           56097 :                 RETURN_RT_STRINGL(entry.d_name, strlen(entry.d_name), ZSTR_DUPLICATE);
     431                 :         }
     432            3049 :         RETURN_FALSE;
     433                 : }
     434                 : /* }}} */
     435                 : 
     436                 : #ifdef HAVE_GLOB
     437                 : /* {{{ proto array glob(string pattern [, int flags]) U
     438                 :    Find pathnames matching a pattern */
     439                 : PHP_FUNCTION(glob)
     440             120 : {
     441             120 :         int cwd_skip = 0;
     442                 : #ifdef ZTS
     443                 :         char cwd[MAXPATHLEN];
     444                 :         char work_pattern[MAXPATHLEN];
     445                 :         char *result;
     446                 : #endif
     447                 :         zval **pppattern;
     448             120 :         char *pattern = NULL;
     449                 :         int pattern_len;
     450             120 :         long flags = 0;
     451                 :         glob_t globbuf;
     452                 :         int ret, n;
     453             120 :         zend_bool basedir_limit = 0;
     454                 : 
     455             120 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|l", &pppattern, &flags) == FAILURE ||
     456                 :                 php_stream_path_param_encode(pppattern, &pattern, &pattern_len, REPORT_ERRORS, FG(default_context)) == FAILURE) {
     457               4 :                 return;
     458                 :         }
     459                 : 
     460             116 :         if (pattern_len >= MAXPATHLEN) {
     461               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Pattern exceeds the maximum allowed length of %d characters", MAXPATHLEN);
     462               0 :                 RETURN_FALSE;
     463                 :         }
     464                 : 
     465             116 :         if ((GLOB_AVAILABLE_FLAGS & flags) != flags) {
     466               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "At least one of the passed flags is invalid or not supported on this platform");
     467               0 :                 RETURN_FALSE;
     468                 :         }
     469                 : 
     470                 : #ifdef ZTS 
     471                 :         if (!IS_ABSOLUTE_PATH(pattern, pattern_len)) {
     472                 :                 result = VCWD_GETCWD(cwd, MAXPATHLEN);  
     473                 :                 if (!result) {
     474                 :                         cwd[0] = '\0';
     475                 :                 }
     476                 : #ifdef PHP_WIN32
     477                 :                 if (IS_SLASH(*pattern)) {
     478                 :                         cwd[2] = '\0';
     479                 :                 }
     480                 : #endif
     481                 :                 cwd_skip = strlen(cwd)+1;
     482                 : 
     483                 :                 snprintf(work_pattern, MAXPATHLEN, "%s%c%s", cwd, DEFAULT_SLASH, pattern);
     484                 :                 pattern = work_pattern;
     485                 :         } 
     486                 : #endif
     487                 : 
     488             116 :         memset(&globbuf, 0, sizeof(glob_t));
     489             116 :         globbuf.gl_offs = 0;
     490             116 :         if (0 != (ret = glob(pattern, flags & GLOB_FLAGMASK, NULL, &globbuf))) {
     491                 : #ifdef GLOB_NOMATCH
     492              49 :                 if (GLOB_NOMATCH == ret) {
     493                 :                         /* Some glob implementation simply return no data if no matches
     494                 :                            were found, others return the GLOB_NOMATCH error code.
     495                 :                            We don't want to treat GLOB_NOMATCH as an error condition
     496                 :                            so that PHP glob() behaves the same on both types of 
     497                 :                            implementations and so that 'foreach (glob() as ...'
     498                 :                            can be used for simple glob() calls without further error
     499                 :                            checking.
     500                 :                         */
     501              49 :                         goto no_results;
     502                 :                 }
     503                 : #endif
     504               0 :                 RETURN_FALSE;
     505                 :         }
     506                 : 
     507                 :         /* now catch the FreeBSD style of "no matches" */
     508              67 :         if (!globbuf.gl_pathc || !globbuf.gl_pathv) {
     509              49 : no_results:
     510              49 :                 if (PG(open_basedir) && *PG(open_basedir)) {
     511                 :                         struct stat s;
     512                 : 
     513               1 :                         if (0 != VCWD_STAT(pattern, &s) || S_IFDIR != (s.st_mode & S_IFMT)) {
     514               1 :                                 RETURN_FALSE;
     515                 :                         }
     516                 :                 }
     517              48 :                 array_init(return_value);
     518              48 :                 return;
     519                 :         }
     520                 : 
     521              67 :         array_init(return_value);
     522             198 :         for (n = 0; n < globbuf.gl_pathc; n++) {
     523                 :                 UChar *path;
     524                 :                 int path_len;
     525                 :                 
     526             131 :                 if (PG(open_basedir) && *PG(open_basedir)) {
     527              17 :                         if (php_check_open_basedir_ex(globbuf.gl_pathv[n], 0 TSRMLS_CC)) {
     528              10 :                                 basedir_limit = 1;
     529              10 :                                 continue;
     530                 :                         }
     531                 :                 }
     532                 :                 /* we need to do this everytime since GLOB_ONLYDIR does not guarantee that
     533                 :                  * all directories will be filtered. GNU libc documentation states the
     534                 :                  * following: 
     535                 :                  * If the information about the type of the file is easily available 
     536                 :                  * non-directories will be rejected but no extra work will be done to 
     537                 :                  * determine the information for each file. I.e., the caller must still be 
     538                 :                  * able to filter directories out. 
     539                 :                  */
     540             121 :                 if (flags & GLOB_ONLYDIR) {
     541                 :                         struct stat s;
     542                 : 
     543              19 :                         if (0 != VCWD_STAT(globbuf.gl_pathv[n], &s)) {
     544               0 :                                 continue;
     545                 :                         }
     546                 : 
     547              19 :                         if (S_IFDIR != (s.st_mode & S_IFMT)) {
     548               0 :                                 continue;
     549                 :                         }
     550                 :                 }
     551                 : 
     552             121 :                 if (SUCCESS == php_stream_path_decode(&php_plain_files_wrapper, &path, &path_len, globbuf.gl_pathv[n]+cwd_skip, 
     553                 :                                                         strlen(globbuf.gl_pathv[n]+cwd_skip), REPORT_ERRORS, FG(default_context))) {
     554             121 :                         add_next_index_unicodel(return_value, path, path_len, 0);
     555                 :                 } else {
     556                 :                         /* Fallback on string version, path_decode will emit warning */
     557               0 :                         add_next_index_string(return_value, globbuf.gl_pathv[n]+cwd_skip, 1);
     558                 :                 }
     559                 :         }
     560                 : 
     561              67 :         globfree(&globbuf);
     562                 : 
     563              67 :         if (basedir_limit && !zend_hash_num_elements(Z_ARRVAL_P(return_value))) {
     564               9 :                 zval_dtor(return_value);
     565               9 :                 RETURN_FALSE;
     566                 :         }
     567                 : }
     568                 : /* }}} */
     569                 : #endif 
     570                 : 
     571                 : /* {{{ proto array scandir(string dir [, int sorting_order [, resource context]]) U
     572                 :    List files & directories inside the specified path */
     573                 : PHP_FUNCTION(scandir)
     574             120 : {
     575                 :         zval **ppdirn;
     576                 :         char *dirn;
     577                 :         int dirn_len;
     578             120 :         long flags = 0;
     579                 :         char **namelist;
     580                 :         int n, i;
     581             120 :         zval *zcontext = NULL;
     582             120 :         php_stream_context *context = NULL;
     583                 : 
     584             120 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|lr", &ppdirn, &flags, &zcontext) == FAILURE) {
     585              34 :                 return;
     586                 :         }
     587                 : 
     588              86 :         if (zcontext) {
     589               2 :                 context = php_stream_context_from_zval(zcontext, 0);
     590                 :         }
     591                 : 
     592              86 :         if (FAILURE == php_stream_path_param_encode(ppdirn, &dirn, &dirn_len, REPORT_ERRORS, context)) {
     593               0 :                 RETURN_FALSE;
     594                 :         }
     595                 : 
     596              86 :         if (!flags) {
     597              75 :                 n = php_stream_scandir(dirn, &namelist, context, (void *) php_stream_dirent_alphasort);
     598                 :         } else {
     599              11 :                 n = php_stream_scandir(dirn, &namelist, context, (void *) php_stream_dirent_alphasortr);
     600                 :         }
     601              86 :         if (n < 0) {
     602              41 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "(errno %d): %s", errno, strerror(errno));
     603              41 :                 RETURN_FALSE;
     604                 :         }
     605                 :         
     606              45 :         array_init(return_value);
     607                 : 
     608             184 :         for (i = 0; i < n; i++) {
     609                 :                 UChar *path;
     610                 :                 int path_len;
     611                 : 
     612             139 :                 if (SUCCESS == php_stream_path_decode(NULL, &path, &path_len, namelist[i], strlen(namelist[i]), REPORT_ERRORS, context)) {
     613             139 :                         add_next_index_unicodel(return_value, path, path_len, 0);
     614             139 :                         efree(namelist[i]);
     615                 :                 } else {
     616                 :                         /* Fallback on using the non-unicode version, path_decode will emit the warning for us */
     617               0 :                         add_next_index_string(return_value, namelist[i], 0);
     618                 :                 }
     619                 :         }
     620                 : 
     621              45 :         if (n) {
     622              45 :                 efree(namelist);
     623                 :         }
     624                 : }
     625                 : /* }}} */
     626                 : 
     627                 : /*
     628                 :  * Local variables:
     629                 :  * tab-width: 4
     630                 :  * c-basic-offset: 4
     631                 :  * End:
     632                 :  * vim600: sw=4 ts=4 fdm=marker
     633                 :  * vim<600: sw=4 ts=4
     634                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Mon, 23 Nov 2009 17:39:40 +0000 (35 hours ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.