Back to index

php5  5.3.10
readdir.c
Go to the documentation of this file.
00001 #include <malloc.h>
00002 #include <string.h>
00003 #include <errno.h>
00004 
00005 #include "php.h"
00006 #include "readdir.h"
00007 #include "TSRM.h"
00008 /**********************************************************************
00009  * Implement dirent-style opendir/readdir/rewinddir/closedir on Win32
00010  *
00011  * Functions defined are opendir(), readdir(), rewinddir() and
00012  * closedir() with the same prototypes as the normal dirent.h
00013  * implementation.
00014  *
00015  * Does not implement telldir(), seekdir(), or scandir().  The dirent
00016  * struct is compatible with Unix, except that d_ino is always 1 and
00017  * d_off is made up as we go along.
00018  *
00019  * The DIR typedef is not compatible with Unix.
00020  **********************************************************************/
00021 
00022 DIR *opendir(const char *dir)
00023 {
00024        DIR *dp;
00025        char *filespec;
00026        HANDLE handle;
00027        int index;
00028        char resolved_path_buff[MAXPATHLEN];
00029        TSRMLS_FETCH();
00030 
00031        if (!VCWD_REALPATH(dir, resolved_path_buff)) {
00032               return NULL;
00033        }
00034 
00035        filespec = (char *)malloc(strlen(resolved_path_buff) + 2 + 1);
00036        if (filespec == NULL) {
00037               return NULL;
00038        }
00039        strcpy(filespec, resolved_path_buff);
00040        index = strlen(filespec) - 1;
00041        if (index >= 0 && (filespec[index] == '/' || 
00042           (filespec[index] == '\\' && (index == 0 || !IsDBCSLeadByte(filespec[index-1])))))
00043               filespec[index] = '\0';
00044        strcat(filespec, "\\*");
00045 
00046        dp = (DIR *) malloc(sizeof(DIR));
00047        if (dp == NULL) {
00048               return NULL;
00049        }
00050        dp->offset = 0;
00051        dp->finished = 0;
00052 
00053        if ((handle = FindFirstFile(filespec, &(dp->fileinfo))) == INVALID_HANDLE_VALUE) {
00054               DWORD err = GetLastError();
00055               if (err == ERROR_NO_MORE_FILES || err == ERROR_FILE_NOT_FOUND) {
00056                      dp->finished = 1;
00057               } else {
00058                      free(dp);
00059                      free(filespec);
00060                      return NULL;
00061               }
00062        }
00063        dp->dir = strdup(resolved_path_buff);
00064        dp->handle = handle;
00065        free(filespec);
00066 
00067        return dp;
00068 }
00069 
00070 struct dirent *readdir(DIR *dp)
00071 {
00072        if (!dp || dp->finished)
00073               return NULL;
00074 
00075        if (dp->offset != 0) {
00076               if (FindNextFile(dp->handle, &(dp->fileinfo)) == 0) {
00077                      dp->finished = 1;
00078                      return NULL;
00079               }
00080        }
00081        dp->offset++;
00082 
00083        strlcpy(dp->dent.d_name, dp->fileinfo.cFileName, _MAX_FNAME+1);
00084        dp->dent.d_ino = 1;
00085        dp->dent.d_reclen = strlen(dp->dent.d_name);
00086        dp->dent.d_off = dp->offset;
00087 
00088        return &(dp->dent);
00089 }
00090 
00091 int readdir_r(DIR *dp, struct dirent *entry, struct dirent **result)
00092 {
00093        if (!dp || dp->finished) {
00094               *result = NULL;
00095               return 0;
00096        }
00097 
00098        if (dp->offset != 0) {
00099               if (FindNextFile(dp->handle, &(dp->fileinfo)) == 0) {
00100                      dp->finished = 1;
00101                      *result = NULL;
00102                      return 0;
00103               }
00104        }
00105        dp->offset++;
00106 
00107        strlcpy(dp->dent.d_name, dp->fileinfo.cFileName, _MAX_FNAME+1);
00108        dp->dent.d_ino = 1;
00109        dp->dent.d_reclen = strlen(dp->dent.d_name);
00110        dp->dent.d_off = dp->offset;
00111 
00112        memcpy(entry, &dp->dent, sizeof(*entry));
00113 
00114        *result = &dp->dent;
00115 
00116        return 0;
00117 }
00118 
00119 int closedir(DIR *dp)
00120 {
00121        if (!dp)
00122               return 0;
00123        /* It is valid to scan an empty directory but we have an invalid
00124           handle in this case (no first file found). */
00125        if (dp->handle != INVALID_HANDLE_VALUE) {
00126               FindClose(dp->handle);
00127        }
00128        if (dp->dir)
00129               free(dp->dir);
00130        if (dp)
00131               free(dp);
00132 
00133        return 0;
00134 }
00135 
00136 int rewinddir(DIR *dp)
00137 {
00138        /* Re-set to the beginning */
00139        char *filespec;
00140        HANDLE handle;
00141        int index;
00142 
00143        FindClose(dp->handle);
00144 
00145        dp->offset = 0;
00146        dp->finished = 0;
00147 
00148        filespec = (char *)malloc(strlen(dp->dir) + 2 + 1);
00149        if (filespec == NULL) {
00150               return -1;
00151        }
00152 
00153        strcpy(filespec, dp->dir);
00154        index = strlen(filespec) - 1;
00155        if (index >= 0 && (filespec[index] == '/' || 
00156           (filespec[index] == '\\' && (index == 0 || !IsDBCSLeadByte(filespec[index-1])))))
00157               filespec[index] = '\0';
00158        strcat(filespec, "/*");
00159 
00160        if ((handle = FindFirstFile(filespec, &(dp->fileinfo))) == INVALID_HANDLE_VALUE) {
00161               dp->finished = 1;
00162        }
00163        
00164        dp->handle = handle;
00165        free(filespec);
00166 
00167        return 0;
00168 }