This commit is contained in:
chenzhikai 2021-11-18 11:44:52 +08:00
commit 50b5dcb328
7 changed files with 94 additions and 46 deletions

View File

@ -4,3 +4,4 @@ add_subdirectory(systemtime)
add_subdirectory(hardware)
add_subdirectory(proc)
add_subdirectory(packages)
add_subdirectory(filesystem)

View File

@ -0,0 +1 @@
add_subdirectory(filewatcher)

View File

@ -0,0 +1,19 @@
set (CMAKE_AUTOMOC ON)
aux_source_directory(. SOURCECODE)
find_package(Qt5Core)
include_directories(${Qt5Core_INCLUDE_DIRS})
add_library(kyfilewatcher SHARED ${SOURCECODE})
add_executable(kyfilewatcher-test test/kyfilewatcher-test.cpp)
target_link_libraries(kyfilewatcher kylog kyconf systemd pthread)
target_link_libraries(kyfilewatcher-test kyfilewatcher kylog kyconf systemd pthread ${Qt5Core_LIBRARIES})
install(TARGETS kyfilewatcher
DESTINATION lib/kysdk/kysdk-system)
install(FILES libkyfilewatcher.hpp
DESTINATION include/kysdk/kysdk-system)
install(FILES libkyfilewatcher_global.hpp
DESTINATION include/kysdk/kysdk-system)

View File

@ -1,4 +1,5 @@
#include "filewatcher.h"
#include "libkyfilewatcher.hpp"
#include <libkylog.h>
#include <errno.h>
#include <sys/inotify.h>
#include <unistd.h>
@ -25,8 +26,6 @@ void* KYSDK_FILEWATCHER::fileWatcherThreadRunner(void *inst)
rd = read(core->watcherFd, events_buf, EVENTBUFLEN);
if (rd < (int)sizeof(struct inotify_event))
{
// log: no data accessed
qDebug() << "no data accessed";
continue;
}
@ -36,7 +35,6 @@ void* KYSDK_FILEWATCHER::fileWatcherThreadRunner(void *inst)
break;
event = (struct inotify_event *)events_pos;
// qDebug() << "wfd "<<event->wd<<" get event mask "<<event->mask;
char pathName[NAME_MAX];
snprintf(pathName, event->len, "%s", event->name);
@ -50,23 +48,33 @@ void* KYSDK_FILEWATCHER::fileWatcherThreadRunner(void *inst)
}
FileWatcher::FileWatcher()
: logfile("/tmp/watcher.log")
{
this->isActived = true;
this->quit = false;
this->watcherFd = inotify_init1(IN_CLOEXEC);
this->logfile.open(QFile::WriteOnly);
pthread_create(&this->threadRunner, nullptr, fileWatcherThreadRunner, this);
if (this->watcherFd <= 0)
{
klog_err("文件监听启动失败,错误码:%d\n", errno);
throw 2;
}
this->threadRunner = (pthread_t *)malloc(sizeof(pthread_t));
if (! this->threadRunner)
{
klog_err("文件监听启动失败,错误码:%d\n", errno);
throw 1;
}
pthread_create(this->threadRunner, nullptr, fileWatcherThreadRunner, this);
}
FileWatcher::~FileWatcher()
{
this->quit = true;
pthread_cancel(this->threadRunner);
pthread_join(this->threadRunner, nullptr);
this->logfile.close();
if (this->threadRunner)
{
pthread_cancel(*this->threadRunner);
pthread_join(*this->threadRunner, nullptr);
free(this->threadRunner);
}
this->isActived = false;
if (this->watcherFd > 0)
@ -110,8 +118,6 @@ QStringList FileWatcher::addWatchTargetRecursive(QString url, FileWatcherType ty
failedList.append(tmpURL);
}
logfile.close();
return failedList;
}
@ -230,17 +236,18 @@ void FileWatcher::clearWatchList()
this->watchList.clear();
this->fdCacheMap.clear();
// log
qDebug() << "Watcher List has been cleared.";
klog_info("文件监听列表已清空\n");
}
void FileWatcher::pauseWatcher()
{
klog_info("文件监听已暂停\n");
this->isActived = false;
}
void FileWatcher::restartWatcher()
{
klog_info("文件监听已恢复\n");
this->isActived = true;
}
@ -288,7 +295,7 @@ void FileWatcher::sendSignal(int wfd, QString name, int mask)
if (isSubFile)
url += "/" + name;
qDebug() << url << " event "<< mask;
// qDebug() << url << " event "<< mask;
if (mask & IN_ACCESS)
{
@ -371,6 +378,7 @@ int FileWatcher::addWatchFile(FileWatcher::FileDescription node)
{
// log
qDebug() << node.url <<"监听符添加失败:"<<errno;
klog_err("文件[%s]监听添加失败,错误码%d\n", node.url.toStdString().c_str(), errno);
return -1;
}
this->fdCacheMap.insert(node.wfd, node.url);
@ -384,7 +392,7 @@ int FileWatcher::addWatchFile(FileWatcher::FileDescription node)
this->updateWatchFileAttribute(node.url, node.attr);
}
// log
klog_debug("文件[%s]已加入监听\n", node.url.toStdString().c_str());
qDebug() << "Watcher for "<<node.url<<" has been added.";
return 0;
@ -401,12 +409,12 @@ int FileWatcher::removeWatchFile(QString url)
{
fdCacheMap.remove(watchList[url].wfd);
watchList.remove(url);
// log
klog_debug("文件[%s]监听已移除\n", url.toStdString().c_str());
qDebug() << "Watcher for "<<url<<" has been removed.";
}
else
{
// log
klog_err("文件[%s]监听移除失败,错误码:%d\n", url.toStdString().c_str(), errno);
qDebug() << "remove watcher for "<<url<<" with wfd" <<this->watchList[url].wfd<<" failed. "<<errno;
}
}
@ -482,40 +490,32 @@ QStringList FileWatcher::getChildFile(QString parent, int depth, int maxdepth, i
return res;
int index = 0;
char buf[1024];
do {
QFileInfo finfo = finfolist.at(index);
if ((recurType & TMPFILE) == 0 && finfo.fileName().startsWith("~"))
{
sprintf(buf, "%s is tmpfile, skip.\n", finfo.absoluteFilePath().toStdString().c_str());
logfile.write(buf);
klog_info("文件[%s]是临时文件,略过\n", finfo.absoluteFilePath().toStdString().c_str());
index ++;
continue;
}
if ((recurType & HIDDEN) == 0 && finfo.fileName().startsWith("."))
{
sprintf(buf, "%s is hidden, skip.\n", finfo.absoluteFilePath().toStdString().c_str());
logfile.write(buf);
klog_info("文件[%s]是隐藏文件,略过\n", finfo.absoluteFilePath().toStdString().c_str());
index ++;
continue;
}
if (finfo.isDir())
{
sprintf(buf, "%s is dir, search for it's subfile.\n", finfo.absoluteFilePath().toStdString().c_str());
logfile.write(buf);
klog_info("文件[%s]是一个目录,略过\n", finfo.absoluteFilePath().toStdString().c_str());
res.append(this->getChildFile(finfo.absoluteFilePath(), depth + 1, maxdepth));
if (recurType & DIR)
res.append(finfo.absoluteFilePath());
sprintf(buf, "append %s\n", finfo.absoluteFilePath().toStdString().c_str());
logfile.write(buf);
}
else
{
res.append(finfo.absoluteFilePath());
sprintf(buf, "append %s\n", finfo.absoluteFilePath().toStdString().c_str());
logfile.write(buf);
}
index ++;
}while (index < finfolist.size());
@ -547,7 +547,6 @@ QStringList FileWatcher::getChildDir(QString parent, int depth, int maxdepth, in
return res;
int index = 0;
char buf[1024];
do {
QFileInfo finfo = finfolist.at(index);
@ -555,24 +554,18 @@ QStringList FileWatcher::getChildDir(QString parent, int depth, int maxdepth, in
{
if ((recurType & TMPFILE) == 0 && finfo.fileName().startsWith("~"))
{
sprintf(buf, "%s is tmpdir, skip.\n", finfo.absoluteFilePath().toStdString().c_str());
logfile.write(buf);
klog_info("文件[%s]是临时文件,略过\n", finfo.absoluteFilePath().toStdString().c_str());
index ++;
continue;
}
if ((recurType & HIDDEN) == 0 && finfo.fileName().startsWith("."))
{
sprintf(buf, "%s is hidden, skip.\n", finfo.absoluteFilePath().toStdString().c_str());
logfile.write(buf);
klog_info("文件[%s]是隐藏文件,略过\n", finfo.absoluteFilePath().toStdString().c_str());
index ++;
continue;
}
sprintf(buf, "%s is dir, search for it's subfile.\n", finfo.absoluteFilePath().toStdString().c_str());
logfile.write(buf);
res.append(this->getChildDir(finfo.absoluteFilePath(), depth + 1, maxdepth));
res.append(finfo.absoluteFilePath());
sprintf(buf, "append %s\n", finfo.absoluteFilePath().toStdString().c_str());
logfile.write(buf);
}
else
break;

View File

@ -1,7 +1,7 @@
#ifndef KYSDK_FILEWATCHER_H
#define KYSDK_FILEWATCHER_H
#ifndef KDK_SYSTEM_FILEWATCHER_H__
#define KDK_SYSTEM_FILEWATCHER_H__
#include "filewatcher_global.h"
#include "libkyfilewatcher_global.hpp"
#include <QObject>
#include <QHash>
#include <QThread>
@ -136,9 +136,7 @@ private:
int watcherFd;
bool isActived;
bool quit;
pthread_t threadRunner;
QFile logfile;
pthread_t *threadRunner;
friend void* fileWatcherThreadRunner(void *inst);
int addWatchFile(FileDescription node);

View File

@ -0,0 +1,36 @@
#include <QCoreApplication>
#include <QDebug>
#include "../libkyfilewatcher.hpp"
using namespace KYSDK_FILEWATCHER;
int main(int argc, char *argv[])
{
KYSDK_FILEWATCHER::FileWatcher watcher;
watcher.addWatchTargetRecursive("/home/kylin/", PERIODIC, ALL, 3, REGULAR);
getchar();
// qDebug() << "update attr test";
// watcher.updateWatchTargetAttribute("/data/testcode/test.c", DELETE);
// getchar();
// qDebug() << "re-add test";
// watcher.addWatchTarget("/data/testcode/test.c", PERIODIC, ALL);
// getchar();
// qDebug() << "update oneshot test";
// watcher.updateWatchTargetType("/data/testcode/test.c", ONESHOT);
// getchar();
// qDebug() << "remove target test";
// watcher.removeWatchTarget("/data/testcode/test.c");
// getchar();
watcher.clearWatchList();
return 0;
}