1 /* Start reading the entries of a directory.
2 Copyright (C) 2006-2022 Free Software Foundation, Inc.
4 This file is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation; either version 2.1 of the
7 License, or (at your option) any later version.
9 This file is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
27 /* Override opendir(), to keep track of the open file descriptors.
28 Needed because there is a function dirfd(). */
34 # include "dirent-private.h"
35 # include "filename.h"
48 #if defined _WIN32 && ! defined __CYGWIN__
49 /* Don't assume that UNICODE is not defined. */
50 # undef WIN32_FIND_DATA
51 # define WIN32_FIND_DATA WIN32_FIND_DATAA
52 # undef GetFullPathName
53 # define GetFullPathName GetFullPathNameA
55 # define FindFirstFile FindFirstFileA
59 opendir (const char *dir_name
)
65 dirp
= opendir (dir_name
);
71 int fd
= open (dir_name
, O_RDONLY
);
72 if (fd
== -1 || _gl_register_dirp_fd (fd
, dirp
))
74 int saved_errno
= errno
;
87 char dir_name_mask
[MAX_PATH
+ 1 + 1 + 1];
90 WIN32_FIND_DATA entry
;
91 struct gl_directory
*dirp
;
93 if (dir_name
[0] == '\0')
99 /* Make the dir_name absolute, so that we continue reading the same
100 directory if the current directory changed between this opendir()
101 call and a subsequent rewinddir() call. */
102 if (!GetFullPathName (dir_name
, MAX_PATH
, dir_name_mask
, NULL
))
109 "*" and "*.*" appear to be equivalent. */
113 p
= dir_name_mask
+ strlen (dir_name_mask
);
114 if (p
> dir_name_mask
&& !ISSLASH (p
[-1]))
120 /* Start searching the directory. */
122 current
= FindFirstFile (dir_name_mask
, &entry
);
123 if (current
== INVALID_HANDLE_VALUE
)
125 switch (GetLastError ())
127 case ERROR_FILE_NOT_FOUND
:
130 case ERROR_PATH_NOT_FOUND
:
133 case ERROR_DIRECTORY
:
136 case ERROR_ACCESS_DENIED
:
145 /* Allocate the result. */
147 (struct gl_directory
*)
148 malloc (offsetof (struct gl_directory
, dir_name_mask
[0])
149 + strlen (dir_name_mask
) + 1);
152 if (current
!= INVALID_HANDLE_VALUE
)
157 dirp
->status
= status
;
158 dirp
->current
= current
;
160 memcpy (&dirp
->entry
, &entry
, sizeof (WIN32_FIND_DATA
));
161 strcpy (dirp
->dir_name_mask
, dir_name_mask
);
167 int fd
= dirfd (dirp
);
168 if (0 <= fd
&& _gl_register_fd (fd
, dir_name
) != fd
)
170 int saved_errno
= errno
;