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

Generated by: LCOV version 1.10

Generated at Sun, 18 Sep 2016 08:20:17 +0000 (9 days ago)

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