Return to readdir.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / win32 |
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) {
1.1.1.2 ! misho 48: free(filespec);
1.1 misho 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: }