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