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