~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/cached_directory.cc

  • Committer: Stewart Smith
  • Date: 2008-10-15 04:21:24 UTC
  • mto: This revision was merged to the branch mainline in revision 516.
  • Revision ID: stewart@flamingspork.com-20081015042124-kdmb74bcbky1k1nz
remove my_pthread_[gs]etspecific

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems, Inc.
5
 
 *
6
 
 *  This program is free software; you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License as published by
8
 
 *  the Free Software Foundation; version 2 of the License.
9
 
 *
10
 
 *  This program is distributed in the hope that it will be useful,
11
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 *  GNU General Public License for more details.
14
 
 *
15
 
 *  You should have received a copy of the GNU General Public License
16
 
 *  along with this program; if not, write to the Free Software
17
 
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 
 */
19
 
 
20
 
/**
21
 
 * @file
22
 
 *   cached_directory.cc
23
 
 *
24
 
 * @brief
25
 
 *   Implementation of CachedDirectory class.
26
 
 */
27
 
 
28
 
#include <config.h>
29
 
 
30
 
#include <drizzled/definitions.h>
31
 
 
32
 
#include <sys/types.h>
33
 
#include <sys/stat.h>
34
 
#include <unistd.h>
35
 
 
36
 
#include <strings.h>
37
 
#include <limits.h>
38
 
 
39
 
#include <drizzled/cached_directory.h>
40
 
 
41
 
using namespace std;
42
 
 
43
 
namespace drizzled
44
 
{
45
 
 
46
 
CachedDirectory::CachedDirectory() : 
47
 
  error(0)
48
 
{
49
 
}
50
 
 
51
 
 
52
 
CachedDirectory::CachedDirectory(const string &in_path) :
53
 
  error(0),
54
 
  use_full_path(false)
55
 
{
56
 
  // TODO: Toss future exception
57
 
  (void) open(in_path);
58
 
}
59
 
 
60
 
 
61
 
CachedDirectory::CachedDirectory(const string& in_path, set<string>& allowed_exts) :
62
 
  error(0),
63
 
  use_full_path(false)
64
 
{
65
 
  // TODO: Toss future exception
66
 
  (void) open(in_path, allowed_exts);
67
 
}
68
 
 
69
 
CachedDirectory::CachedDirectory(const string& in_path, enum CachedDirectory::FILTER filter, bool use_full_path_arg) :
70
 
  error(0),
71
 
  use_full_path(use_full_path_arg)
72
 
{
73
 
  set<string> empty;
74
 
  // TODO: Toss future exception
75
 
  (void) open(in_path, empty, filter);
76
 
}
77
 
 
78
 
 
79
 
CachedDirectory::~CachedDirectory()
80
 
{
81
 
  for (Entries::iterator iter= entries.begin(); iter != entries.end(); ++iter)
82
 
  {
83
 
    delete *iter;
84
 
  }
85
 
  entries.clear();
86
 
}
87
 
 
88
 
bool CachedDirectory::open(const string &in_path)
89
 
{
90
 
  set<string> empty;
91
 
 
92
 
  return open(in_path, empty);
93
 
}
94
 
 
95
 
bool CachedDirectory::open(const string &in_path, set<string> &allowed_exts)
96
 
{
97
 
  return open(in_path, allowed_exts, CachedDirectory::NONE);
98
 
}
99
 
 
100
 
bool CachedDirectory::open(const string &in_path, set<string> &allowed_exts, enum CachedDirectory::FILTER filter)
101
 
{
102
 
  DIR *dirp= opendir(in_path.c_str());
103
 
 
104
 
  if (dirp == NULL)
105
 
  {
106
 
    error= errno;
107
 
    return false;
108
 
  }
109
 
 
110
 
  path= in_path;
111
 
 
112
 
  union {
113
 
    dirent entry;
114
 
#ifdef __sun
115
 
    /*
116
 
     * The readdir_r() call on Solaris operates a bit differently from other
117
 
     * systems in that the dirent structure must be allocated along with enough
118
 
     * space to contain the filename (see man page for readdir_r on Solaris).
119
 
     * Instead of dynamically try to allocate this buffer, just set the max
120
 
     * name for a path instead.
121
 
     */
122
 
    char space[sizeof(dirent) + PATH_MAX + 1];
123
 
#endif
124
 
  } buffer;
125
 
 
126
 
  int retcode;
127
 
  dirent *result;
128
 
 
129
 
  while ((retcode= readdir_r(dirp, &buffer.entry, &result)) == 0 &&
130
 
         result != NULL)
131
 
  {
132
 
    std::string buffered_fullpath;
133
 
    if (not allowed_exts.empty())
134
 
    {
135
 
      char *ptr= rindex(result->d_name, '.');
136
 
 
137
 
      if (ptr)
138
 
      {
139
 
        set<string>::iterator it;
140
 
        it= allowed_exts.find(ptr);
141
 
 
142
 
        if (it != allowed_exts.end())
143
 
        {
144
 
          entries.push_back(new Entry(result->d_name));
145
 
        }
146
 
      }
147
 
    }
148
 
    else
149
 
    {
150
 
      switch (filter)
151
 
      {
152
 
      case DIRECTORY:
153
 
        {
154
 
          struct stat entrystat;
155
 
 
156
 
          if (result->d_name[0] == '.') // We don't pass back anything hidden at the moment.
157
 
            continue;
158
 
 
159
 
          if (use_full_path)
160
 
          {
161
 
            buffered_fullpath.append(in_path);
162
 
            if (buffered_fullpath[buffered_fullpath.length()] != '/')
163
 
              buffered_fullpath.append(1, FN_LIBCHAR);
164
 
          }
165
 
 
166
 
          buffered_fullpath.append(result->d_name);
167
 
 
168
 
          stat(buffered_fullpath.c_str(), &entrystat);
169
 
 
170
 
          if (S_ISDIR(entrystat.st_mode))
171
 
          {
172
 
            entries.push_back(new Entry(result->d_name));
173
 
          }
174
 
        }
175
 
        break;
176
 
      case FILE:
177
 
        {
178
 
          struct stat entrystat;
179
 
 
180
 
          buffered_fullpath.append(in_path);
181
 
          if (buffered_fullpath[buffered_fullpath.length()] != '/')
182
 
            buffered_fullpath.append(1, FN_LIBCHAR);
183
 
 
184
 
          buffered_fullpath.assign(result->d_name);
185
 
 
186
 
          stat(buffered_fullpath.c_str(), &entrystat);
187
 
 
188
 
          if (S_ISREG(entrystat.st_mode))
189
 
          {
190
 
            entries.push_back(new Entry(result->d_name));
191
 
          }
192
 
        }
193
 
        break;
194
 
      case NONE:
195
 
      case MAX:
196
 
        entries.push_back(new Entry(result->d_name));
197
 
        break;
198
 
      }
199
 
    }
200
 
  }
201
 
    
202
 
  closedir(dirp);
203
 
  error= retcode;
204
 
 
205
 
  return error == 0;
206
 
}
207
 
 
208
 
} /* namespace drizzled */