meta = vfsExtendedStat(components.back(), path, follow);
#if 0
-// FIXME: openDir without permissions check and indirect recursion
- // black magic - dmlite tests require proper count in st_nlink
+ // XXX: black magic
+ // dmlite tests require proper count in st_nlink,
+ // but another test requires not changed atime
if (S_ISDIR(meta.stat.st_mode)) {
Directory *dir;
struct dirent *entry;
int count = 0;
- dir = openDir(path);
+ dir = vfsOpenDir(path);
while ((entry = readDir(dir)) != NULL) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
-Directory* VfsCatalog::openDir(const std::string& path) throw (DmException)
+PrivateDir* VfsCatalog::vfsOpenDir(const std::string& path) throw (DmException)
{
PrivateDir *privateDir;
- ExtendedStat meta;
privateDir = new PrivateDir();
try {
- meta = this->extendedStat(path);
- if (checkPermissions(this->secCtx_, meta.acl, meta.stat, S_IREAD) != 0)
- vfsThrow(EACCES, "not enough permissions for '%s' to read '%s'", clientName.c_str(), path.c_str());
-
privateDir->path = path;
privateDir->dir = opendir(path.c_str());
if (privateDir->dir == NULL)
+Directory* VfsCatalog::openDir(const std::string& path) throw (DmException)
+{
+ PrivateDir *privateDir;
+ ExtendedStat meta;
+
+ meta = this->extendedStat(path);
+ if (checkPermissions(this->secCtx_, meta.acl, meta.stat, S_IREAD) != 0)
+ vfsThrow(EACCES, "not enough permissions for '%s' to read '%s'", clientName.c_str(), path.c_str());
+
+ privateDir = vfsOpenDir(path);
+
+ syslog(LOG_DEBUG, "%s: directory '%s' opened", __func__, path.c_str());
+ return privateDir;
+}
+
+
+
void VfsCatalog::closeDir(Directory* dir) throw (DmException)
{
int r;
PrivateDir *privateDir = dynamic_cast<PrivateDir*>(dir);
+ std::string path = privateDir->path;
if (privateDir == NULL)
throw DmException(DMLITE_SYSERR(EFAULT),
delete privateDir;
wrapCall(r);
+ syslog(LOG_DEBUG, "%s: directory '%s' closed", __func__, path.c_str());
}
struct dirent* VfsCatalog::readDir(Directory* dir) throw (DmException)
{
PrivateDir *privateDir = dynamic_cast<PrivateDir*>(dir);
+ struct dirent *ent;
if (privateDir == NULL)
- throw DmException(DMLITE_SYSERR(EFAULT),
- "Tried to read a null directory");
+ vfsThrow(DMLITE_SYSERR(EFAULT), "Tried to read a null directory");
+
+ errno = 0;
+ ent = readdir(privateDir->dir);
+ if (!ent && errno)
+ vfsThrow(errno, "readdir() on '%s' failed", privateDir->path.c_str());
- return static_cast<struct dirent*>(readdir(privateDir->dir));
+ syslog(LOG_DEBUG, "%s: result %s", __func__, ent ? ent->d_name : "(null)");
+ return static_cast<struct dirent*>(ent);
}