Annotation of embedaddon/php/win32/readdir.c, revision 1.1
1.1 ! misho 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: return NULL;
! 49: }
! 50: dp->offset = 0;
! 51: dp->finished = 0;
! 52:
! 53: if ((handle = FindFirstFile(filespec, &(dp->fileinfo))) == INVALID_HANDLE_VALUE) {
! 54: DWORD err = GetLastError();
! 55: if (err == ERROR_NO_MORE_FILES || err == ERROR_FILE_NOT_FOUND) {
! 56: dp->finished = 1;
! 57: } else {
! 58: free(dp);
! 59: free(filespec);
! 60: return NULL;
! 61: }
! 62: }
! 63: dp->dir = strdup(resolved_path_buff);
! 64: dp->handle = handle;
! 65: free(filespec);
! 66:
! 67: return dp;
! 68: }
! 69:
! 70: struct dirent *readdir(DIR *dp)
! 71: {
! 72: if (!dp || dp->finished)
! 73: return NULL;
! 74:
! 75: if (dp->offset != 0) {
! 76: if (FindNextFile(dp->handle, &(dp->fileinfo)) == 0) {
! 77: dp->finished = 1;
! 78: return NULL;
! 79: }
! 80: }
! 81: dp->offset++;
! 82:
! 83: strlcpy(dp->dent.d_name, dp->fileinfo.cFileName, _MAX_FNAME+1);
! 84: dp->dent.d_ino = 1;
! 85: dp->dent.d_reclen = strlen(dp->dent.d_name);
! 86: dp->dent.d_off = dp->offset;
! 87:
! 88: return &(dp->dent);
! 89: }
! 90:
! 91: int readdir_r(DIR *dp, struct dirent *entry, struct dirent **result)
! 92: {
! 93: if (!dp || dp->finished) {
! 94: *result = NULL;
! 95: return 0;
! 96: }
! 97:
! 98: if (dp->offset != 0) {
! 99: if (FindNextFile(dp->handle, &(dp->fileinfo)) == 0) {
! 100: dp->finished = 1;
! 101: *result = NULL;
! 102: return 0;
! 103: }
! 104: }
! 105: dp->offset++;
! 106:
! 107: strlcpy(dp->dent.d_name, dp->fileinfo.cFileName, _MAX_FNAME+1);
! 108: dp->dent.d_ino = 1;
! 109: dp->dent.d_reclen = strlen(dp->dent.d_name);
! 110: dp->dent.d_off = dp->offset;
! 111:
! 112: memcpy(entry, &dp->dent, sizeof(*entry));
! 113:
! 114: *result = &dp->dent;
! 115:
! 116: return 0;
! 117: }
! 118:
! 119: int closedir(DIR *dp)
! 120: {
! 121: if (!dp)
! 122: return 0;
! 123: /* It is valid to scan an empty directory but we have an invalid
! 124: handle in this case (no first file found). */
! 125: if (dp->handle != INVALID_HANDLE_VALUE) {
! 126: FindClose(dp->handle);
! 127: }
! 128: if (dp->dir)
! 129: free(dp->dir);
! 130: if (dp)
! 131: free(dp);
! 132:
! 133: return 0;
! 134: }
! 135:
! 136: int rewinddir(DIR *dp)
! 137: {
! 138: /* Re-set to the beginning */
! 139: char *filespec;
! 140: HANDLE handle;
! 141: int index;
! 142:
! 143: FindClose(dp->handle);
! 144:
! 145: dp->offset = 0;
! 146: dp->finished = 0;
! 147:
! 148: filespec = (char *)malloc(strlen(dp->dir) + 2 + 1);
! 149: if (filespec == NULL) {
! 150: return -1;
! 151: }
! 152:
! 153: strcpy(filespec, dp->dir);
! 154: index = strlen(filespec) - 1;
! 155: if (index >= 0 && (filespec[index] == '/' ||
! 156: (filespec[index] == '\\' && (index == 0 || !IsDBCSLeadByte(filespec[index-1])))))
! 157: filespec[index] = '\0';
! 158: strcat(filespec, "/*");
! 159:
! 160: if ((handle = FindFirstFile(filespec, &(dp->fileinfo))) == INVALID_HANDLE_VALUE) {
! 161: dp->finished = 1;
! 162: }
! 163:
! 164: dp->handle = handle;
! 165: free(filespec);
! 166:
! 167: return 0;
! 168: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>