root/win32/readdir.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. opendir
  2. readdir
  3. readdir_r
  4. closedir
  5. rewinddir

   1 #include <malloc.h>
   2 #include <string.h>
   3 #include <errno.h>
   4 
   5 #include "php.h"
   6 #include "readdir.h"
   7 #include "TSRM.h"
   8 /**********************************************************************
   9  * Implement dirent-style opendir/readdir/rewinddir/closedir on Win32
  10  *
  11  * Functions defined are opendir(), readdir(), rewinddir() and
  12  * closedir() with the same prototypes as the normal dirent.h
  13  * implementation.
  14  *
  15  * Does not implement telldir(), seekdir(), or scandir().  The dirent
  16  * struct is compatible with Unix, except that d_ino is always 1 and
  17  * d_off is made up as we go along.
  18  *
  19  * The DIR typedef is not compatible with Unix.
  20  **********************************************************************/
  21 
  22 DIR *opendir(const char *dir)
  23 {
  24         DIR *dp;
  25         char *filespec;
  26         HANDLE handle;
  27         int index;
  28         char resolved_path_buff[MAXPATHLEN];
  29         TSRMLS_FETCH();
  30 
  31         if (!VCWD_REALPATH(dir, resolved_path_buff)) {
  32                 return NULL;
  33         }
  34 
  35         filespec = (char *)malloc(strlen(resolved_path_buff) + 2 + 1);
  36         if (filespec == NULL) {
  37                 return NULL;
  38         }
  39         strcpy(filespec, resolved_path_buff);
  40         index = strlen(filespec) - 1;
  41         if (index >= 0 && (filespec[index] == '/' || 
  42            (filespec[index] == '\\' && (index == 0 || !IsDBCSLeadByte(filespec[index-1])))))
  43                 filespec[index] = '\0';
  44         strcat(filespec, "\\*");
  45 
  46         dp = (DIR *) malloc(sizeof(DIR));
  47         if (dp == NULL) {
  48                 free(filespec);
  49                 return NULL;
  50         }
  51         dp->offset = 0;
  52         dp->finished = 0;
  53 
  54         if ((handle = FindFirstFile(filespec, &(dp->fileinfo))) == INVALID_HANDLE_VALUE) {
  55                 DWORD err = GetLastError();
  56                 if (err == ERROR_NO_MORE_FILES || err == ERROR_FILE_NOT_FOUND) {
  57                         dp->finished = 1;
  58                 } else {
  59                         free(dp);
  60                         free(filespec);
  61                         return NULL;
  62                 }
  63         }
  64         dp->dir = strdup(resolved_path_buff);
  65         dp->handle = handle;
  66         free(filespec);
  67 
  68         return dp;
  69 }
  70 
  71 struct dirent *readdir(DIR *dp)
  72 {
  73         if (!dp || dp->finished)
  74                 return NULL;
  75 
  76         if (dp->offset != 0) {
  77                 if (FindNextFile(dp->handle, &(dp->fileinfo)) == 0) {
  78                         dp->finished = 1;
  79                         return NULL;
  80                 }
  81         }
  82         dp->offset++;
  83 
  84         strlcpy(dp->dent.d_name, dp->fileinfo.cFileName, _MAX_FNAME+1);
  85         dp->dent.d_ino = 1;
  86         dp->dent.d_reclen = strlen(dp->dent.d_name);
  87         dp->dent.d_off = dp->offset;
  88 
  89         return &(dp->dent);
  90 }
  91 
  92 int readdir_r(DIR *dp, struct dirent *entry, struct dirent **result)
  93 {
  94         if (!dp || dp->finished) {
  95                 *result = NULL;
  96                 return 0;
  97         }
  98 
  99         if (dp->offset != 0) {
 100                 if (FindNextFile(dp->handle, &(dp->fileinfo)) == 0) {
 101                         dp->finished = 1;
 102                         *result = NULL;
 103                         return 0;
 104                 }
 105         }
 106         dp->offset++;
 107 
 108         strlcpy(dp->dent.d_name, dp->fileinfo.cFileName, _MAX_FNAME+1);
 109         dp->dent.d_ino = 1;
 110         dp->dent.d_reclen = strlen(dp->dent.d_name);
 111         dp->dent.d_off = dp->offset;
 112 
 113         memcpy(entry, &dp->dent, sizeof(*entry));
 114 
 115         *result = &dp->dent;
 116 
 117         return 0;
 118 }
 119 
 120 int closedir(DIR *dp)
 121 {
 122         if (!dp)
 123                 return 0;
 124         /* It is valid to scan an empty directory but we have an invalid
 125            handle in this case (no first file found). */
 126         if (dp->handle != INVALID_HANDLE_VALUE) {
 127                 FindClose(dp->handle);
 128         }
 129         if (dp->dir)
 130                 free(dp->dir);
 131         if (dp)
 132                 free(dp);
 133 
 134         return 0;
 135 }
 136 
 137 int rewinddir(DIR *dp)
 138 {
 139         /* Re-set to the beginning */
 140         char *filespec;
 141         HANDLE handle;
 142         int index;
 143 
 144         FindClose(dp->handle);
 145 
 146         dp->offset = 0;
 147         dp->finished = 0;
 148 
 149         filespec = (char *)malloc(strlen(dp->dir) + 2 + 1);
 150         if (filespec == NULL) {
 151                 return -1;
 152         }
 153 
 154         strcpy(filespec, dp->dir);
 155         index = strlen(filespec) - 1;
 156         if (index >= 0 && (filespec[index] == '/' || 
 157            (filespec[index] == '\\' && (index == 0 || !IsDBCSLeadByte(filespec[index-1])))))
 158                 filespec[index] = '\0';
 159         strcat(filespec, "/*");
 160 
 161         if ((handle = FindFirstFile(filespec, &(dp->fileinfo))) == INVALID_HANDLE_VALUE) {
 162                 dp->finished = 1;
 163         }
 164         
 165         dp->handle = handle;
 166         free(filespec);
 167 
 168         return 0;
 169 }

/* [<][>][^][v][top][bottom][index][help] */