void SampleShadowFeature::runFileMonitor()

in source/shadow/SampleShadowFeature.cpp [196:281]


void SampleShadowFeature::runFileMonitor()
{
    int len = 0;
    string fileDir = FileUtils::ExtractParentDirectory(inputFile.c_str());
    string fileName = inputFile.substr(fileDir.length());
    char buf[EVENT_BUFSIZE];

    int fd = 0;
    int dir_wd = 0;
    int file_wd = 0;

    fd = inotify_init();

    if (fd == -1)
    {
        LOGM_ERROR(TAG, "Encounter error %d while initializing the inode notify system return s%", fd);
        return;
    }

    dir_wd = inotify_add_watch(fd, fileDir.c_str(), IN_CREATE);
    if (dir_wd == -1)
    {
        LOGM_ERROR(TAG, "Encounter error %d while adding the watch for input file's parent directory", fd);
        goto exit;
    }

    file_wd = inotify_add_watch(fd, inputFile.c_str(), IN_CLOSE_WRITE);
    if (file_wd == -1)
    {
        LOGM_ERROR(TAG, "Encounter error %d while adding the watch for target file", fd);
        goto exit;
    }

    while (!needStop.load())
    {
        len = read(fd, buf, EVENT_BUFSIZE);
        if (len <= 0)
        {
            LOG_WARN(TAG, "Couldn't monitor ant more target file modify events as it reaches max read buffer size");
            goto exit;
        }

        for (int i = 0; i < len;)
        {
            struct inotify_event *e = (struct inotify_event *)&buf[i];

            if (e->mask & IN_CREATE)
            {
                if (strcmp(e->name, fileName.c_str()) != 0)
                    goto next;

                if (e->mask & IN_ISDIR)
                    goto next;

                LOG_DEBUG(TAG, "New file is created with the same name of target file, start updating the shadow");
                readAndUpdateShadowFromFile();
                file_wd = inotify_add_watch(fd, inputFile.c_str(), IN_CLOSE_WRITE | IN_DELETE_SELF);
            }

            if (e->mask & IN_CLOSE_WRITE)
            {
                LOG_DEBUG(TAG, "The target file is modified, start updating the shadow");
                readAndUpdateShadowFromFile();
            }

            if (e->mask & IN_DELETE_SELF)
            {
                if (e->mask & IN_ISDIR)
                    goto next;

                LOG_DEBUG(TAG, "The target file is deleted by itself, removing the watch");
                inotify_rm_watch(fd, file_wd);
            }

        next:
            i += EVENT_SIZE + e->len;
        }

        this_thread::sleep_for(std::chrono::milliseconds(500));
    }

exit:
    inotify_rm_watch(fd, file_wd);
    inotify_rm_watch(fd, dir_wd);
    close(fd);
}