1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1997-2009 Oracle. All rights reserved.
*
* $Id$
*/
#include "db_config.h"
#include "db_int.h"
/*
* __os_dirlist --
* Return a list of the files in a directory.
*/
int
__os_dirlist(env, dir, returndir, namesp, cntp)
ENV *env;
const char *dir;
int returndir, *cntp;
char ***namesp;
{
HANDLE dirhandle;
WIN32_FIND_DATA fdata;
int arraysz, cnt, ret;
char **names, *onename;
_TCHAR tfilespec[DB_MAXPATHLEN + 1];
_TCHAR *tdir;
*namesp = NULL;
*cntp = 0;
TO_TSTRING(env, dir, tdir, ret);
if (ret != 0)
return (ret);
(void)_sntprintf(tfilespec, DB_MAXPATHLEN,
_T("%s%hc*"), tdir, PATH_SEPARATOR[0]);
/*
* On WinCE, FindFirstFile will return INVALID_HANDLE_VALUE when
* the searched directory is empty, and set last error to
* ERROR_NO_MORE_FILES, on Windows it will return "." instead.
*/
if ((dirhandle =
FindFirstFile(tfilespec, &fdata)) == INVALID_HANDLE_VALUE) {
if (GetLastError() == ERROR_NO_MORE_FILES)
return (0);
return (__os_posix_err(__os_get_syserr()));
}
names = NULL;
arraysz = cnt = ret = 0;
for (;;) {
if (returndir ||
(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
if (fdata.cFileName[0] == _T('.') &&
(fdata.cFileName[1] == _T('\0') ||
(fdata.cFileName[1] == _T('.') &&
fdata.cFileName[2] == _T('\0'))))
goto next;
if (cnt >= arraysz) {
arraysz += 100;
if ((ret = __os_realloc(env,
arraysz * sizeof(names[0]), &names)) != 0)
goto err;
}
/*
* FROM_TSTRING doesn't necessarily allocate new
* memory, so we must do that explicitly.
* Unfortunately, when compiled with UNICODE, we'll
* copy twice.
*/
FROM_TSTRING(env, fdata.cFileName, onename, ret);
if (ret != 0)
goto err;
ret = __os_strdup(env, onename, &names[cnt]);
FREE_STRING(env, onename);
if (ret != 0)
goto err;
cnt++;
}
next:
if (!FindNextFile(dirhandle, &fdata)) {
if (GetLastError() == ERROR_NO_MORE_FILES)
break;
else {
ret = __os_posix_err(__os_get_syserr());
goto err;
}
}
}
err: if (!FindClose(dirhandle) && ret == 0)
ret = __os_posix_err(__os_get_syserr());
if (ret == 0) {
*namesp = names;
*cntp = cnt;
} else if (names != NULL)
__os_dirfree(env, names, cnt);
FREE_STRING(env, tdir);
return (ret);
}
/*
* __os_dirfree --
* Free the list of files.
*/
void
__os_dirfree(env, names, cnt)
ENV *env;
char **names;
int cnt;
{
while (cnt > 0)
__os_free(env, names[--cnt]);
__os_free(env, names);
}
|