ewmscp  ..
Public Member Functions | Static Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | Static Private Attributes | List of all members
watchedDirType Class Reference

represents a watched directory inside a directory tree. More...

Collaboration diagram for watchedDirType:
[legend]

Public Member Functions

void buildPath (std::string &path)
 fill path with the fill path to this directory More...
 
void buildPath (std::string &path, const std::string &aName)
 fill path with the full path to a file in this directory More...
 
std::string getPath ()
 return full path to this dir, for use in error messages only More...
 
 watchedDirType (const std::string &aName, int aFd, watchedDirType *aParent=nullptr)
 construct a new watchedDir. More...
 
 ~watchedDirType ()
 destruct watchedDir. More...
 
void invalidateId ()
 
int getId () const
 
watchedDirTypegetChild (const std::string &aName)
 
void getAdoptedBy (const std::string &newName, watchedDirType *newParent)
 move to a new place in the directory tree. More...
 

Static Public Member Functions

static void dump (std::ostream &out)
 
static watchedDirTypeget (int aId)
 get a watcheDir by the inotify id More...
 
static bool empty ()
 test if any directories are watched More...
 
static size_t size ()
 return number of watched directories More...
 
static void setExtraEventMask (int extraMask)
 

Private Member Functions

void becomeChildOfMyParent (watchedDirType *aParent)
 set object a child of the parent. More...
 

Static Private Member Functions

static std::map< int, watchedDirType * > & getWatchedDirs ()
 

Private Attributes

std::string name
 basename of the directory, i.e. not the full path More...
 
watchedDirTypeparent
 
int fd
 fd for the inotify instance, needed for destructor More...
 
int id
 the watch id More...
 
std::map< std::string, watchedDirType * > children
 
decltype(getWatchedDirs().begin()) watchIterator
 iterator in the map that holds this object More...
 
decltype(children.begin()) childIterator
 iterator in parent's child map that holds this object More...
 

Static Private Attributes

static int extraEventMask = 0
 

Detailed Description

represents a watched directory inside a directory tree.

Holds pointers to paren and children in the tree as well as info on the inotify watch.

Definition at line 285 of file inotify_watch.cpp.

Constructor & Destructor Documentation

◆ watchedDirType()

watchedDirType::watchedDirType ( const std::string &  aName,
int  aFd,
watchedDirType aParent = nullptr 
)
inline

construct a new watchedDir.

If it has a parent then name is the basename of the directory, i.e. without path If parent is nullptr then name is the full path to the directory. [in] aFd is the fd to the inotify object. If something goes wrong the id will be -1. Also inserts this directory into the watched directory tree and the id map.

Definition at line 379 of file inotify_watch.cpp.

381  :
382  name(aName),
383  parent(aParent),
384  fd(aFd) {
385  std::string path;
386  buildPath(path);
387  watchIterator = getWatchedDirs().end();
388  id = inotify_add_watch(fd, path.c_str(),
389  IN_CLOSE_WRITE
390  | IN_DELETE
391  | IN_MOVED_TO | IN_MOVED_FROM
392  | IN_CREATE
393  | IN_DELETE_SELF
394  | IN_EXCL_UNLINK
395  | IN_DONT_FOLLOW
396  | IN_ONLYDIR
397  | extraEventMask);
398 
399  if (id == -1 && (errno == ENOENT || errno == ENOTDIR)) { // we fell prey to a race
400  parent = nullptr;
401  return;
402  }
403 
404  throwcall::badval(id, -1, "inotify_add_watch failed on ", path);
405 
406  auto result = getWatchedDirs().emplace(id, this);
407 
408  if (result.second == false) { // watch for this object already exists, declare this as invalid
409  parent = nullptr;
410  id = -1;
411  return;
412  } else {
413  watchIterator = result.first;
414  }
415 
416  becomeChildOfMyParent(aParent);
417  }

References throwcall::badval(), becomeChildOfMyParent(), buildPath(), extraEventMask, fd, getWatchedDirs(), parent, and watchIterator.

Here is the call graph for this function:

◆ ~watchedDirType()

watchedDirType::~watchedDirType ( )
inline

destruct watchedDir.

Unwatchews it in the inotify_object, removes it from the directory tree (destroig all leftover children, which should be gone now anyway), and unregisters it in the map.

Definition at line 424 of file inotify_watch.cpp.

424  {
425  if (id != -1) {
426  auto retval = inotify_rm_watch(fd, id);
427 
428  if (retval && errno == EINVAL) {
429  *errStream << errPrefix << "oops " << getPath() << " id " << id << "could not be unwatched" << std::endl;
430  } else {
431  throwcall::good0(retval, "can't unwatch ", getPath());
432  }
433  }
434 
435  if (watchIterator != getWatchedDirs().end()) {
436  getWatchedDirs().erase(watchIterator);
437  }
438 
439  for (auto& child : children) {
440  *errStream << errPrefix << "oops " << getPath() << " still has child " << child.second->getPath() << ", deleting it" << std::endl;
441  delete child.second;
442  }
443 
444  if (parent) {
445  parent->children.erase(childIterator);
446  }
447  }

References childIterator, children, errPrefix, errStream(), fd, getPath(), getWatchedDirs(), throwcall::good0(), parent, and watchIterator.

Here is the call graph for this function:

Member Function Documentation

◆ becomeChildOfMyParent()

void watchedDirType::becomeChildOfMyParent ( watchedDirType aParent)
inlineprivate

set object a child of the parent.

The parent should not have a child of this name, but in extreme stress cases it can have one. In order to continue working we "orphan" that child.

Definition at line 305 of file inotify_watch.cpp.

305  {
306  parent = aParent;
307 
308  if (parent) {
309  auto result = parent->children.emplace(name, this);
310 
311  if (result.second == false) {
312  result.first->second->parent = nullptr; // orphanize old child
313  result.first->second = this; // overwrite old child
314  }
315 
316  childIterator = result.first;
317  }
318  }

References childIterator, children, name, and parent.

Referenced by getAdoptedBy(), and watchedDirType().

Here is the caller graph for this function:

◆ buildPath() [1/2]

void watchedDirType::buildPath ( std::string &  path)
inline

fill path with the fill path to this directory

Definition at line 333 of file inotify_watch.cpp.

333  {
334  if (parent) {
335  parent->buildPath(path);
336  path += "/";
337  }
338 
339  path += name;
340  }

References buildPath(), name, and parent.

Referenced by buildPath(), getPath(), main(), watchDirectory(), and watchedDirType().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ buildPath() [2/2]

void watchedDirType::buildPath ( std::string &  path,
const std::string &  aName 
)
inline

fill path with the full path to a file in this directory

Definition at line 342 of file inotify_watch.cpp.

343  {
344  buildPath(path);
345  path += "/";
346  path += aName;
347  }

References buildPath().

Here is the call graph for this function:

◆ dump()

static void watchedDirType::dump ( std::ostream &  out)
inlinestatic

Definition at line 321 of file inotify_watch.cpp.

321  {
322  out << errPrefix << "begin list of watched directories (" << getWatchedDirs().size() << "):\n";
323  for (const auto& item: getWatchedDirs()) {
324  std::string path;
325  item.second->buildPath(path);
326  out << errPrefix << item.first << ": " << path << "\n";
327  }
328  out << errPrefix << "end list of watched directories.\n";
329  }

References errPrefix, and getWatchedDirs().

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ empty()

static bool watchedDirType::empty ( )
inlinestatic

test if any directories are watched

Definition at line 360 of file inotify_watch.cpp.

360  {
361  return getWatchedDirs().empty();
362  }

References getWatchedDirs().

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get()

static watchedDirType* watchedDirType::get ( int  aId)
inlinestatic

get a watcheDir by the inotify id

Definition at line 356 of file inotify_watch.cpp.

356  {
357  return getWatchedDirs()[aId];
358  }

References getWatchedDirs().

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getAdoptedBy()

void watchedDirType::getAdoptedBy ( const std::string &  newName,
watchedDirType newParent 
)
inline

move to a new place in the directory tree.

This is needed when a directory is moved (renamed) and changes the tree as well as the name of this directory.

Definition at line 467 of file inotify_watch.cpp.

468  {
469  if (parent) {
470  parent->children.erase(childIterator);
471  }
472 
473  name = newName;
474  becomeChildOfMyParent(newParent);
475  }

References becomeChildOfMyParent(), childIterator, children, name, and parent.

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getChild()

watchedDirType* watchedDirType::getChild ( const std::string &  aName)
inline

Definition at line 454 of file inotify_watch.cpp.

454  {
455  auto it = children.find(aName);
456 
457  if (it == children.end()) {
458  return nullptr;
459  } else {
460  return it->second;
461  }
462  }

References children.

Referenced by main().

Here is the caller graph for this function:

◆ getId()

int watchedDirType::getId ( ) const
inline

Definition at line 451 of file inotify_watch.cpp.

451  {
452  return id;
453  }

References id.

◆ getPath()

std::string watchedDirType::getPath ( )
inline

return full path to this dir, for use in error messages only

Definition at line 349 of file inotify_watch.cpp.

349  {
350  std::string path;
351  buildPath(path);
352  return path;
353  }

References buildPath().

Referenced by ~watchedDirType().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getWatchedDirs()

static std::map<int, watchedDirType*>& watchedDirType::getWatchedDirs ( )
inlinestaticprivate

Definition at line 286 of file inotify_watch.cpp.

286  {
287  static std::remove_reference<decltype(getWatchedDirs())>::type watchedDirs;
288  return watchedDirs;
289  }

Referenced by dump(), empty(), get(), size(), watchedDirType(), and ~watchedDirType().

Here is the caller graph for this function:

◆ invalidateId()

void watchedDirType::invalidateId ( )
inline

Definition at line 448 of file inotify_watch.cpp.

448  {
449  id = -1;
450  }

◆ setExtraEventMask()

static void watchedDirType::setExtraEventMask ( int  extraMask)
inlinestatic

Definition at line 368 of file inotify_watch.cpp.

368  {
369  extraEventMask = extraMask;
370  }

References extraEventMask.

Referenced by main().

Here is the caller graph for this function:

◆ size()

static size_t watchedDirType::size ( )
inlinestatic

return number of watched directories

Definition at line 364 of file inotify_watch.cpp.

364  {
365  return getWatchedDirs().size();
366  }

References getWatchedDirs().

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ childIterator

decltype(children.begin()) watchedDirType::childIterator
private

iterator in parent's child map that holds this object

Definition at line 298 of file inotify_watch.cpp.

Referenced by becomeChildOfMyParent(), getAdoptedBy(), and ~watchedDirType().

◆ children

std::map<std::string, watchedDirType*> watchedDirType::children
private

Definition at line 296 of file inotify_watch.cpp.

Referenced by becomeChildOfMyParent(), getAdoptedBy(), getChild(), and ~watchedDirType().

◆ extraEventMask

int watchedDirType::extraEventMask = 0
staticprivate

Definition at line 290 of file inotify_watch.cpp.

Referenced by setExtraEventMask(), and watchedDirType().

◆ fd

int watchedDirType::fd
private

fd for the inotify instance, needed for destructor

Definition at line 294 of file inotify_watch.cpp.

Referenced by watchedDirType(), and ~watchedDirType().

◆ id

int watchedDirType::id
private

the watch id

Definition at line 295 of file inotify_watch.cpp.

Referenced by getId().

◆ name

std::string watchedDirType::name
private

basename of the directory, i.e. not the full path

Definition at line 292 of file inotify_watch.cpp.

Referenced by becomeChildOfMyParent(), buildPath(), and getAdoptedBy().

◆ parent

watchedDirType* watchedDirType::parent
private

◆ watchIterator

decltype(getWatchedDirs().begin()) watchedDirType::watchIterator
private

iterator in the map that holds this object

Definition at line 297 of file inotify_watch.cpp.

Referenced by watchedDirType(), and ~watchedDirType().


The documentation for this class was generated from the following file:
watchedDirType::getWatchedDirs
static std::map< int, watchedDirType * > & getWatchedDirs()
Definition: inotify_watch.cpp:286
watchedDirType::name
std::string name
basename of the directory, i.e. not the full path
Definition: inotify_watch.cpp:292
throwcall::badval
T badval(T call, t badvalue, const Args &... args)
template function to wrap system calls that return a special bad value on failure
Definition: throwcall.h:54
watchedDirType::buildPath
void buildPath(std::string &path)
fill path with the fill path to this directory
Definition: inotify_watch.cpp:333
watchedDirType::id
int id
the watch id
Definition: inotify_watch.cpp:295
watchedDirType::childIterator
decltype(children.begin()) childIterator
iterator in parent's child map that holds this object
Definition: inotify_watch.cpp:298
errStream
std::ostream * errStream(nullptr)
errPrefix
options::single< std::string > errPrefix('\0', "errPrefix", "prefix for error messages")
watchedDirType::watchIterator
decltype(getWatchedDirs().begin()) watchIterator
iterator in the map that holds this object
Definition: inotify_watch.cpp:297
watchedDirType::becomeChildOfMyParent
void becomeChildOfMyParent(watchedDirType *aParent)
set object a child of the parent.
Definition: inotify_watch.cpp:305
watchedDirType::getPath
std::string getPath()
return full path to this dir, for use in error messages only
Definition: inotify_watch.cpp:349
watchedDirType::parent
watchedDirType * parent
Definition: inotify_watch.cpp:293
watchedDirType::fd
int fd
fd for the inotify instance, needed for destructor
Definition: inotify_watch.cpp:294
watchedDirType::children
std::map< std::string, watchedDirType * > children
Definition: inotify_watch.cpp:296
throwcall::good0
void good0(T call, const Args &... args)
template function to wrap system calls that return 0 on success
Definition: throwcall.h:40
watchedDirType::extraEventMask
static int extraEventMask
Definition: inotify_watch.cpp:290