aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--win32/dirent.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/win32/dirent.c b/win32/dirent.c
index 795fc779c..f0e8deae2 100644
--- a/win32/dirent.c
+++ b/win32/dirent.c
@@ -3,7 +3,9 @@
3struct DIR { 3struct DIR {
4 struct dirent dd_dir; 4 struct dirent dd_dir;
5 HANDLE dd_handle; /* FindFirstFile handle */ 5 HANDLE dd_handle; /* FindFirstFile handle */
6 int dd_stat; /* 0-based index */ 6 int not_first;
7 int got_dot;
8 int got_dotdot;
7}; 9};
8 10
9static inline void finddata2dirent(struct dirent *ent, WIN32_FIND_DATAA *fdata) 11static inline void finddata2dirent(struct dirent *ent, WIN32_FIND_DATAA *fdata)
@@ -59,9 +61,11 @@ DIR *opendir(const char *name)
59 } 61 }
60 62
61 /* initialize DIR structure and copy first dir entry */ 63 /* initialize DIR structure and copy first dir entry */
62 dir = xmalloc(sizeof(DIR)); 64 dir = xzalloc(sizeof(DIR));
63 dir->dd_handle = h; 65 dir->dd_handle = h;
64 dir->dd_stat = 0; 66 /* dir->not_first = 0; */
67 /* dir->got_dot = 0; */
68 /* dir->got_dotdot = 0; */
65 finddata2dirent(&dir->dd_dir, &fdata); 69 finddata2dirent(&dir->dd_dir, &fdata);
66 return dir; 70 return dir;
67} 71}
@@ -74,11 +78,17 @@ struct dirent *readdir(DIR *dir)
74 } 78 }
75 79
76 /* if first entry, dirent has already been set up by opendir */ 80 /* if first entry, dirent has already been set up by opendir */
77 if (dir->dd_stat) { 81 if (dir->not_first) {
78 /* get next entry and convert from WIN32_FIND_DATA to dirent */ 82 /* get next entry and convert from WIN32_FIND_DATA to dirent */
79 WIN32_FIND_DATAA fdata; 83 WIN32_FIND_DATAA fdata;
80 if (FindNextFileA(dir->dd_handle, &fdata)) { 84 if (FindNextFileA(dir->dd_handle, &fdata)) {
81 finddata2dirent(&dir->dd_dir, &fdata); 85 finddata2dirent(&dir->dd_dir, &fdata);
86 } else if (!dir->got_dot) {
87 strcpy(dir->dd_dir.d_name, ".");
88 dir->dd_dir.d_type = DT_DIR;
89 } else if (!dir->got_dotdot) {
90 strcpy(dir->dd_dir.d_name, "..");
91 dir->dd_dir.d_type = DT_DIR;
82 } else { 92 } else {
83 DWORD lasterr = GetLastError(); 93 DWORD lasterr = GetLastError();
84 /* POSIX says you shouldn't set errno when readdir can't 94 /* POSIX says you shouldn't set errno when readdir can't
@@ -89,7 +99,15 @@ struct dirent *readdir(DIR *dir)
89 } 99 }
90 } 100 }
91 101
92 ++dir->dd_stat; 102 /* Have we seen '.' or '..'? */
103 if (dir->dd_dir.d_name[0] == '.') {
104 if (dir->dd_dir.d_name[1] == '\0')
105 dir->got_dot = TRUE;
106 else if (dir->dd_dir.d_name[1] == '.' && dir->dd_dir.d_name[2] == '\0')
107 dir->got_dotdot = TRUE;
108 }
109
110 dir->not_first = TRUE;
93 return &dir->dd_dir; 111 return &dir->dd_dir;
94} 112}
95 113