 |
ewmscp
..
|
The inotify_watch command watches recursively a set of directories for a set of events and creates commands in the format understood by The ewmscp command.
More...
The inotify_watch command watches recursively a set of directories for a set of events and creates commands in the format understood by The ewmscp command.
- Bug:
- When an anonymous tmp file is created and made visible via open(dirpath, O_WRONLY|O_TMPFILE);inkat(AT_FDCWD, "/proc/self/fd/%fd", AT_FDCWD, path, AT_SYMLINK_FOLLOW) no CLOSE_WRITE event is triggered. Not likely to happen as SL7/Centos7's kernel does not support O_TMPFILE, and also NFS does not support it (apparently)
- Bug:
- When a file in a watched directory has a hard link from an unwatched directory and is modified using that other link no notification is produced.
◆ watchDirectoryReturnType
special enum for the return values of watchDirectory.
Enumerator |
---|
vanished | |
islink | |
ignore | |
iswatched | |
Definition at line 481 of file inotify_watch.cpp.
◆ main()
int main |
( |
int |
argc, |
|
|
const char * |
argv[] |
|
) |
| |
main inotify_watch function.
This is the main executable.
Definition at line 649 of file inotify_watch.cpp.
650 std::ios::sync_with_stdio(
false);
653 "directories to be watched");
655 "use DIRECTORY as work dir");
657 "regexp for files to be ignored for IN_CLOSE_WRITE");
659 "be verbose",
false);
661 "file to write errors to");
664 "extra events to listen to");
667 "extra events beside IN_CLOSE_NOWRITE hat trigger a copy");
669 parser.fParse(argc, argv);
672 errStream = &(errStreamBase.getStream());
678 std::cerr <<
"events of type ";
680 std::cerr <<
" (" << std::hex << copyTriggerBits << std::dec <<
") will trigger a copy event\n";
686 pidFile << getpid() <<
"\n";
700 for (
const auto& directory : directories) {
707 char buffer[4096 * 256] __attribute__ ((aligned(__alignof__(
struct inotify_event))));
724 auto event = copy->getEvent();
728 if (event->mask() & IN_MOVED_TO) {
742 auto meAsDirChild = parent->getChild(event->name());
754 auto result = poll(&pfd, 1, 1000);
757 if (errno == EINTR) {
765 for (
const auto& directory : directories) {
767 auto retval = stat(directory.c_str(), &statbuf);
769 if (retval != 0 && errno == ENOENT) {
780 -1,
"read inotification");
781 auto now = clock_type::now();
784 *
errStream <<
errPrefix << now <<
" got " << bytes <<
" bytes of notification" << std::endl;
791 event =
event->next()) {
793 *
errStream <<
errPrefix <<
"watch id " <<
event->wd() <<
" @ " << (
void*)event <<
" with name " << event->name() << *
event << std::endl;
796 if (event->mask() & IN_IGNORED) {
800 if (event->mask() & IN_Q_OVERFLOW) {
808 if (watchedDir ==
nullptr) {
809 *
errStream <<
errPrefix <<
"unknown watch id " <<
event->wd() <<
" @ " << (
void*)event <<
" with name " << event->name() << *
event << std::endl;
813 watchedDir->buildPath(path, event->name());
815 if (event->mask() & (IN_MOVED_TO | IN_MOVED_FROM)) {
819 std::string partnerPath;
823 const std::string* fromPath;
824 const std::string* toPath;
826 if (event->mask() & IN_MOVED_TO) {
827 from = partner->getEvent();
829 fromPath = &partnerPath;
833 to = partner->getEvent();
835 toPath = &partnerPath;
840 if (fromAsDirChild) {
849 if (event->mask() & copyTriggerBits) {
855 if (event->mask() & IN_CREATE) {
867 if (event->mask() & IN_DELETE_SELF) {
868 watchedDir->invalidateId();
876 if (event->mask() & IN_DELETE) {
893 }
catch (
const std::exception& e) {
References maskName::addToRange(), throwcall::badval(), watchedDirType::buildPath(), logstream::crit, inotify_event_copy::doCopyLeftovers(), watchedDirType::dump(), dumpRequested(), watchedDirType::empty(), errPrefix, errStream(), options::base::fIsSet(), inotify_event_copy::forget(), inotify_event_wrapper::fromChar(), watchedDirType::get(), watchedDirType::getAdoptedBy(), watchedDirType::getChild(), inotify_event_copy::getPartner(), inotify_event_copy::getStaleSingles(), logstream::provider::getStream(), throwcall::good0(), ignore, islink, iswatched, commandSender::keepalive(), maskName::maskFromList(), inotify_event_wrapper::name(), pidFileName, pidFileRemover(), maskName::print(), commandSender::sendCommand(), watchedDirType::setExtraEventMask(), sigPipeHandler(), sigTermHandler(), sigUsrHandler(), watchedDirType::size(), verbose, watchDirectory(), inotify_event_wrapper::wd(), and workDir.
◆ watchDirectory()
watch a directory.
The directory indicated by name will be watched, together with all the subdirs recursively. [in] fd is the fd of the inotify object, [in] name is the basename (if parent != null) of full path (no parent) of the directory. [in] parent pointer to the parent directory, may be nullpr for initial command line args
Definition at line 494 of file inotify_watch.cpp.
507 auto retval = lstat(path.c_str(), &statbuf);
509 if (retval && (errno == ENOENT || errno == ENOTDIR)) {
515 if (!S_ISDIR(statbuf.st_mode)) {
522 if (watchedDir->getId() == -1) {
528 std::list<std::string> subdirs;
530 auto result = opendir(path.c_str());
532 if (result ==
nullptr && (errno == ENOENT || errno == ENOTDIR)) {
539 while (
auto entry = readdir(dir)) {
540 if (entry->d_name[entry->d_name[0] !=
'.' ? 0 : entry->d_name[1] !=
'.' ? 1 : 2] ==
'\0') {
543 if (entry->d_type == DT_DIR) {
544 subdirs.emplace_back(entry->d_name);
549 for (
auto& subname : subdirs) {
References watchedDirType::buildPath(), throwcall::good0(), ignore, islink, iswatched, and vanished.
Referenced by main().
class that contains the parser, i.e. does that option handling
represents a watched directory inside a directory tree.
static void doCopyLeftovers()
options::single< bool > verbose
options::single< std::string > workDir
static inotify_event_copy * getPartner(const inotify_event_wrapper *event, clock_type::time_point then)
get partner of a half rename event.
class specialisation for options of type bool
T badval(T call, t badvalue, const Args &... args)
template function to wrap system calls that return a special bad value on failure
void buildPath(std::string &path)
fill path with the fill path to this directory
const char * name() const
static size_t size()
return number of watched directories
virtual bool fIsSet() const
check if this option was set, regardless of from command line or config file
wrapper for inotify_event with nicer interface.
static std::atomic< bool > dumpRequested(false)
std::ostream * errStream(nullptr)
static void forget(inotify_event_copy *what)
deletes a copy.
watchedDirType * getChild(const std::string &aName)
options::single< std::string > errPrefix('\0', "errPrefix", "prefix for error messages")
void getAdoptedBy(const std::string &newName, watchedDirType *newParent)
move to a new place in the directory tree.
void sendCommand(const char *command, std::chrono::system_clock::time_point when, const std::string &path)
static void sigUsrHandler(int)
static void pidFileRemover()
static void print(std::ostream &out, uint32_t mask)
class to flush output on scope basis.
static options::single< std::string > pidFileName('p', "pidFile", "name of PID file")
watchDirectoryReturnType watchDirectory(int fd, const std::string &name, watchedDirType *parent=nullptr)
watch a directory.
static void addToRange(options::container< std::string > &opt)
static uint32_t maskFromList(const options::container< std::string > &list)
static void setExtraEventMask(int extraMask)
static bool empty()
test if any directories are watched
static inotify_event_copy * getStaleSingles()
get the next old inotify_event.
static void dump(std::ostream &out)
static void sigPipeHandler(int)
void good0(T call, const Args &... args)
template function to wrap system calls that return 0 on success
static watchedDirType * get(int aId)
get a watcheDir by the inotify id
static const inotify_event_wrapper * fromChar(char *pointer)
static void sigTermHandler(int)
class used to send messages via stdout.