11#include "../../git-compat-util.h"
22
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 */
57 HANDLE dd_handle ; /* FindFirstFile handle */
68 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 ;
814
915static inline void finddata2dirent (struct dirent * ent , WIN32_FIND_DATAW * fdata )
1016{
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 );
1319
1420 /* Set file type, based on WIN32_FIND_DATA */
1521 if (fdata -> dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
@@ -18,41 +24,7 @@ static inline void finddata2dirent(struct dirent *ent, WIN32_FIND_DATAW *fdata)
1824 ent -> d_type = DT_REG ;
1925}
2026
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 )
5628{
5729 if (!dir ) {
5830 errno = EBADF ; /* No set_errno for mingw */
@@ -79,7 +51,7 @@ struct dirent *readdir(DIR *dir)
7951 return & dir -> dd_dir ;
8052}
8153
82- int closedir ( DIR * dir )
54+ static int dirent_closedir ( dirent_DIR * dir )
8355{
8456 if (!dir ) {
8557 errno = EBADF ;
@@ -90,3 +62,39 @@ int closedir(DIR *dir)
9062 free (dir );
9163 return 0 ;
9264}
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