1 #include "ace/OS_NS_dirent.h"
5 #if !defined (ACE_HAS_INLINED_OSCALLS)
6 # include "ace/OS_NS_dirent.inl"
7 #endif /* ACE_HAS_INLINED_OSCALLS */
9 #include "ace/OS_NS_errno.h"
10 #include "ace/OS_NS_string.h"
11 #include "ace/Log_Category.h"
12 #include "ace/OS_NS_stdlib.h"
14 #if defined (ACE_HAS_ALLOC_HOOKS)
15 # include "ace/Malloc_Base.h"
16 #endif /* ACE_HAS_ALLOC_HOOKS */
18 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
20 #if defined (ACE_LACKS_CLOSEDIR)
22 ACE_OS::closedir_emulation (ACE_DIR
*d
)
24 #if defined (ACE_WIN32)
25 if (d
->current_handle_
!= INVALID_HANDLE_VALUE
)
27 ::FindClose (d
->current_handle_
);
28 d
->current_handle_
= INVALID_HANDLE_VALUE
;
31 d
->started_reading_
= 0;
34 ACE_OS::free (d
->dirent_
->d_name
);
35 ACE_OS::free (d
->dirent_
);
39 #endif /* ACE_WIN32 */
41 #endif /* ACE_LACKS_CLOSEDIR */
43 #if defined (ACE_LACKS_OPENDIR)
45 ACE_OS::opendir_emulation (const ACE_TCHAR
*filename
)
47 #if defined (ACE_WIN32)
48 # if !defined (INVALID_FILE_ATTRIBUTES)
49 # define INVALID_FILE_ATTRIBUTES 0xFFFFFFFF
53 ACE_TCHAR extra
[3] = {0,0,0};
55 // Check if filename is a directory.
56 DWORD fileAttribute
= ACE_TEXT_GetFileAttributes (filename
);
57 if (fileAttribute
== INVALID_FILE_ATTRIBUTES
58 || !(fileAttribute
& FILE_ATTRIBUTE_DIRECTORY
))
62 Note: the semantics of the win32 function FindFirstFile take the
63 basename(filename) as a pattern to be matched within the dirname(filename).
64 This is contrary to the behavior of the posix function readdir which treats
65 basename(filename) as a directory to be opened and read.
67 For this reason, we append a slash-star or backslash-star to the supplied
68 filename so the result is that FindFirstFile will do what we need.
70 According to the documentation for FindFirstFile, either a '/' or a '\' may
71 be used as a directory name separator.
73 Of course, it is necessary to ensure that this is only done if the trailing
74 filespec is not already there.
79 size_t const lastchar
= ACE_OS::strlen (filename
);
82 if (filename
[lastchar
-1] != '*')
84 if (filename
[lastchar
-1] != '/' && filename
[lastchar
-1] != '\\')
85 ACE_OS::strcpy (extra
, ACE_TEXT ("/*"));
87 ACE_OS::strcpy (extra
, ACE_TEXT ("*"));
91 ACE_NEW_RETURN (dir
, ACE_DIR
, 0);
92 ACE_NEW_RETURN (dir
->directory_name_
,
93 ACE_TCHAR
[lastchar
+ ACE_OS::strlen (extra
) + 1],
95 ACE_OS::strcpy (dir
->directory_name_
, filename
);
97 ACE_OS::strcat (dir
->directory_name_
, extra
);
98 dir
->current_handle_
= INVALID_HANDLE_VALUE
;
99 dir
->started_reading_
= 0;
103 ACE_UNUSED_ARG (filename
);
104 ACE_NOTSUP_RETURN (0);
107 #endif /* ACE_LACKS_CLOSEDIR */
109 #if defined (ACE_LACKS_READDIR)
111 ACE_OS::readdir_emulation (ACE_DIR
*d
)
113 #if defined (ACE_WIN32)
116 ACE_OS::free (d
->dirent_
->d_name
);
117 ACE_OS::free (d
->dirent_
);
121 if (!d
->started_reading_
)
123 d
->current_handle_
= ACE_TEXT_FindFirstFile (d
->directory_name_
,
125 d
->started_reading_
= 1;
129 int const retval
= ACE_TEXT_FindNextFile (d
->current_handle_
, &d
->fdata_
);
132 // Make sure to close the handle explicitly to avoid a leak!
133 ::FindClose (d
->current_handle_
);
134 d
->current_handle_
= INVALID_HANDLE_VALUE
;
138 if (d
->current_handle_
!= INVALID_HANDLE_VALUE
)
140 d
->dirent_
= (ACE_DIRENT
*)
141 ACE_OS::malloc (sizeof (ACE_DIRENT
));
145 d
->dirent_
->d_name
= (ACE_TCHAR
*)
146 ACE_OS::malloc ((ACE_OS::strlen (d
->fdata_
.cFileName
) + 1)
147 * sizeof (ACE_TCHAR
));
148 ACE_OS::strcpy (d
->dirent_
->d_name
, d
->fdata_
.cFileName
);
149 d
->dirent_
->d_reclen
= sizeof (ACE_DIRENT
);
156 #else /* ACE_WIN32 */
158 ACE_NOTSUP_RETURN (0);
159 #endif /* ACE_WIN32 */
161 #endif /* ACE_LACKS_READDIR */
163 #if !defined (ACE_HAS_SCANDIR)
165 ACE_OS::scandir_emulation (const ACE_TCHAR
*dirname
,
166 ACE_DIRENT
**namelist
[],
167 ACE_SCANDIR_SELECTOR selector
,
168 ACE_SCANDIR_COMPARATOR comparator
)
170 ACE_DIR
*dirp
= ACE_OS::opendir (dirname
);
174 // A sanity check here. "namelist" had better not be zero.
175 else if (namelist
== 0)
178 ACE_DIRENT
**vector
= 0;
184 // @@ This code shoulduse readdir_r() rather than readdir().
185 for (dp
= ACE_OS::readdir (dirp
);
187 dp
= ACE_OS::readdir (dirp
))
189 if (selector
&& (*selector
)(dp
) == 0)
192 // If we get here, we have a dirent that the user likes.
193 if (nfiles
== arena_size
)
195 ACE_DIRENT
**newv
= 0;
200 new_arena_size
= arena_size
* 2;
202 #if defined (ACE_HAS_ALLOC_HOOKS)
203 newv
= (ACE_DIRENT
**) ACE_Allocator::instance()->malloc (new_arena_size
* sizeof (ACE_DIRENT
*));
206 ACE_OS::memcpy (newv
, vector
, arena_size
* sizeof (ACE_DIRENT
*));
209 newv
= (ACE_DIRENT
**) ACE_OS::realloc (vector
,
210 new_arena_size
* sizeof (ACE_DIRENT
*));
211 #endif /* ACE_HAS_ALLOC_HOOKS */
213 arena_size
= new_arena_size
;
223 #if defined (ACE_LACKS_STRUCT_DIR)
224 #if defined (ACE_HAS_ALLOC_HOOKS)
225 ACE_DIRENT
*newdp
= (ACE_DIRENT
*) ACE_Allocator::instance()->malloc (sizeof (ACE_DIRENT
));
227 ACE_DIRENT
*newdp
= (ACE_DIRENT
*) ACE_OS::malloc (sizeof (ACE_DIRENT
));
228 #endif /* ACE_HAS_ALLOC_HOOKS */
231 sizeof (ACE_DIRENT
) +
232 ((ACE_OS::strlen (dp
->d_name
) + 1) * sizeof (ACE_TCHAR
));
233 #if defined (ACE_HAS_ALLOC_HOOKS)
234 ACE_DIRENT
*newdp
= (ACE_DIRENT
*) ACE_Allocator::instance()->malloc (dsize
);
236 ACE_DIRENT
*newdp
= (ACE_DIRENT
*) ACE_OS::malloc (dsize
);
237 #endif /* ACE_HAS_ALLOC_HOOKS */
238 #endif /* ACE_LACKS_STRUCT_DIR */
246 #if defined (ACE_LACKS_STRUCT_DIR)
247 #if defined (ACE_HAS_ALLOC_HOOKS)
248 newdp
->d_name
= (ACE_TCHAR
*) ACE_Allocator::instance()->malloc ((ACE_OS::strlen (dp
->d_name
) + 1) * sizeof (ACE_TCHAR
));
250 newdp
->d_name
= (ACE_TCHAR
*) ACE_OS::malloc ((ACE_OS::strlen (dp
->d_name
) + 1) * sizeof (ACE_TCHAR
));
251 #endif /* ACE_HAS_ALLOC_HOOKS */
253 if (newdp
->d_name
== 0)
256 #if defined (ACE_HAS_ALLOC_HOOKS)
257 ACE_Allocator::instance()->free (newdp
);
259 ACE_OS::free (newdp
);
260 #endif /* ACE_HAS_ALLOC_HOOKS */
264 // Don't use memcpy here since d_name is now a pointer
265 newdp
->d_ino
= dp
->d_ino
;
266 newdp
->d_off
= dp
->d_off
;
267 newdp
->d_reclen
= dp
->d_reclen
;
268 ACE_OS::strcpy (newdp
->d_name
, dp
->d_name
);
269 vector
[nfiles
++] = newdp
;
271 vector
[nfiles
++] = (ACE_DIRENT
*) ACE_OS::memcpy (newdp
, dp
, dsize
);
272 #endif /* ACE_LACKS_STRUCT_DIR */
277 ACE_OS::closedir (dirp
);
278 while (vector
&& nfiles
-- > 0)
280 #if defined (ACE_LACKS_STRUCT_DIR)
281 #if defined (ACE_HAS_ALLOC_HOOKS)
282 ACE_Allocator::instance()->free (vector
[nfiles
]->d_name
);
284 ACE_OS::free (vector
[nfiles
]->d_name
);
285 #endif /* ACE_HAS_ALLOC_HOOKS */
286 #endif /* ACE_LACKS_STRUCT_DIR */
287 #if defined (ACE_HAS_ALLOC_HOOKS)
288 ACE_Allocator::instance()->free (vector
[nfiles
]);
290 ACE_OS::free (vector
[nfiles
]);
291 #endif /* ACE_HAS_ALLOC_HOOKS */
293 #if defined (ACE_HAS_ALLOC_HOOKS)
294 ACE_Allocator::instance()->free (vector
);
296 ACE_OS::free (vector
);
297 #endif /* ACE_HAS_ALLOC_HOOKS */
301 ACE_OS::closedir (dirp
);
306 ACE_OS::qsort (*namelist
,
308 sizeof (ACE_DIRENT
*),
309 (ACE_COMPARE_FUNC
) comparator
);
313 #endif /* !ACE_HAS_SCANDIR */
315 ACE_END_VERSIONED_NAMESPACE_DECL