Skip to content

Commit

Permalink
monitor dir;
Browse files Browse the repository at this point in the history
  • Loading branch information
RealChuan committed Aug 3, 2023
1 parent cd176fe commit 137896f
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 72 deletions.
12 changes: 10 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,22 @@ jobs:
with:
fetch-depth: 1

- name: Configure Windows
- name: Enable Developer Command Prompt
if: startsWith(matrix.os, 'windows')
uses: ilammy/[email protected]
with:
arch: amd64
- name: Configure windows
if: startsWith(matrix.os, 'windows')
shell: bash
run: |
cmake \
-S . \
-B ./build \
-A x64 \
-DCMAKE_C_COMPILER=cl \
-DCMAKE_CXX_COMPILER=cl \
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \
-G "${{ matrix.generators }}" \
-DCMAKE_INSTALL_PREFIX:PATH=instdir
- name: Configure macos or ubuntu
if: startsWith(matrix.os, 'macos') || startsWith(matrix.os, 'ubuntu')
Expand Down
11 changes: 2 additions & 9 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,10 @@ message(STATUS "Current Platform is ${CURRENT_PLATFORM}")
# 设定可执行二进制文件的目录
set(EXECUTABLE_OUTPUT_PATH
${PROJECT_SOURCE_DIR}/bin${CURRENT_PLATFORM}/${CMAKE_BUILD_TYPE}) # 源文件目录
# SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin) #输出文件目录

# 设定存放编译出来的库文件的目录
set(LIBRARY_OUTPUT_PATH
${PROJECT_SOURCE_DIR}/lib${CURRENT_PLATFORM}/${CMAKE_BUILD_TYPE})
# SET(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib)

set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin${CURRENT_PLATFORM}/libs)
# 并且把该目录设为连接目录
link_directories(
${PROJECT_SOURCE_DIR}/lib${CURRENT_PLATFORM}/${CMAKE_BUILD_TYPE})
# LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/lib)
link_directories(${LIBRARY_OUTPUT_PATH})

include_directories(${PROJECT_SOURCE_DIR})

Expand Down
52 changes: 30 additions & 22 deletions MonitorDir/monitordir_linux.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "monitordir.hpp"

#include <cassert>
#include <fcntl.h>
#include <iostream>
#include <sys/inotify.h>
Expand Down Expand Up @@ -35,7 +36,7 @@ class MonitorDir::MonitorDirPrivate
}
}

auto addWatch(const std::string &dir) -> bool
auto addWatch() -> bool
{
// 添加监控目录
watchFd = inotify_add_watch(inotifyFd, dir.c_str(), IN_ALL_EVENTS);
Expand Down Expand Up @@ -69,53 +70,56 @@ class MonitorDir::MonitorDirPrivate
return;
}

std::string fileEvent;
for (char *ptr = buf; ptr < buf + len; ptr += sizeof(struct inotify_event) + event->len) {
event = reinterpret_cast<struct inotify_event *>(ptr);
if ((event->mask & IN_CREATE) != 0U) {
std::cout << "IN_CREATE: " << event->name << std::endl;
fileEvent = "IN_CREATE: ";
} else if ((event->mask & IN_DELETE) != 0U) {
std::cout << "IN_DELETE: " << event->name << std::endl;
fileEvent = "IN_DELETE: ";
} else if ((event->mask & IN_MODIFY) != 0U) {
std::cout << "IN_MODIFY: " << event->name << std::endl;
fileEvent = "IN_MODIFY: ";
} else if ((event->mask & IN_MOVED_FROM) != 0U) {
std::cout << "IN_MOVED_FROM: " << event->name << std::endl;
fileEvent = "IN_MOVED_FROM: ";
} else if ((event->mask & IN_MOVED_TO) != 0U) {
std::cout << "IN_MOVED_TO: " << event->name << std::endl;
fileEvent = "IN_MOVED_TO: ";
} else if ((event->mask & IN_CLOSE_WRITE) != 0U) {
std::cout << "IN_CLOSE_WRITE: " << event->name << std::endl;
fileEvent = "IN_CLOSE_WRITE: ";
} else if ((event->mask & IN_CLOSE_NOWRITE) != 0U) {
std::cout << "IN_CLOSE_NOWRITE: " << event->name << std::endl;
fileEvent = "IN_CLOSE_NOWRITE: ";
} else if ((event->mask & IN_ACCESS) != 0U) {
std::cout << "IN_ACCESS: " << event->name << std::endl;
fileEvent = "IN_ACCESS: ";
} else if ((event->mask & IN_ATTRIB) != 0U) {
std::cout << "IN_ATTRIB: " << event->name << std::endl;
fileEvent = "IN_ATTRIB: ";
} else if ((event->mask & IN_OPEN) != 0U) {
std::cout << "IN_OPEN: " << event->name << std::endl;
fileEvent = "IN_OPEN: ";
} else if ((event->mask & IN_DELETE_SELF) != 0U) {
std::cout << "IN_DELETE_SELF: " << event->name << std::endl;
fileEvent = "IN_DELETE_SELF: ";
} else if ((event->mask & IN_MOVE_SELF) != 0U) {
std::cout << "IN_MOVE_SELF: " << event->name << std::endl;
fileEvent = "IN_MOVE_SELF: ";
} else if ((event->mask & IN_UNMOUNT) != 0U) {
std::cout << "IN_UNMOUNT: " << event->name << std::endl;
fileEvent = "IN_UNMOUNT: ";
} else if ((event->mask & IN_Q_OVERFLOW) != 0U) {
std::cout << "IN_Q_OVERFLOW: " << event->name << std::endl;
fileEvent = "IN_Q_OVERFLOW: ";
} else if ((event->mask & IN_IGNORED) != 0U) {
std::cout << "IN_IGNORED: " << event->name << std::endl;
fileEvent = "IN_IGNORED: ";
} else if ((event->mask & IN_ISDIR) != 0U) {
std::cout << "IN_ISDIR: " << event->name << std::endl;
fileEvent = "IN_ISDIR: ";
} else {
std::cout << "UNKNOWN: " << event->name << std::endl;
fileEvent = "UNKNOWN: ";
}
fileEvent += event->name;
std::cout << fileEvent << std::endl;
}
}

void run(const std::string &dir)
void run()
{
if (!createFd()) {
return;
}

if (!addWatch(dir)) {
if (!addWatch()) {
closeFd();
return;
}
Expand All @@ -133,6 +137,7 @@ class MonitorDir::MonitorDirPrivate
int inotifyFd = -1;
int watchFd = -1;

std::filesystem::path dir;
std::atomic_bool isRunning;
std::thread monitorThread;
};
Expand All @@ -141,7 +146,10 @@ MonitorDir::MonitorDir(const std::filesystem::path &dir)
: d_ptr(std::make_unique<MonitorDirPrivate>(this))
, m_dir(dir)
, m_isRunning(false)
{}
{
assert(std::filesystem::is_directory(dir) && std::filesystem::exists(dir));
d_ptr->dir = dir;
}

MonitorDir::~MonitorDir()
{
Expand All @@ -157,7 +165,7 @@ auto MonitorDir::start() -> bool

m_isRunning.store(true);
d_ptr->monitorThread = std::thread([this] {
d_ptr->run(m_dir.string());
d_ptr->run();
m_isRunning.store(false);
});

Expand Down
51 changes: 30 additions & 21 deletions MonitorDir/monitordir_mac.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,43 +23,45 @@ class MonitorDir::MonitorDirPrivate
{
//auto *monitorDir = static_cast<MonitorDirPrivate *>(clientCallBackInfo);
char **paths = static_cast<char **>(eventPaths);
std::string fileEvent;
for (size_t i = 0; i < numEvents; ++i) {
std::string path = paths[i];
if ((eventFlags[i] & kFSEventStreamEventFlagItemCreated) != 0U) {
std::cout << "Created: " << path << std::endl;
fileEvent = "Created: ";
} else if ((eventFlags[i] & kFSEventStreamEventFlagItemRemoved) != 0U) {
std::cout << "Removed: " << path << std::endl;
fileEvent = "Removed: ";
} else if ((eventFlags[i] & kFSEventStreamEventFlagItemRenamed) != 0U) {
std::cout << "Renamed: " << path << std::endl;
fileEvent = "Renamed: ";
} else if ((eventFlags[i] & kFSEventStreamEventFlagItemModified) != 0U) {
std::cout << "Modified: " << path << std::endl;
fileEvent = "Modified: ";
} else if ((eventFlags[i] & kFSEventStreamEventFlagItemInodeMetaMod) != 0U) {
std::cout << "InodeMetaMod: " << path << std::endl;
fileEvent = "InodeMetaMod: ";
} else if ((eventFlags[i] & kFSEventStreamEventFlagItemChangeOwner) != 0U) {
std::cout << "ChangeOwner: " << path << std::endl;
fileEvent = "ChangeOwner: ";
} else if ((eventFlags[i] & kFSEventStreamEventFlagItemXattrMod) != 0U) {
std::cout << "XattrMod: " << path << std::endl;
fileEvent = "XattrMod: ";
} else if ((eventFlags[i] & kFSEventStreamEventFlagItemIsFile) != 0U) {
std::cout << "IsFile: " << path << std::endl;
fileEvent = "IsFile: ";
} else if ((eventFlags[i] & kFSEventStreamEventFlagItemIsDir) != 0U) {
std::cout << "IsDir: " << path << std::endl;
fileEvent = "IsDir: ";
} else if ((eventFlags[i] & kFSEventStreamEventFlagItemIsSymlink) != 0U) {
std::cout << "IsSymlink: " << path << std::endl;
fileEvent = "IsSymlink: ";
} else if ((eventFlags[i] & kFSEventStreamEventFlagOwnEvent) != 0U) {
std::cout << "OwnEvent: " << path << std::endl;
fileEvent = "OwnEvent: ";
} else if ((eventFlags[i] & kFSEventStreamEventFlagItemIsHardlink) != 0U) {
std::cout << "IsHardlink: " << path << std::endl;
fileEvent = "IsHardlink: ";
} else if ((eventFlags[i] & kFSEventStreamEventFlagItemIsLastHardlink) != 0U) {
std::cout << "IsLastHardlink: " << path << std::endl;
fileEvent = "IsLastHardlink: ";
} else if ((eventFlags[i] & kFSEventStreamEventFlagItemCloned) != 0U) {
std::cout << "Cloned: " << path << std::endl;
fileEvent = "Cloned: ";
} else {
std::cout << "Unknown: " << path << std::endl;
fileEvent = "Unknown: ";
}
fileEvent += paths[i];
std::cout << fileEvent << std::endl;
}
}

void monitor(const std::string &dir)
void monitor()
{
std::cout << "addWatch: " << dir << std::endl;
CFStringRef pathToWatch = CFStringCreateWithCString(kCFAllocatorDefault,
Expand Down Expand Up @@ -90,26 +92,33 @@ class MonitorDir::MonitorDirPrivate

void stop()
{
if (nullptr == runLoop) {
return;
}
if (CFRunLoopIsWaiting(runLoop) == 0U) {
CFRunLoopWakeUp(runLoop);
}
CFRunLoopStop(runLoop);
}

void run(const std::string &dir) { monitor(dir); }
void run() { monitor(); }

MonitorDir *q_ptr;

CFRunLoopRef runLoop;
CFRunLoopRef runLoop = nullptr;

std::filesystem::path dir;
std::thread monitorThread;
};

MonitorDir::MonitorDir(const std::filesystem::path &dir)
: d_ptr(std::make_unique<MonitorDirPrivate>(this))
, m_dir(dir)
, m_isRunning(false)
{}
{
assert(std::filesystem::is_directory(dir) && std::filesystem::exists(dir));
d_ptr->dir = dir;
}

MonitorDir::~MonitorDir()
{
Expand All @@ -125,7 +134,7 @@ bool MonitorDir::start()

m_isRunning.store(true);
d_ptr->monitorThread = std::thread([this] {
d_ptr->run(m_dir.string());
d_ptr->run();
m_isRunning.store(false);
});

Expand Down
38 changes: 20 additions & 18 deletions MonitorDir/monitordir_win.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "monitordir.hpp"

#include <cassert>
#include <condition_variable>
#include <iostream>
#include <thread>
Expand Down Expand Up @@ -31,10 +32,10 @@ class MonitorDir::MonitorDirPrivate

~MonitorDirPrivate() = default;

auto createHandle(const std::string &dir) -> bool
auto createHandle() -> bool
{
// 创建目录句柄
directoryHandle = CreateFile(dir.c_str(),
directoryHandle = CreateFile(dir.string().c_str(),
FILE_LIST_DIRECTORY,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
Expand Down Expand Up @@ -79,7 +80,7 @@ class MonitorDir::MonitorDirPrivate
}
}

void monitor(const std::string &dir)
void monitor()
{
char notifyBuffer[BUFSIZ] = {0};
DWORD bytesReturned = 0;
Expand Down Expand Up @@ -121,7 +122,7 @@ class MonitorDir::MonitorDirPrivate
// 通知目录变化
std::string fileEvent;
PFILE_NOTIFY_INFORMATION notifyInfo = (PFILE_NOTIFY_INFORMATION) notifyBuffer;
do {
while (isRunning.load()) {
std::wstring fileName(notifyInfo->FileName,
notifyInfo->FileNameLength / sizeof(wchar_t));
std::string fileNameUtf8 = utf8_encode(fileName);
Expand All @@ -136,19 +137,21 @@ class MonitorDir::MonitorDirPrivate
case FILE_ACTION_RENAMED_NEW_NAME:
fileEvent = "renamed new name: " + fileNameUtf8;
break;
default: break;
default: fileEvent = "unknown: " + fileNameUtf8; break;
}
std::cout << fileEvent << std::endl;

if (notifyInfo->NextEntryOffset == 0) {
break;
}
notifyInfo = (PFILE_NOTIFY_INFORMATION) ((LPBYTE) notifyInfo
+ notifyInfo->NextEntryOffset);
} while (notifyInfo->NextEntryOffset != 0);

std::cout << fileEvent << std::endl;
}
}

void run(const std::string &dir)
void run()
{
if (!createHandle(dir)) {
if (!createHandle()) {
return;
}
if (!createEvent()) {
Expand All @@ -157,26 +160,22 @@ class MonitorDir::MonitorDirPrivate
}
isRunning.store(true);
while (isRunning.load()) {
monitor(dir);
monitor();
}
closeEvent();
closeHandle();
}

MonitorDir *q_ptr;

std::string fileExtension;
std::string filePattern;
std::string filePatternRegex;
std::string filePatternRegexFlags;

DWORD filters = FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME
| FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE
| FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_LAST_ACCESS
| FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_SECURITY;
HANDLE directoryHandle = INVALID_HANDLE_VALUE;
OVERLAPPED overlapped;

std::filesystem::path dir;
std::atomic_bool isRunning;
std::thread monitorThread;
};
Expand All @@ -185,7 +184,10 @@ MonitorDir::MonitorDir(const std::filesystem::path &dir)
: d_ptr(std::make_unique<MonitorDirPrivate>(this))
, m_dir(dir)
, m_isRunning(false)
{}
{
assert(std::filesystem::is_directory(dir) && std::filesystem::exists(dir));
d_ptr->dir = dir;
}

MonitorDir::~MonitorDir()
{
Expand All @@ -200,7 +202,7 @@ auto MonitorDir::start() -> bool
}
m_isRunning.store(true);
d_ptr->monitorThread = std::thread([this]() {
d_ptr->run(m_dir.string());
d_ptr->run();
m_isRunning.store(false);
});
return true;
Expand Down

0 comments on commit 137896f

Please sign in to comment.