Annotation of embedaddon/php/win32/readdir.c, revision 1.1.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>