ewmscp  ..
inputHandlerDcap.cpp
Go to the documentation of this file.
1 #include "inputHandlerDcap.h"
2 
3 #include <memory>
4 
5 #include "block.h"
6 #include "copyRequestTypes.h"
7 #include "ewmscp.h"
8 
9 #include <errMsgQueue.h>
10 
11 namespace inputHandler {
12  decltype(dcap::factory) dcap::factory("dcap");
13  std::unique_ptr<base::reader> dcap::newReader(const std::string& aPath,
15  const genericStat& inititalStat) {
16  return std::unique_ptr<base::reader>(new readerDcap(aPath,
17  state,
18  inititalStat));
19  }
20 
21 
22  dcap::readerDcap::readerDcap(const std::string& aPath,
24  const genericStat&inititalStat):
25  dcapIoCommon(aPath),
26  reader(inititalStat) {
27  dCapLock extraOptionLock;
28  fd = dc_open(path.c_str(), O_RDONLY);
29  if (fd == -1) {
30  if (errno == ENOENT
31  || (errno == ENOTDIR && !S_ISDIR(readInitialStat.mode))) {
33  }
34  }
35  throwcall::dcap::badval(fd, -1, "can't open ", path, " for reading");
36  blockSize = readInitialStat.blksize;
37  }
38 
40  if (fd != -1) {
41  dCapLock extraOptionLock;
42  if (isUnwinding()) {
43  if (dc_close(fd) != 0) {
45  path, "close during unwind ",
46  dc_strerror(dc_errno));
47  }
48  return;
49  }
50  throwcall::dcap::good0(dc_close(fd), "can't close ", path, " after reading");
51  }
52  }
53 
54 
56  b.clear(totalBytesRead);
57  bool lastblock = false;
58 
59  while (b.size() + blockSize <= b.max_size()) {
61  auto bytes_read = throwcall::dcap::badval(dc_read(fd, b.bufferAt(b.size()), blockSize),
62  -1, "read failed on ", path);
63  readRateLimit.update(bytes_read);
64  if (bytes_read == 0) {
65  lastblock = true;
66  if (totalBytesRead < readInitialStat.size) {
67  throw delayAdvisingError(path + " has shrunk while reading, (" +
68  std::to_string(readInitialStat.size) +
69  " -> " +
70  std::to_string(totalBytesRead) +
71  ")");
72  }
73  break;
74  }
75  totalBytesRead += bytes_read;
76  if (totalBytesRead > readInitialStat.size) {
77  throw delayAdvisingError(path + " has grown while reading, (" +
78  std::to_string(readInitialStat.size) +
79  " -> " +
80  std::to_string(totalBytesRead) +
81  ")");
82  }
83 
84  b.bump_size(bytes_read);
85  }
86 
87  return lastblock;
88  }
89 
90 
92  struct dcapStat readFinalStatBuf;
93  dCapLock extraOptionLock;
94  throwcall::dcap::good0(dc_fstat(fd, &readFinalStatBuf), "can't stat path file ", path);
95  genericStat readFinalStat(readFinalStatBuf, std::chrono::seconds(1));
96  if (readFinalStat.size != readInitialStat.size) {
97  throw delayAdvisingError("file size has changed (" +
98  std::to_string(readInitialStat.size) +
99  " -> " +
100  std::to_string(readFinalStat.size) +
101  ") during reading on " + path);
102  }
103 
104  if (!readFinalStat.isSameMtimeAs(readInitialStat)) {
105  throw delayAdvisingError("file " + path + " was modified (" +
106  std::to_string(std::chrono::duration_cast<std::chrono::duration<double>>(readFinalStat.getMtime() - readInitialStat.getMtime()).count()) +
107  "s different mtime) during reading");
108  }
109  }
110  dcap::dcapDirectory::dcapDirectory(const std::string& aPath):
111  Directory(dcapCommon::fixPathUrl(aPath)) {
112  dCapLock extraOptionLock;
113  dir = throwcall::dcap::badval(dc_opendir(path.c_str()), nullptr, "can't open directory ", path);
114  }
116  dCapLock extraOptionLock;
117  if (isUnwinding()) {
118  if (dc_closedir(dir) != 0) {
120  path, "close directory during unwind ",
121  dc_strerror(dc_errno));
122  }
123  } else {
124  throwcall::dcap::good0(dc_closedir(dir), "can't close directory ", path);
125  }
126  }
127  std::unique_ptr<base::Directory::Entry> dcap::dcapDirectory::getNextEntry(bool ignoreMissing) {
128  dCapLock extraOptionLock;
129  while (auto entry = dc_readdir(dir)) {
130  if (entry->d_name[entry->d_name[0] != '.' ? 0 : entry->d_name[1] != '.' ? 1 : 2] == '\0') {
131  continue; // skip . .. and empty strings
132  }
133  struct dcapStat statbuf;
134  auto entrypath(dcapCommon::fixPathUrl(path + "/" + entry->d_name));
135  auto result = dc_stat(entrypath.c_str(), &statbuf);
136  if (result != 0 && errno == ENOENT && ignoreMissing) {
137  continue;
138  }
139  throwcall::dcap::good0(result, "can't stat ", entrypath);
140  auto genStat = std::unique_ptr<const genericStat>(new genericStat(statbuf, std::chrono::seconds(1)));
141  return std::unique_ptr<Entry>(new Entry(entry->d_name, genStat));
142  }
143  return nullptr;
144  }
145  std::unique_ptr<base::Directory> dcap::getDirectory(const std::string& path) {
146  return std::unique_ptr<Directory>(new dcapDirectory(path));
147  }
148 
149 } //end namespace inputHandler
block.h
delayAdvisingError
class for exceptions that advise for delays Exceptions of this kind are to be thrown when circumstanc...
Definition: inputHandler.h:22
throwcall::dcap::badval
T badval(T call, t badvalue, const Args &... args)
Definition: dcapCommon.h:28
errMsgQueue.h
block::max_size
size_t max_size() const
Definition: block.h:22
dcapIoCommon
Definition: dcapCommon.h:74
inputHandler
Definition: inputHandler.h:29
inputHandler::dcap::dcapDirectory::dir
DIR * dir
Definition: inputHandlerDcap.h:33
errMsg::location
class for defining the location of a error message in the source code.
Definition: errMsgQueue.h:14
inputHandler::dcap::newReader
std::unique_ptr< reader > newReader(const std::string &aPath, copyRequest::stateType &state, const genericStat &inititalStat) override
get a reader for the file at path
Definition: inputHandlerDcap.cpp:13
dCapLock
Definition: dcapCommon.h:40
genericStat
generic stat abstraction class Used to abstract the variants of the stat structure.
Definition: genericStat.h:12
copyRequestTypes.h
dcapStat
#define dcapStat
Definition: dcapCommon.h:7
inputHandlerDcap.h
inputHandler::dcap::readerDcap
Definition: inputHandlerDcap.h:18
inputHandler::dcap::readerDcap::checkUnchangedness
void checkUnchangedness() override
Definition: inputHandlerDcap.cpp:91
genericStat::getMtime
void getMtime(struct timespec &spec) const
Definition: genericStat.cpp:65
dcapIoCommon::path
const std::string path
Definition: dcapCommon.h:76
inputHandler::dcap::readerDcap::~readerDcap
~readerDcap() override
Definition: inputHandlerDcap.cpp:39
copyRequest::stateBitType::vanished
@ vanished
block::bump_size
void bump_size(size_t additionalBytes)
Definition: block.h:33
copyRequest::stateType
Definition: copyRequestTypes.h:66
genericStat::isSameMtimeAs
bool isSameMtimeAs(const genericStat &that) const
Definition: genericStat.cpp:87
readRateLimit
throttle::watch readRateLimit
errMsg::level::debug
@ debug
ioHandle::blockSize
size_t blockSize
in bytes, block size to be used when reading or writing
Definition: ioHandle.h:17
inputHandler::dcap::factory
static factoryTemplate< dcap > factory
Definition: inputHandlerDcap.h:15
genericStat::size
size_t size
Definition: genericStat.h:16
inputHandler::dcap::getDirectory
std::unique_ptr< Directory > getDirectory(const std::string &path) override
Definition: inputHandlerDcap.cpp:145
block::bufferAt
void * bufferAt(size_t offset)
only way to access the data in the block
Definition: block.cpp:28
dcapCommon::fixPathUrl
static std::string fixPathUrl(const std::string &path)
Definition: dcapCommon.cpp:127
inputHandler::dcap::readerDcap::readBlock
bool readBlock(block &b) override
Definition: inputHandlerDcap.cpp:55
block
data block, used to hold the data that are being copied (or checksummed).
Definition: block.h:7
inputHandler::base::Directory
Definition: inputHandler.h:159
inputHandler::dcap::dcapDirectory::~dcapDirectory
~dcapDirectory() noexcept(false) override
Definition: inputHandlerDcap.cpp:115
inputHandler::dcap::dcapDirectory::getNextEntry
std::unique_ptr< Entry > getNextEntry(bool ignoreMissing) override
Definition: inputHandlerDcap.cpp:127
inputHandler::base::Directory::path
const std::string path
Definition: inputHandler.h:161
throttle::watch::wait
void wait()
Definition: throttle.h:50
errMsg::emit
void emit(level aLogLevel, const location &loc, const std::string &aObject, const std::string &aAction, const Args &... args)
function to create and enqueue a message, this is the only way that messages should be created!
Definition: errMsgQueue.h:148
throwcall::dcap::good0
void good0(T call, const Args &... args)
Definition: dcapCommon.h:21
block::size
size_t size() const
Definition: block.h:16
inputHandler::dcap::readerDcap::readerDcap
readerDcap(const std::string &aPath, copyRequest::stateType &state, const genericStat &inititalStat)
Definition: inputHandlerDcap.cpp:22
block::clear
void clear(size_t aOffset)
Definition: block.h:28
dcapIoCommon::fd
int fd
Definition: dcapCommon.h:77
dcapCommon
Definition: dcapCommon.h:65
inputHandler::base::Directory::Entry
Definition: inputHandler.h:163
throttle::watch::update
void update(double units=1.0)
Definition: throttle.h:35
inputHandler::dcap::dcapDirectory
Definition: inputHandlerDcap.h:32
inputHandler::dcap::dcapDirectory::dcapDirectory
dcapDirectory(const std::string &aPath)
Definition: inputHandlerDcap.cpp:110
ewmscp.h