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

View File

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