14
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
16
/* TODO: check for overun of memory for names. */
17
/* Convert MSDOS-TIME to standar time_t (still needed?) */
19
#include "mysys_priv.h"
18
#include "mysys/mysys_priv.h"
20
19
#include <mystrings/m_string.h>
21
#include <my_dir.h> /* Structs used by my_dir,includes sys/types */
22
#include "mysys_err.h"
20
#include "mysys/mysys_err.h"
21
#include "my_dir.h" /* Structs used by my_dir,includes sys/types */
23
22
#if defined(HAVE_DIRENT_H)
24
23
# include <dirent.h>
25
# define NAMLEN(dirent) strlen((dirent)->d_name)
27
25
# define dirent direct
28
# define NAMLEN(dirent) (dirent)->d_namlen
29
26
# if defined(HAVE_SYS_NDIR_H)
30
27
# include <sys/ndir.h>
40
37
#if defined(HAVE_READDIR_R)
41
38
#define READDIR(A,B,C) ((errno=readdir_r(A,B,&C)) != 0 || !C)
43
#define READDIR(A,B,C) (!(C=readdir(A)))
40
#error You must have a thread safe readdir()
47
We are assuming that directory we are reading is either has less than
44
We are assuming that directory we are reading is either has less than
48
45
100 files and so can be read in one initial chunk or has more than 1000
49
46
files and so big increment are suitable.
65
delete_dynamic((DYNAMIC_ARRAY*)((char*)buffer +
62
delete_dynamic((DYNAMIC_ARRAY*)((char*)buffer +
66
63
ALIGN_SIZE(sizeof(MY_DIR))));
67
free_root((MEM_ROOT*)((char*)buffer + ALIGN_SIZE(sizeof(MY_DIR)) +
64
free_root((MEM_ROOT*)((char*)buffer + ALIGN_SIZE(sizeof(MY_DIR)) +
68
65
ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))), MYF(0));
69
my_free((uchar*) buffer,MYF(0));
66
free((unsigned char*) buffer);
92
89
char tmp_path[FN_REFLEN+1],*tmp_file;
93
90
char dirent_tmp[sizeof(struct dirent)+_POSIX_PATH_MAX+1];
95
#if !defined(HAVE_READDIR_R)
96
pthread_mutex_lock(&THR_LOCK_open);
99
92
dirp = opendir(directory_file_name(tmp_path,(char *) path));
101
! (buffer= my_malloc(ALIGN_SIZE(sizeof(MY_DIR)) +
102
ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)) +
103
sizeof(MEM_ROOT), MyFlags)))
94
! (buffer= (char *) malloc(ALIGN_SIZE(sizeof(MY_DIR)) +
95
ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)) +
106
dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)));
99
dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)));
107
100
names_storage= (MEM_ROOT*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)) +
108
101
ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)));
110
103
if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO),
111
104
ENTRIES_START_SIZE, ENTRIES_INCREMENT))
113
my_free((uchar*) buffer,MYF(0));
106
free((unsigned char*) buffer);
116
109
init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE);
118
111
/* MY_DIR structure is allocated and completly initialized at this point */
119
112
result= (MY_DIR*)buffer;
121
tmp_file=strend(tmp_path);
114
tmp_file= strchr(tmp_path, '\0');
123
116
dp= (struct dirent*) dirent_tmp;
125
118
while (!(READDIR(dirp,(struct dirent*) dirent_tmp,dp)))
127
120
if (!(finfo.name= strdup_root(names_storage, dp->d_name)))
130
123
if (MyFlags & MY_WANT_STAT)
132
if (!(finfo.mystat= (struct stat*)alloc_root(names_storage,
125
if (!(finfo.mystat= (struct stat*)alloc_root(names_storage,
133
126
sizeof(struct stat))))
136
129
memset(finfo.mystat, 0, sizeof(struct stat));
137
VOID(stpcpy(tmp_file,dp->d_name));
138
VOID(stat(tmp_path, finfo.mystat));
130
strcpy(tmp_file,dp->d_name);
131
stat(tmp_path, finfo.mystat);
139
132
if (!(finfo.mystat->st_mode & S_IREAD))
143
136
finfo.mystat= NULL;
145
if (push_dynamic(dir_entries_storage, (uchar*)&finfo))
138
if (push_dynamic(dir_entries_storage, (unsigned char*)&finfo))
149
142
(void) closedir(dirp);
150
#if !defined(HAVE_READDIR_R)
151
pthread_mutex_unlock(&THR_LOCK_open);
153
144
result->dir_entry= (FILEINFO *)dir_entries_storage->buffer;
154
result->number_off_files= dir_entries_storage->elements;
145
result->number_off_files= static_cast<uint>(dir_entries_storage->elements);
156
147
if (!(MyFlags & MY_DONT_SORT))
157
148
my_qsort((void *) result->dir_entry, result->number_off_files,
158
149
sizeof(FILEINFO), (qsort_cmp) comp_names);
162
#if !defined(HAVE_READDIR_R)
163
pthread_mutex_unlock(&THR_LOCK_open);
167
156
(void) closedir(dirp);
168
157
my_dirend(result);
169
158
if (MyFlags & (MY_FAE | MY_WME))
170
159
my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,my_errno);
171
161
return((MY_DIR *) NULL);