1 /* Start reading the entries of a directory.
2 Copyright (C) 2006-2024 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(). */
32 # include "filename.h"
39 #if GNULIB_defined_DIR
40 # include "dirent-private.h"
47 #if defined _WIN32 && ! defined __CYGWIN__
48 /* Don't assume that UNICODE is not defined. */
49 # undef WIN32_FIND_DATA
50 # define WIN32_FIND_DATA WIN32_FIND_DATAA
51 # undef GetFullPathName
52 # define GetFullPathName GetFullPathNameA
54 # define FindFirstFile FindFirstFileA
58 opendir (const char *dir_name
)
61 #if HAVE_DIRENT_H /* equivalent to HAVE_OPENDIR */
64 # if GNULIB_defined_DIR
67 dirp
= (struct gl_directory
*) malloc (sizeof (struct gl_directory
));
74 DIR *real_dirp
= opendir (dir_name
);
75 if (real_dirp
== NULL
)
77 int saved_errno
= errno
;
83 dirp
->fd_to_close
= -1;
84 dirp
->real_dirp
= real_dirp
;
86 dirp
= opendir (dir_name
);
93 char dir_name_mask
[MAX_PATH
+ 1 + 1 + 1];
96 WIN32_FIND_DATA entry
;
97 struct gl_directory
*dirp
;
99 if (dir_name
[0] == '\0')
105 /* Make the dir_name absolute, so that we continue reading the same
106 directory if the current directory changed between this opendir()
107 call and a subsequent rewinddir() call. */
108 if (!GetFullPathName (dir_name
, MAX_PATH
, dir_name_mask
, NULL
))
115 "*" and "*.*" appear to be equivalent. */
119 p
= dir_name_mask
+ strlen (dir_name_mask
);
120 if (p
> dir_name_mask
&& !ISSLASH (p
[-1]))
126 /* Start searching the directory. */
128 current
= FindFirstFile (dir_name_mask
, &entry
);
129 if (current
== INVALID_HANDLE_VALUE
)
131 switch (GetLastError ())
133 case ERROR_FILE_NOT_FOUND
:
136 case ERROR_PATH_NOT_FOUND
:
139 case ERROR_DIRECTORY
:
142 case ERROR_ACCESS_DENIED
:
151 /* Allocate the result. */
153 (struct gl_directory
*)
154 malloc (offsetof (struct gl_directory
, dir_name_mask
[0])
155 + strlen (dir_name_mask
) + 1);
158 if (current
!= INVALID_HANDLE_VALUE
)
163 dirp
->fd_to_close
= -1;
164 dirp
->status
= status
;
165 dirp
->current
= current
;
167 memcpy (&dirp
->entry
, &entry
, sizeof (WIN32_FIND_DATA
));
168 strcpy (dirp
->dir_name_mask
, dir_name_mask
);
174 int fd
= dirfd (dirp
);
175 if (0 <= fd
&& _gl_register_fd (fd
, dir_name
) != fd
)
177 int saved_errno
= errno
;