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: 157 167 94.0 %
Date: 2014-04-19 Functions: 13 13 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Sun, 20 Apr 2014 03:52:17 +0000 (3 days ago)

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