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

LCOV - code coverage report
Current view: top level - ext/standard - dir.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 158 168 94.0 %
Date: 2015-05-21 Functions: 13 13 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP Version 7                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1997-2015 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$ */
      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             :         zend_resource *default_dir;
      56             : } php_dir_globals;
      57             : 
      58             : #ifdef ZTS
      59             : #define DIRG(v) ZEND_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(), "|r", &id) == FAILURE) { \
      79             :                 return; \
      80             :         } \
      81             :         if (ZEND_NUM_ARGS() == 0) { \
      82             :                 myself = getThis(); \
      83             :                 if (myself) { \
      84             :                         if ((tmp = zend_hash_str_find(Z_OBJPROP_P(myself), "handle", sizeof("handle")-1)) == NULL) { \
      85             :                                 php_error_docref(NULL, E_WARNING, "Unable to find my handle property"); \
      86             :                                 RETURN_FALSE; \
      87             :                         } \
      88             :                         if ((dirp = (php_stream *)zend_fetch_resource_ex(tmp, "Directory", php_file_le_stream())) == NULL) { \
      89             :                                 RETURN_FALSE; \
      90             :                         } \
      91             :                 } else { \
      92             :                         if (!DIRG(default_dir) || \
      93             :                                 (dirp = (php_stream *)zend_fetch_resource(DIRG(default_dir), "Directory", php_file_le_stream())) == NULL) { \
      94             :                                 RETURN_FALSE; \
      95             :                         } \
      96             :                 } \
      97             :         } else { \
      98             :                 if ((dirp = (php_stream *)zend_fetch_resource(Z_RES_P(id), "Directory", php_file_le_stream())) == NULL) { \
      99             :                         RETURN_FALSE; \
     100             :                 } \
     101             :         }
     102             : 
     103             : /* {{{ arginfo */
     104             : ZEND_BEGIN_ARG_INFO_EX(arginfo_dir, 0, 0, 0)
     105             :         ZEND_ARG_INFO(0, dir_handle)
     106             : ZEND_END_ARG_INFO()
     107             : /* }}} */
     108             : 
     109             : static const zend_function_entry php_dir_class_functions[] = {
     110             :         PHP_FALIAS(close,       closedir,               arginfo_dir)
     111             :         PHP_FALIAS(rewind,      rewinddir,              arginfo_dir)
     112             :         PHP_NAMED_FE(read,  php_if_readdir, arginfo_dir)
     113             :         {NULL, NULL, NULL}
     114             : };
     115             : 
     116             : 
     117        1260 : static void php_set_default_dir(zend_resource *res)
     118             : {
     119        1260 :         if (DIRG(default_dir)) {
     120         733 :                 zend_list_delete(DIRG(default_dir));
     121             :         }
     122             : 
     123        1260 :         if (res) {
     124         755 :                 GC_REFCOUNT(res)++;
     125             :         }
     126             : 
     127        1260 :         DIRG(default_dir) = res;
     128        1260 : }
     129             : 
     130       20873 : PHP_RINIT_FUNCTION(dir)
     131             : {
     132       20873 :         DIRG(default_dir) = NULL;
     133       20873 :         return SUCCESS;
     134             : }
     135             : 
     136       20916 : PHP_MINIT_FUNCTION(dir)
     137             : {
     138             :         static char dirsep_str[2], pathsep_str[2];
     139             :         zend_class_entry dir_class_entry;
     140             : 
     141       20916 :         INIT_CLASS_ENTRY(dir_class_entry, "Directory", php_dir_class_functions);
     142       20916 :         dir_class_entry_ptr = zend_register_internal_class(&dir_class_entry);
     143             : 
     144             : #ifdef ZTS
     145             :         ts_allocate_id(&dir_globals_id, sizeof(php_dir_globals), NULL, NULL);
     146             : #endif
     147             : 
     148       20916 :         dirsep_str[0] = DEFAULT_SLASH;
     149       20916 :         dirsep_str[1] = '\0';
     150       20916 :         REGISTER_STRING_CONSTANT("DIRECTORY_SEPARATOR", dirsep_str, CONST_CS|CONST_PERSISTENT);
     151             : 
     152       20916 :         pathsep_str[0] = ZEND_PATHS_SEPARATOR;
     153       20916 :         pathsep_str[1] = '\0';
     154       20916 :         REGISTER_STRING_CONSTANT("PATH_SEPARATOR", pathsep_str, CONST_CS|CONST_PERSISTENT);
     155             : 
     156       20916 :         REGISTER_LONG_CONSTANT("SCANDIR_SORT_ASCENDING",  PHP_SCANDIR_SORT_ASCENDING,  CONST_CS | CONST_PERSISTENT);
     157       20916 :         REGISTER_LONG_CONSTANT("SCANDIR_SORT_DESCENDING", PHP_SCANDIR_SORT_DESCENDING, CONST_CS | CONST_PERSISTENT);
     158       20916 :         REGISTER_LONG_CONSTANT("SCANDIR_SORT_NONE",       PHP_SCANDIR_SORT_NONE,       CONST_CS | CONST_PERSISTENT);
     159             : 
     160             : #ifdef HAVE_GLOB
     161             : 
     162             : #ifdef GLOB_BRACE
     163       20916 :         REGISTER_LONG_CONSTANT("GLOB_BRACE", GLOB_BRACE, CONST_CS | CONST_PERSISTENT);
     164             : #else
     165             : # define GLOB_BRACE 0
     166             : #endif
     167             : 
     168             : #ifdef GLOB_MARK
     169       20916 :         REGISTER_LONG_CONSTANT("GLOB_MARK", GLOB_MARK, CONST_CS | CONST_PERSISTENT);
     170             : #else
     171             : # define GLOB_MARK 0
     172             : #endif
     173             : 
     174             : #ifdef GLOB_NOSORT
     175       20916 :         REGISTER_LONG_CONSTANT("GLOB_NOSORT", GLOB_NOSORT, CONST_CS | CONST_PERSISTENT);
     176             : #else
     177             : # define GLOB_NOSORT 0
     178             : #endif
     179             : 
     180             : #ifdef GLOB_NOCHECK
     181       20916 :         REGISTER_LONG_CONSTANT("GLOB_NOCHECK", GLOB_NOCHECK, CONST_CS | CONST_PERSISTENT);
     182             : #else
     183             : # define GLOB_NOCHECK 0
     184             : #endif
     185             : 
     186             : #ifdef GLOB_NOESCAPE
     187       20916 :         REGISTER_LONG_CONSTANT("GLOB_NOESCAPE", GLOB_NOESCAPE, CONST_CS | CONST_PERSISTENT);
     188             : #else
     189             : # define GLOB_NOESCAPE 0
     190             : #endif
     191             : 
     192             : #ifdef GLOB_ERR
     193       20916 :         REGISTER_LONG_CONSTANT("GLOB_ERR", GLOB_ERR, CONST_CS | CONST_PERSISTENT);
     194             : #else
     195             : # define GLOB_ERR 0
     196             : #endif
     197             : 
     198             : #ifndef GLOB_ONLYDIR
     199             : # define GLOB_ONLYDIR (1<<30)
     200             : # define GLOB_EMULATE_ONLYDIR
     201             : # define GLOB_FLAGMASK (~GLOB_ONLYDIR)
     202             : #else
     203             : # define GLOB_FLAGMASK (~0)
     204             : #endif
     205             : 
     206             : /* This is used for checking validity of passed flags (passing invalid flags causes segfault in glob()!! */
     207             : #define GLOB_AVAILABLE_FLAGS (0 | GLOB_BRACE | GLOB_MARK | GLOB_NOSORT | GLOB_NOCHECK | GLOB_NOESCAPE | GLOB_ERR | GLOB_ONLYDIR)
     208             : 
     209       20916 :         REGISTER_LONG_CONSTANT("GLOB_ONLYDIR", GLOB_ONLYDIR, CONST_CS | CONST_PERSISTENT);
     210       20916 :         REGISTER_LONG_CONSTANT("GLOB_AVAILABLE_FLAGS", GLOB_AVAILABLE_FLAGS, CONST_CS | CONST_PERSISTENT);
     211             : 
     212             : #endif /* HAVE_GLOB */
     213             : 
     214       20916 :         return SUCCESS;
     215             : }
     216             : /* }}} */
     217             : 
     218             : /* {{{ internal functions */
     219         897 : static void _php_do_opendir(INTERNAL_FUNCTION_PARAMETERS, int createobject)
     220             : {
     221             :         char *dirname;
     222             :         size_t dir_len;
     223         897 :         zval *zcontext = NULL;
     224         897 :         php_stream_context *context = NULL;
     225             :         php_stream *dirp;
     226             : 
     227         897 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|r", &dirname, &dir_len, &zcontext) == FAILURE) {
     228          66 :                 RETURN_NULL();
     229             :         }
     230             : 
     231         831 :         context = php_stream_context_from_zval(zcontext, 0);
     232             : 
     233         831 :         dirp = php_stream_opendir(dirname, REPORT_ERRORS, context);
     234             : 
     235         831 :         if (dirp == NULL) {
     236          76 :                 RETURN_FALSE;
     237             :         }
     238             : 
     239         755 :         dirp->flags |= PHP_STREAM_FLAG_NO_FCLOSE;
     240             : 
     241         755 :         php_set_default_dir(dirp->res);
     242             : 
     243         755 :         if (createobject) {
     244          22 :                 object_init_ex(return_value, dir_class_entry_ptr);
     245          22 :                 add_property_stringl(return_value, "path", dirname, dir_len);
     246          22 :                 add_property_resource(return_value, "handle", dirp->res);
     247          22 :                 php_stream_auto_cleanup(dirp); /* so we don't get warnings under debug */
     248             :         } else {
     249         733 :                 php_stream_to_zval(dirp, return_value);
     250             :         }
     251             : }
     252             : /* }}} */
     253             : 
     254             : /* {{{ proto mixed opendir(string path[, resource context])
     255             :    Open a directory and return a dir_handle */
     256         806 : PHP_FUNCTION(opendir)
     257             : {
     258         806 :         _php_do_opendir(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
     259         806 : }
     260             : /* }}} */
     261             : 
     262             : /* {{{ proto object dir(string directory[, resource context])
     263             :    Directory class with properties, handle and class and methods read, rewind and close */
     264          91 : PHP_FUNCTION(getdir)
     265             : {
     266          91 :         _php_do_opendir(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
     267          91 : }
     268             : /* }}} */
     269             : 
     270             : /* {{{ proto void closedir([resource dir_handle])
     271             :    Close directory connection identified by the dir_handle */
     272         745 : PHP_FUNCTION(closedir)
     273             : {
     274         745 :         zval *id = NULL, *tmp, *myself;
     275             :         php_stream *dirp;
     276             :         zend_resource *res;
     277             : 
     278         745 :         FETCH_DIRP();
     279             : 
     280         716 :         if (!(dirp->flags & PHP_STREAM_FLAG_IS_DIR)) {
     281           1 :                 php_error_docref(NULL, E_WARNING, "%pd is not a valid Directory resource", dirp->res->handle);
     282           1 :                 RETURN_FALSE;
     283             :         }
     284             : 
     285         715 :         res = dirp->res;
     286         715 :         zend_list_close(dirp->res);
     287             : 
     288         715 :         if (res == DIRG(default_dir)) {
     289         505 :                 php_set_default_dir(NULL);
     290             :         }
     291             : }
     292             : /* }}} */
     293             : 
     294             : #if defined(HAVE_CHROOT) && !defined(ZTS) && ENABLE_CHROOT_FUNC
     295             : /* {{{ proto bool chroot(string directory)
     296             :    Change root directory */
     297             : PHP_FUNCTION(chroot)
     298             : {
     299             :         char *str;
     300             :         int ret;
     301             :         size_t str_len;
     302             : 
     303             :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &str, &str_len) == FAILURE) {
     304             :                 RETURN_FALSE;
     305             :         }
     306             : 
     307             :         ret = chroot(str);
     308             :         if (ret != 0) {
     309             :                 php_error_docref(NULL, E_WARNING, "%s (errno %d)", strerror(errno), errno);
     310             :                 RETURN_FALSE;
     311             :         }
     312             : 
     313             :         php_clear_stat_cache(1, NULL, 0);
     314             : 
     315             :         ret = chdir("/");
     316             : 
     317             :         if (ret != 0) {
     318             :                 php_error_docref(NULL, E_WARNING, "%s (errno %d)", strerror(errno), errno);
     319             :                 RETURN_FALSE;
     320             :         }
     321             : 
     322             :         RETURN_TRUE;
     323             : }
     324             : /* }}} */
     325             : #endif
     326             : 
     327             : /* {{{ proto bool chdir(string directory)
     328             :    Change the current directory */
     329         306 : PHP_FUNCTION(chdir)
     330             : {
     331             :         char *str;
     332             :         int ret;
     333             :         size_t str_len;
     334             : 
     335         306 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &str, &str_len) == FAILURE) {
     336           4 :                 RETURN_FALSE;
     337             :         }
     338             : 
     339         302 :         if (php_check_open_basedir(str)) {
     340           6 :                 RETURN_FALSE;
     341             :         }
     342         296 :         ret = VCWD_CHDIR(str);
     343             : 
     344         296 :         if (ret != 0) {
     345          21 :                 php_error_docref(NULL, E_WARNING, "%s (errno %d)", strerror(errno), errno);
     346          21 :                 RETURN_FALSE;
     347             :         }
     348             : 
     349         275 :         if (BG(CurrentStatFile) && !IS_ABSOLUTE_PATH(BG(CurrentStatFile), strlen(BG(CurrentStatFile)))) {
     350           1 :                 efree(BG(CurrentStatFile));
     351           1 :                 BG(CurrentStatFile) = NULL;
     352             :         }
     353         275 :         if (BG(CurrentLStatFile) && !IS_ABSOLUTE_PATH(BG(CurrentLStatFile), strlen(BG(CurrentLStatFile)))) {
     354           0 :                 efree(BG(CurrentLStatFile));
     355           0 :                 BG(CurrentLStatFile) = NULL;
     356             :         }
     357             : 
     358         275 :         RETURN_TRUE;
     359             : }
     360             : /* }}} */
     361             : 
     362             : /* {{{ proto mixed getcwd(void)
     363             :    Gets the current directory */
     364         254 : PHP_FUNCTION(getcwd)
     365             : {
     366             :         char path[MAXPATHLEN];
     367         254 :         char *ret=NULL;
     368             : 
     369         254 :         if (zend_parse_parameters_none() == FAILURE) {
     370           1 :                 return;
     371             :         }
     372             : 
     373             : #if HAVE_GETCWD
     374         253 :         ret = VCWD_GETCWD(path, MAXPATHLEN);
     375             : #elif HAVE_GETWD
     376             :         ret = VCWD_GETWD(path);
     377             : #endif
     378             : 
     379         253 :         if (ret) {
     380         506 :                 RETURN_STRING(path);
     381             :         } else {
     382           0 :                 RETURN_FALSE;
     383             :         }
     384             : }
     385             : /* }}} */
     386             : 
     387             : /* {{{ proto void rewinddir([resource dir_handle])
     388             :    Rewind dir_handle back to the start */
     389          33 : PHP_FUNCTION(rewinddir)
     390             : {
     391          33 :         zval *id = NULL, *tmp, *myself;
     392             :         php_stream *dirp;
     393             : 
     394          33 :         FETCH_DIRP();
     395             : 
     396           4 :         if (!(dirp->flags & PHP_STREAM_FLAG_IS_DIR)) {
     397           1 :                 php_error_docref(NULL, E_WARNING, "%pd is not a valid Directory resource", dirp->res->handle);
     398           1 :                 RETURN_FALSE;
     399             :         }
     400             : 
     401           3 :         php_stream_rewinddir(dirp);
     402             : }
     403             : /* }}} */
     404             : 
     405             : /* {{{ proto string readdir([resource dir_handle])
     406             :    Read directory entry from dir_handle */
     407       28759 : PHP_NAMED_FUNCTION(php_if_readdir)
     408             : {
     409       28759 :         zval *id = NULL, *tmp, *myself;
     410             :         php_stream *dirp;
     411             :         php_stream_dirent entry;
     412             : 
     413       28759 :         FETCH_DIRP();
     414             : 
     415       28729 :         if (!(dirp->flags & PHP_STREAM_FLAG_IS_DIR)) {
     416           1 :                 php_error_docref(NULL, E_WARNING, "%pd is not a valid Directory resource", dirp->res->handle);
     417           1 :                 RETURN_FALSE;
     418             :         }
     419             : 
     420       28728 :         if (php_stream_readdir(dirp, &entry)) {
     421       56186 :                 RETURN_STRINGL(entry.d_name, strlen(entry.d_name));
     422             :         }
     423         635 :         RETURN_FALSE;
     424             : }
     425             : /* }}} */
     426             : 
     427             : #ifdef HAVE_GLOB
     428             : /* {{{ proto array glob(string pattern [, int flags])
     429             :    Find pathnames matching a pattern */
     430         150 : PHP_FUNCTION(glob)
     431             : {
     432         150 :         int cwd_skip = 0;
     433             : #ifdef ZTS
     434             :         char cwd[MAXPATHLEN];
     435             :         char work_pattern[MAXPATHLEN];
     436             :         char *result;
     437             : #endif
     438         150 :         char *pattern = NULL;
     439             :         size_t pattern_len;
     440         150 :         zend_long flags = 0;
     441             :         glob_t globbuf;
     442             :         int n;
     443             :         int ret;
     444         150 :         zend_bool basedir_limit = 0;
     445             : 
     446         150 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|l", &pattern, &pattern_len, &flags) == FAILURE) {
     447          11 :                 return;
     448             :         }
     449             : 
     450         139 :         if (pattern_len >= MAXPATHLEN) {
     451           0 :                 php_error_docref(NULL, E_WARNING, "Pattern exceeds the maximum allowed length of %d characters", MAXPATHLEN);
     452           0 :                 RETURN_FALSE;
     453             :         }
     454             : 
     455         139 :         if ((GLOB_AVAILABLE_FLAGS & flags) != flags) {
     456           0 :                 php_error_docref(NULL, E_WARNING, "At least one of the passed flags is invalid or not supported on this platform");
     457           0 :                 RETURN_FALSE;
     458             :         }
     459             : 
     460             : #ifdef ZTS
     461             :         if (!IS_ABSOLUTE_PATH(pattern, pattern_len)) {
     462             :                 result = VCWD_GETCWD(cwd, MAXPATHLEN);
     463             :                 if (!result) {
     464             :                         cwd[0] = '\0';
     465             :                 }
     466             : #ifdef PHP_WIN32
     467             :                 if (IS_SLASH(*pattern)) {
     468             :                         cwd[2] = '\0';
     469             :                 }
     470             : #endif
     471             :                 cwd_skip = (int)strlen(cwd)+1;
     472             : 
     473             :                 snprintf(work_pattern, MAXPATHLEN, "%s%c%s", cwd, DEFAULT_SLASH, pattern);
     474             :                 pattern = work_pattern;
     475             :         }
     476             : #endif
     477             : 
     478             : 
     479         139 :         memset(&globbuf, 0, sizeof(glob_t));
     480         139 :         globbuf.gl_offs = 0;
     481         139 :         if (0 != (ret = glob(pattern, flags & GLOB_FLAGMASK, NULL, &globbuf))) {
     482             : #ifdef GLOB_NOMATCH
     483          67 :                 if (GLOB_NOMATCH == ret) {
     484             :                         /* Some glob implementation simply return no data if no matches
     485             :                            were found, others return the GLOB_NOMATCH error code.
     486             :                            We don't want to treat GLOB_NOMATCH as an error condition
     487             :                            so that PHP glob() behaves the same on both types of
     488             :                            implementations and so that 'foreach (glob() as ...'
     489             :                            can be used for simple glob() calls without further error
     490             :                            checking.
     491             :                         */
     492          67 :                         goto no_results;
     493             :                 }
     494             : #endif
     495           0 :                 RETURN_FALSE;
     496             :         }
     497             : 
     498             :         /* now catch the FreeBSD style of "no matches" */
     499          72 :         if (!globbuf.gl_pathc || !globbuf.gl_pathv) {
     500             : no_results:
     501             : #ifndef PHP_WIN32
     502             :                 /* Paths containing '*', '?' and some other chars are
     503             :                 illegal on Windows but legit on other platforms. For
     504             :                 this reason the direct basedir check against the glob
     505             :                 query is senseless on windows. For instance while *.txt
     506             :                 is a pretty valid filename on EXT3, it's invalid on NTFS. */
     507          67 :                 if (PG(open_basedir) && *PG(open_basedir)) {
     508          13 :                         if (php_check_open_basedir_ex(pattern, 0)) {
     509           7 :                                 RETURN_FALSE;
     510             :                         }
     511             :                 }
     512             : #endif
     513          60 :                 array_init(return_value);
     514          60 :                 return;
     515             :         }
     516             : 
     517          72 :         array_init(return_value);
     518         225 :         for (n = 0; n < globbuf.gl_pathc; n++) {
     519         153 :                 if (PG(open_basedir) && *PG(open_basedir)) {
     520          19 :                         if (php_check_open_basedir_ex(globbuf.gl_pathv[n], 0)) {
     521          10 :                                 basedir_limit = 1;
     522          10 :                                 continue;
     523             :                         }
     524             :                 }
     525             :                 /* we need to do this every time since GLOB_ONLYDIR does not guarantee that
     526             :                  * all directories will be filtered. GNU libc documentation states the
     527             :                  * following:
     528             :                  * If the information about the type of the file is easily available
     529             :                  * non-directories will be rejected but no extra work will be done to
     530             :                  * determine the information for each file. I.e., the caller must still be
     531             :                  * able to filter directories out.
     532             :                  */
     533         143 :                 if (flags & GLOB_ONLYDIR) {
     534             :                         zend_stat_t s;
     535             : 
     536          28 :                         if (0 != VCWD_STAT(globbuf.gl_pathv[n], &s)) {
     537           0 :                                 continue;
     538             :                         }
     539             : 
     540          28 :                         if (S_IFDIR != (s.st_mode & S_IFMT)) {
     541           0 :                                 continue;
     542             :                         }
     543             :                 }
     544         143 :                 add_next_index_string(return_value, globbuf.gl_pathv[n]+cwd_skip);
     545             :         }
     546             : 
     547          72 :         globfree(&globbuf);
     548             : 
     549          72 :         if (basedir_limit && !zend_hash_num_elements(Z_ARRVAL_P(return_value))) {
     550             :                 zval_dtor(return_value);
     551           9 :                 RETURN_FALSE;
     552             :         }
     553             : }
     554             : /* }}} */
     555             : #endif
     556             : 
     557             : /* {{{ proto array scandir(string dir [, int sorting_order [, resource context]])
     558             :    List files & directories inside the specified path */
     559         125 : PHP_FUNCTION(scandir)
     560             : {
     561             :         char *dirn;
     562             :         size_t dirn_len;
     563         125 :         zend_long flags = 0;
     564             :         zend_string **namelist;
     565             :         int n, i;
     566         125 :         zval *zcontext = NULL;
     567         125 :         php_stream_context *context = NULL;
     568             : 
     569         125 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|lr", &dirn, &dirn_len, &flags, &zcontext) == FAILURE) {
     570          36 :                 return;
     571             :         }
     572             : 
     573          89 :         if (dirn_len < 1) {
     574           9 :                 php_error_docref(NULL, E_WARNING, "Directory name cannot be empty");
     575           9 :                 RETURN_FALSE;
     576             :         }
     577             : 
     578          80 :         if (zcontext) {
     579           2 :                 context = php_stream_context_from_zval(zcontext, 0);
     580             :         }
     581             : 
     582          80 :         if (flags == PHP_SCANDIR_SORT_ASCENDING) {
     583          67 :                 n = php_stream_scandir(dirn, &namelist, context, (void *) php_stream_dirent_alphasort);
     584          13 :         } else if (flags == PHP_SCANDIR_SORT_NONE) {
     585           1 :                 n = php_stream_scandir(dirn, &namelist, context, NULL);
     586             :         } else {
     587          12 :                 n = php_stream_scandir(dirn, &namelist, context, (void *) php_stream_dirent_alphasortr);
     588             :         }
     589          80 :         if (n < 0) {
     590          31 :                 php_error_docref(NULL, E_WARNING, "(errno %d): %s", errno, strerror(errno));
     591          31 :                 RETURN_FALSE;
     592             :         }
     593             : 
     594          49 :         array_init(return_value);
     595             : 
     596         204 :         for (i = 0; i < n; i++) {
     597         155 :                 add_next_index_str(return_value, namelist[i]);
     598             :         }
     599             : 
     600          49 :         if (n) {
     601          49 :                 efree(namelist);
     602             :         }
     603             : }
     604             : /* }}} */
     605             : 
     606             : /*
     607             :  * Local variables:
     608             :  * tab-width: 4
     609             :  * c-basic-offset: 4
     610             :  * End:
     611             :  * vim600: sw=4 ts=4 fdm=marker
     612             :  * vim<600: sw=4 ts=4
     613             :  */

Generated by: LCOV version 1.10

Generated at Thu, 21 May 2015 19:59:05 +0000 (33 hours ago)

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