8 /**********************************************************************
9 * Implement dirent-style opendir/readdir/rewinddir/closedir on Win32
11 * Functions defined are opendir(), readdir(), rewinddir() and
12 * closedir() with the same prototypes as the normal dirent.h
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.
19 * The DIR typedef is not compatible with Unix.
20 **********************************************************************/
22 DIR *opendir(const char *dir
)
28 char resolved_path_buff
[MAXPATHLEN
];
31 if (!VCWD_REALPATH(dir
, resolved_path_buff
)) {
35 filespec
= (char *)malloc(strlen(resolved_path_buff
) + 2 + 1);
36 if (filespec
== NULL
) {
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
, "\\*");
46 dp
= (DIR *) malloc(sizeof(DIR));
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
) {
63 dp
->dir
= strdup(resolved_path_buff
);
70 struct dirent
*readdir(DIR *dp
)
72 if (!dp
|| dp
->finished
)
75 if (dp
->offset
!= 0) {
76 if (FindNextFile(dp
->handle
, &(dp
->fileinfo
)) == 0) {
83 strlcpy(dp
->dent
.d_name
, dp
->fileinfo
.cFileName
, _MAX_FNAME
+1);
85 dp
->dent
.d_reclen
= strlen(dp
->dent
.d_name
);
86 dp
->dent
.d_off
= dp
->offset
;
91 int readdir_r(DIR *dp
, struct dirent
*entry
, struct dirent
**result
)
93 if (!dp
|| dp
->finished
) {
98 if (dp
->offset
!= 0) {
99 if (FindNextFile(dp
->handle
, &(dp
->fileinfo
)) == 0) {
107 strlcpy(dp
->dent
.d_name
, dp
->fileinfo
.cFileName
, _MAX_FNAME
+1);
109 dp
->dent
.d_reclen
= strlen(dp
->dent
.d_name
);
110 dp
->dent
.d_off
= dp
->offset
;
112 memcpy(entry
, &dp
->dent
, sizeof(*entry
));
119 int closedir(DIR *dp
)
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
);
136 int rewinddir(DIR *dp
)
138 /* Re-set to the beginning */
143 FindClose(dp
->handle
);
148 filespec
= (char *)malloc(strlen(dp
->dir
) + 2 + 1);
149 if (filespec
== NULL
) {
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
, "/*");
160 if ((handle
= FindFirstFile(filespec
, &(dp
->fileinfo
))) == INVALID_HANDLE_VALUE
) {