Chunk single;
Url wloc;
std::vector<std::string> components;
- std::string path, curdir, parentdir;
+ std::string path, parentdir;
struct stat fstat;
if (sfn.empty() || sfn[0] != '/') path = "/" + sfn;
components.pop_back();
parentdir = Url::joinPath(components);
- //
- // check the parent directory and try to create subtree if not available
- //
- // Catalog checks permissions in all parent directories, so with disk is in
- // sync with namespace, the creating of subtree should not be needed.
- //
- if (stat(getLocalPath(parentdir).c_str(), &fstat) == -1) {
- components = Url::splitPath(path);
- curdir = "";
- for (unsigned int i = 0; i < components.size() - 1; i++) {
- // the first component always '/', let's use it as separator
- if (i < 2) curdir += components[i];
- else curdir = curdir + "/" + components[i];
- // ignore all errors - we stupidly go from '/' toward deeper levels
- mkdir(getLocalPath(curdir).c_str(), 0755);
- }
-
- // detailed error from stat() only after the attempt for the subtree
- wrapCall(stat(getLocalPath(curdir).c_str(), &fstat), "parent directory '%s' not available", curdir.c_str());
- }
-
+ wrapCall(stat(getLocalPath(parentdir).c_str(), &fstat), "parent directory '%s' not available", parentdir.c_str());
if (!S_ISDIR(fstat.st_mode))
- vfsThrow(ENOTDIR, "'%s' is not directory", curdir.c_str());
+ vfsThrow(ENOTDIR, "'%s' is not directory", parentdir.c_str());
wloc = Url(path);
/// @file VfsIO.cpp
/// @brief IO factory.
/// @author Alejandro Álvarez Ayllón <aalvarez@cern.ch>
-#include <dmlite/cpp/dmlite.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include <errno.h>
+#include <unistd.h>
+#include <dmlite/cpp/dmlite.h>
#include "Vfs.h"
#include "VfsIO.h"
-VfsIOHandler::VfsIOHandler(const std::string& path, const std::string& prefix,
+VfsIOHandler::VfsIOHandler(const std::string& urlpath, const std::string& prefix,
int flags, mode_t mode) throw (DmException):
eof_(false), pos_(0)
{
- std::string real;
+ std::string path, lpath, parentdir, curdir;
+ std::vector<std::string> components;
+ struct stat fstat;
- if (path.compare(0, 5, "/vfs/") != 0)
- vfsThrow(EINVAL, "file not on the /vfs/ namespace");
-
this->prefix_ = prefix;
- real = getLocalPath(path.substr(4));
+ if (urlpath.compare(0, 5, "/vfs/") != 0)
+ vfsThrow(EINVAL, "file not on the /vfs/ namespace");
+
+ path = urlpath.substr(4);
+ components = Url::splitPath(path);
+ components.pop_back();
+ if (components.size() == 1 && components[0] == "/") parentdir = "/";
+ else parentdir = Url::joinPath(components);
+
+ //
+ // check the parent directory and try to create subtree if not available
+ //
+ if (stat(getLocalPath(parentdir).c_str(), &fstat) == -1) {
+ curdir = this->prefix_;
+ for (unsigned int i = 0; i < components.size(); i++) {
+ // the first component always '/', let's use it as separator
+ if (i < 2) curdir += components[i];
+ else curdir = curdir + "/" + components[i];
+ // ignore all errors - just go from "/" toward deeper levels
+ if (mkdir(curdir.c_str(), 0755) == 0)
+ syslog(LOG_DEBUG, "%s: created directory '%s'", __func__, curdir.c_str());
+ }
+ }
+ lpath = getLocalPath(path);
- this->fd_ = ::open(real.c_str(), flags, mode);
- syslog(LOG_DEBUG, "%s: open('%s', flags=%04X, mode=%04o) = %d", __func__, real.c_str(), flags, mode, this->fd_);
+ this->fd_ = ::open(lpath.c_str(), flags, mode);
+ syslog(LOG_DEBUG, "%s: open('%s', flags=%04X, mode=%04o) = %d", __func__, lpath.c_str(), flags, mode, this->fd_);
if (this->fd_ == -1)
- vfsThrowErrno("could not open %s)", path.c_str());
+ vfsThrowErrno("could not open '%s'", lpath.c_str());
}