diff --git a/src/inotify_watch.cpp b/src/inotify_watch.cpp index 9d640e2ab2f2dac90cb7f5a6be77c837826b9164..4a133f839acd9a334560ee6af41465b6ca6aa30b 100644 --- a/src/inotify_watch.cpp +++ b/src/inotify_watch.cpp @@ -63,26 +63,60 @@ std::ostream* errStream(nullptr); options::single errPrefix('\0', "errPrefix", "prefix for error messages"); -struct maskName { - int bits; - const char *name; -}; -maskName maskNames[] = {{IN_ACCESS, "IN_ACCESS"}, - {IN_ATTRIB, "IN_ATTRIB"}, - {IN_CLOSE_WRITE, "IN_CLOSE_WRITE"}, - {IN_CLOSE_NOWRITE, "IN_CLOSE_NOWRITE"}, - {IN_CREATE, "IN_CREATE"}, - {IN_DELETE, "IN_DELETE"}, - {IN_DELETE_SELF, "IN_DELETE_SELF"}, - {IN_MODIFY, "IN_MODIFY"}, - {IN_MOVE_SELF, "IN_MOVE_SELF"}, - {IN_MOVED_FROM, "IN_MOVED_FROM"}, - {IN_MOVED_TO, "IN_MOVED_TO"}, - {IN_OPEN, "IN_OPEN"}, - {IN_IGNORED, "IN_IGNORED"}, - {IN_ISDIR, "IN_ISDIR"}, - {IN_Q_OVERFLOW, "IN_Q_OVERFLOW"}, - {IN_UNMOUNT, "IN_UNMOUNT"} +class maskName { + const uint32_t bits; + const std::string name; + maskName(uint32_t aBits,const std::string& aName): bits(aBits), name(aName){}; + static const std::array maskNames() { + static const std::array maskNamesArray {{{IN_ACCESS, "IN_ACCESS"}, + {IN_ATTRIB, "IN_ATTRIB"}, + {IN_CLOSE_WRITE, "IN_CLOSE_WRITE"}, + {IN_CLOSE_NOWRITE, "IN_CLOSE_NOWRITE"}, + {IN_CREATE, "IN_CREATE"}, + {IN_DELETE, "IN_DELETE"}, + {IN_DELETE_SELF, "IN_DELETE_SELF"}, + {IN_MODIFY, "IN_MODIFY"}, + {IN_MOVE_SELF, "IN_MOVE_SELF"}, + {IN_MOVED_FROM, "IN_MOVED_FROM"}, + {IN_MOVED_TO, "IN_MOVED_TO"}, + {IN_OPEN, "IN_OPEN"}, + {IN_IGNORED, "IN_IGNORED"}, + {IN_ISDIR, "IN_ISDIR"}, + {IN_Q_OVERFLOW, "IN_Q_OVERFLOW"}, + {IN_UNMOUNT, "IN_UNMOUNT"} + }}; + return(maskNamesArray); + } +public: + static void print(std::ostream& out, uint32_t mask) { + bool needComma = false; + + for (const auto &item : maskNames()) { + if (mask & item.bits) { + if (needComma) { + out << ","; + } + out << item.name; + needComma = true; + } + } + }; + static uint32_t maskFromList(const options::container& list) { + uint32_t mask = 0; + for (const auto& listItem : list) { + for (const auto& item : maskNames()) { + if (item.name == listItem) { + mask |= item.bits; + } + } + } + return mask; + }; + static void addToRange(options::container& opt) { + for (const auto& item : maskNames()) { + opt.fAddToRange(item.name); + } + }; }; @@ -126,19 +160,7 @@ class inotify_event_wrapper { } friend std::ostream& operator<<(std::ostream& out, const inotify_event_wrapper& aEvent) { out << " mask: "; - bool needComma = false; - - for (auto &item : maskNames) { - if (aEvent.mask() & item.bits) { - if (needComma) { - out << ","; - } - - out << item.name; - needComma = true; - } - } - + maskName::print(out, aEvent.mask()); out << "(" << aEvent.mask() << ")"; return out; } @@ -640,26 +662,23 @@ int main(int argc, const char* argv[]) { options::container extraEvents('e', "extraEvents", "extra events to listen to"); - for (const auto& item : maskNames) { - extraEvents.fAddToRange(item.name); - } + maskName::addToRange(extraEvents); + options::container copyTriggers('c', "copyTrigger", + "extra events beside IN_CLOSE_NOWRITE hat trigger a copy"); + maskName::addToRange(copyTriggers); parser.fParse(argc, argv); logstream::provider errStreamBase(errorStream, std::cerr); errStream = &(errStreamBase.getStream()); - { - int mask = 0; - for (const auto& extra : extraEvents) { - for (const auto& item : maskNames) { - if (item.name == extra) { - mask |= item.bits; - } - } - } - watchedDirType::setExtraEventMask(mask); - } + watchedDirType::setExtraEventMask(maskName::maskFromList(extraEvents)); + uint32_t copyTriggerBits = IN_CLOSE_WRITE | maskName::maskFromList(copyTriggers); + if (verbose) { + std::cerr << "events of type "; + maskName::print(std::cerr, copyTriggerBits); + std::cerr << " (" << std::hex << copyTriggerBits << std::dec << ") will trigger a copy event\n"; + } try { if (pidFileName != "") { @@ -827,7 +846,7 @@ int main(int argc, const char* argv[]) { } } - if (event->mask() & IN_CLOSE_WRITE) { + if (event->mask() & copyTriggerBits) { if (!(ignore.fIsSet() && regex_match(path, ignore))) { sender.sendCommand("cp", now, path); }