~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/my_lib.cc

Remove PLUGIN and MODULES.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2000 MySQL AB
2
 
 
3
 
   This program is free software; you can redistribute it and/or modify
4
 
   it under the terms of the GNU General Public License as published by
5
 
   the Free Software Foundation; version 2 of the License.
6
 
 
7
 
   This program is distributed in the hope that it will be useful,
8
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 
   GNU General Public License for more details.
11
 
 
12
 
   You should have received a copy of the GNU General Public License
13
 
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
 
 
16
 
/* TODO: check for overun of memory for names. */
17
 
 
18
 
#include        "mysys/mysys_priv.h"
19
 
#include        <mystrings/m_string.h>
20
 
#include        "mysys/mysys_err.h"
21
 
#include        "my_dir.h"      /* Structs used by my_dir,includes sys/types */
22
 
#if defined(HAVE_DIRENT_H)
23
 
# include <dirent.h>
24
 
#else
25
 
# define dirent direct
26
 
# if defined(HAVE_SYS_NDIR_H)
27
 
#  include <sys/ndir.h>
28
 
# endif
29
 
# if defined(HAVE_SYS_DIR_H)
30
 
#  include <sys/dir.h>
31
 
# endif
32
 
# if defined(HAVE_NDIR_H)
33
 
#  include <ndir.h>
34
 
# endif
35
 
#endif
36
 
 
37
 
#if defined(HAVE_READDIR_R)
38
 
#define READDIR(A,B,C) ((errno=readdir_r(A,B,&C)) != 0 || !C)
39
 
#else 
40
 
#error You must have a thread safe readdir() 
41
 
#endif
42
 
 
43
 
/*
44
 
  We are assuming that directory we are reading is either has less than
45
 
  100 files and so can be read in one initial chunk or has more than 1000
46
 
  files and so big increment are suitable.
47
 
*/
48
 
#define ENTRIES_START_SIZE (8192/sizeof(FILEINFO))
49
 
#define ENTRIES_INCREMENT  (65536/sizeof(FILEINFO))
50
 
#define NAMES_START_SIZE   32768
51
 
 
52
 
 
53
 
static int comp_names(const struct fileinfo *a, const struct fileinfo *b);
54
 
static char* directory_file_name(char* dst, const char* src);
55
 
 
56
 
        /* We need this because program don't know with malloc we used */
57
 
 
58
 
void my_dirend(MY_DIR *buffer)
59
 
{
60
 
  if (buffer)
61
 
  {
62
 
    delete_dynamic((DYNAMIC_ARRAY*)((char*)buffer +
63
 
                                    ALIGN_SIZE(sizeof(MY_DIR))));
64
 
    free_root((MEM_ROOT*)((char*)buffer + ALIGN_SIZE(sizeof(MY_DIR)) +
65
 
                          ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))), MYF(0));
66
 
    free((unsigned char*) buffer);
67
 
  }
68
 
  return;
69
 
} /* my_dirend */
70
 
 
71
 
 
72
 
        /* Compare in sort of filenames */
73
 
 
74
 
static int comp_names(const struct fileinfo *a, const struct fileinfo *b)
75
 
{
76
 
  return (strcmp(a->name,b->name));
77
 
} /* comp_names */
78
 
 
79
 
 
80
 
MY_DIR  *my_dir(const char *path, myf MyFlags)
81
 
{
82
 
  char          *buffer;
83
 
  MY_DIR        *result= 0;
84
 
  FILEINFO      finfo;
85
 
  DYNAMIC_ARRAY *dir_entries_storage;
86
 
  MEM_ROOT      *names_storage;
87
 
  DIR           *dirp;
88
 
  struct dirent *dp;
89
 
  char          tmp_path[FN_REFLEN+1],*tmp_file;
90
 
  char  dirent_tmp[sizeof(struct dirent)+_POSIX_PATH_MAX+1];
91
 
 
92
 
  dirp = opendir(directory_file_name(tmp_path,(char *) path));
93
 
  if (dirp == NULL ||
94
 
      ! (buffer= (char *) malloc(ALIGN_SIZE(sizeof(MY_DIR)) + 
95
 
                                 ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)) +
96
 
                                 sizeof(MEM_ROOT))))
97
 
    goto error;
98
 
 
99
 
  dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)));
100
 
  names_storage= (MEM_ROOT*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)) +
101
 
                             ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)));
102
 
 
103
 
  if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO),
104
 
                            ENTRIES_START_SIZE, ENTRIES_INCREMENT))
105
 
  {
106
 
    free((unsigned char*) buffer);
107
 
    goto error;
108
 
  }
109
 
  init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE);
110
 
 
111
 
  /* MY_DIR structure is allocated and completly initialized at this point */
112
 
  result= (MY_DIR*)buffer;
113
 
 
114
 
  tmp_file= strchr(tmp_path, '\0');
115
 
 
116
 
  dp= (struct dirent*) dirent_tmp;
117
 
 
118
 
  while (!(READDIR(dirp,(struct dirent*) dirent_tmp,dp)))
119
 
  {
120
 
    if (!(finfo.name= strdup_root(names_storage, dp->d_name)))
121
 
      goto error;
122
 
 
123
 
    if (MyFlags & MY_WANT_STAT)
124
 
    {
125
 
      if (!(finfo.mystat= (struct stat*)alloc_root(names_storage,
126
 
                                               sizeof(struct stat))))
127
 
        goto error;
128
 
 
129
 
      memset(finfo.mystat, 0, sizeof(struct stat));
130
 
      strcpy(tmp_file,dp->d_name);
131
 
      stat(tmp_path, finfo.mystat);
132
 
      if (!(finfo.mystat->st_mode & S_IREAD))
133
 
        continue;
134
 
    }
135
 
    else
136
 
      finfo.mystat= NULL;
137
 
 
138
 
    if (push_dynamic(dir_entries_storage, (unsigned char*)&finfo))
139
 
      goto error;
140
 
  }
141
 
 
142
 
  (void) closedir(dirp);
143
 
 
144
 
  result->dir_entry= (FILEINFO *)dir_entries_storage->buffer;
145
 
  result->number_off_files= static_cast<uint>(dir_entries_storage->elements);
146
 
 
147
 
  if (!(MyFlags & MY_DONT_SORT))
148
 
    my_qsort((void *) result->dir_entry, result->number_off_files,
149
 
          sizeof(FILEINFO), (qsort_cmp) comp_names);
150
 
  return(result);
151
 
 
152
 
 error:
153
 
 
154
 
  my_errno=errno;
155
 
  if (dirp)
156
 
    (void) closedir(dirp);
157
 
  my_dirend(result);
158
 
  if (MyFlags & (MY_FAE | MY_WME))
159
 
    my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,my_errno);
160
 
 
161
 
  return((MY_DIR *) NULL);
162
 
} /* my_dir */
163
 
 
164
 
 
165
 
/*
166
 
 * Convert from directory name to filename.
167
 
 * On VMS:
168
 
 *       xyzzy:[mukesh.emacs] => xyzzy:[mukesh]emacs.dir.1
169
 
 *       xyzzy:[mukesh] => xyzzy:[000000]mukesh.dir.1
170
 
 * On UNIX, it's simple: just make sure there is a terminating /
171
 
 
172
 
 * Returns pointer to dst;
173
 
 */
174
 
 
175
 
static char* directory_file_name(char* dst, const char* src)
176
 
{
177
 
  /* Process as Unix format: just remove test the final slash. */
178
 
 
179
 
  char * end;
180
 
 
181
 
  if (src[0] == 0)
182
 
    src= (char*) ".";                           /* Use empty as current */
183
 
  end= strcpy(dst, src)+strlen(src);
184
 
  if (end[-1] != FN_LIBCHAR)
185
 
  {
186
 
    end[0]=FN_LIBCHAR;                          /* Add last '/' */
187
 
    end[1]='\0';
188
 
  }
189
 
  return dst;
190
 
} /* directory_file_name */
191