1
1
#include "../../git-compat-util.h"
2
2
3
- struct DIR {
3
+ typedef struct dirent_DIR {
4
+ struct DIR base_dir ; /* extend base struct DIR */
4
5
struct dirent dd_dir ; /* includes d_type */
5
6
HANDLE dd_handle ; /* FindFirstFile handle */
6
7
int dd_stat ; /* 0-based index */
7
- };
8
+ char dd_name [MAX_PATH * 3 ]; /* file name (* 3 for UTF-8 conversion) */
9
+ } dirent_DIR ;
10
+
11
+ DIR * (* opendir )(const char * dirname ) = dirent_opendir ;
8
12
9
13
static inline void finddata2dirent (struct dirent * ent , WIN32_FIND_DATAW * fdata )
10
14
{
11
- /* convert UTF-16 name to UTF-8 */
12
- xwcstoutf (ent -> d_name , fdata -> cFileName , sizeof ( ent -> d_name ) );
15
+ /* convert UTF-16 name to UTF-8 (d_name points to dirent_DIR.dd_name) */
16
+ xwcstoutf (ent -> d_name , fdata -> cFileName , MAX_PATH * 3 );
13
17
14
18
/* Set file type, based on WIN32_FIND_DATA */
15
19
if (fdata -> dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
@@ -18,41 +22,7 @@ static inline void finddata2dirent(struct dirent *ent, WIN32_FIND_DATAW *fdata)
18
22
ent -> d_type = DT_REG ;
19
23
}
20
24
21
- DIR * opendir (const char * name )
22
- {
23
- wchar_t pattern [MAX_PATH + 2 ]; /* + 2 for '/' '*' */
24
- WIN32_FIND_DATAW fdata ;
25
- HANDLE h ;
26
- int len ;
27
- DIR * dir ;
28
-
29
- /* convert name to UTF-16 and check length < MAX_PATH */
30
- if ((len = xutftowcs_path (pattern , name )) < 0 )
31
- return NULL ;
32
-
33
- /* append optional '/' and wildcard '*' */
34
- if (len && !is_dir_sep (pattern [len - 1 ]))
35
- pattern [len ++ ] = '/' ;
36
- pattern [len ++ ] = '*' ;
37
- pattern [len ] = 0 ;
38
-
39
- /* open find handle */
40
- h = FindFirstFileW (pattern , & fdata );
41
- if (h == INVALID_HANDLE_VALUE ) {
42
- DWORD err = GetLastError ();
43
- errno = (err == ERROR_DIRECTORY ) ? ENOTDIR : err_win_to_posix (err );
44
- return NULL ;
45
- }
46
-
47
- /* initialize DIR structure and copy first dir entry */
48
- dir = xmalloc (sizeof (DIR ));
49
- dir -> dd_handle = h ;
50
- dir -> dd_stat = 0 ;
51
- finddata2dirent (& dir -> dd_dir , & fdata );
52
- return dir ;
53
- }
54
-
55
- struct dirent * readdir (DIR * dir )
25
+ static struct dirent * dirent_readdir (dirent_DIR * dir )
56
26
{
57
27
if (!dir ) {
58
28
errno = EBADF ; /* No set_errno for mingw */
@@ -79,7 +49,7 @@ struct dirent *readdir(DIR *dir)
79
49
return & dir -> dd_dir ;
80
50
}
81
51
82
- int closedir ( DIR * dir )
52
+ static int dirent_closedir ( dirent_DIR * dir )
83
53
{
84
54
if (!dir ) {
85
55
errno = EBADF ;
@@ -90,3 +60,40 @@ int closedir(DIR *dir)
90
60
free (dir );
91
61
return 0 ;
92
62
}
63
+
64
+ DIR * dirent_opendir (const char * name )
65
+ {
66
+ wchar_t pattern [MAX_PATH + 2 ]; /* + 2 for '/' '*' */
67
+ WIN32_FIND_DATAW fdata ;
68
+ HANDLE h ;
69
+ int len ;
70
+ dirent_DIR * dir ;
71
+
72
+ /* convert name to UTF-16 and check length < MAX_PATH */
73
+ if ((len = xutftowcs_path (pattern , name )) < 0 )
74
+ return NULL ;
75
+
76
+ /* append optional '/' and wildcard '*' */
77
+ if (len && !is_dir_sep (pattern [len - 1 ]))
78
+ pattern [len ++ ] = '/' ;
79
+ pattern [len ++ ] = '*' ;
80
+ pattern [len ] = 0 ;
81
+
82
+ /* open find handle */
83
+ h = FindFirstFileW (pattern , & fdata );
84
+ if (h == INVALID_HANDLE_VALUE ) {
85
+ DWORD err = GetLastError ();
86
+ errno = (err == ERROR_DIRECTORY ) ? ENOTDIR : err_win_to_posix (err );
87
+ return NULL ;
88
+ }
89
+
90
+ /* initialize DIR structure and copy first dir entry */
91
+ dir = xmalloc (sizeof (dirent_DIR ));
92
+ dir -> base_dir .preaddir = (struct dirent * (* )(DIR * dir )) dirent_readdir ;
93
+ dir -> base_dir .pclosedir = (int (* )(DIR * dir )) dirent_closedir ;
94
+ dir -> dd_dir .d_name = dir -> dd_name ;
95
+ dir -> dd_handle = h ;
96
+ dir -> dd_stat = 0 ;
97
+ finddata2dirent (& dir -> dd_dir , & fdata );
98
+ return (DIR * ) dir ;
99
+ }
0 commit comments