Back to index

php5  5.3.10
php_scandir.c
Go to the documentation of this file.
00001 /* 
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2012 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.php.net/license/3_01.txt                                  |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Author: Shane Caraveo <shane@caraveo.com>                            |
00016    |         Ilia Alshanetsky <ilia@prohost.org>                          |
00017    +----------------------------------------------------------------------+
00018  */
00019 
00020 /* $Id: php_scandir.c 321634 2012-01-01 13:15:04Z felipe $ */
00021 
00022 #include "php.h"
00023 #include "php_scandir.h"
00024 
00025 #ifdef HAVE_SYS_TYPES_H
00026 #include <sys/types.h>
00027 #endif
00028 
00029 #ifdef HAVE_DIRENT_H
00030 #include <dirent.h>
00031 #endif
00032 
00033 #ifndef HAVE_SCANDIR
00034 
00035 #ifdef PHP_WIN32
00036 #include "win32/param.h"
00037 #include "win32/readdir.h"
00038 #endif  
00039 
00040 #include <stdlib.h>
00041 #ifndef NETWARE
00042 #include <search.h>
00043 #endif
00044 
00045 #endif /* HAVE_SCANDIR */
00046 
00047 #ifndef HAVE_ALPHASORT
00048 
00049 #ifdef HAVE_STRING_H
00050 #include <string.h>
00051 #endif
00052 
00053 PHPAPI int php_alphasort(const struct dirent **a, const struct dirent **b)
00054 {
00055        return strcoll((*a)->d_name,(*b)->d_name);
00056 }
00057 #endif /* HAVE_ALPHASORT */
00058 
00059 #ifndef HAVE_SCANDIR
00060 PHPAPI int php_scandir(const char *dirname, struct dirent **namelist[], int (*selector) (const struct dirent *entry), int (*compare) (const struct dirent **a, const struct dirent **b))
00061 {
00062        DIR *dirp = NULL;
00063        struct dirent **vector = NULL;
00064        int vector_size = 0;
00065        int nfiles = 0;
00066        char entry[sizeof(struct dirent)+MAXPATHLEN];
00067        struct dirent *dp = (struct dirent *)&entry;
00068 
00069        if (namelist == NULL) {
00070               return -1;
00071        }
00072 
00073        if (!(dirp = opendir(dirname))) {
00074               return -1;
00075        }
00076 
00077        while (!php_readdir_r(dirp, (struct dirent *)entry, &dp) && dp) {
00078               int dsize = 0;
00079               struct dirent *newdp = NULL;
00080 
00081               if (selector && (*selector)(dp) == 0) {
00082                      continue;
00083               }
00084 
00085               if (nfiles == vector_size) {
00086                      struct dirent **newv;
00087                      if (vector_size == 0) {
00088                             vector_size = 10;
00089                      } else { 
00090                             vector_size *= 2;
00091                      }
00092 
00093                      newv = (struct dirent **) realloc (vector, vector_size * sizeof (struct dirent *));
00094                      if (!newv) {
00095                             return -1;
00096                      }
00097                      vector = newv;
00098               }
00099 
00100               dsize = sizeof (struct dirent) + ((strlen(dp->d_name) + 1) * sizeof(char));
00101               newdp = (struct dirent *) malloc(dsize);
00102 
00103               if (newdp == NULL) {
00104                      goto fail;
00105               }
00106 
00107               vector[nfiles++] = (struct dirent *) memcpy(newdp, dp, dsize);
00108        }
00109 
00110        closedir(dirp);
00111 
00112        *namelist = vector;
00113 
00114        if (compare) {
00115               qsort (*namelist, nfiles, sizeof(struct dirent *), compare);
00116        }
00117 
00118        return nfiles;
00119 
00120 fail:
00121        while (nfiles-- > 0) {
00122               free(vector[nfiles]);
00123        }
00124        free(vector);
00125        return -1;    
00126 }
00127 #endif
00128 
00129 /*
00130  * Local variables:
00131  * tab-width: 4
00132  * c-basic-offset: 4
00133  * End:
00134  * vim600: sw=4 ts=4 fdm=marker
00135  * vim<600: sw=4 ts=4
00136  */