// // Created by xajhuang on 2023/2/9. // #include #include "uthash/uthash.h" #include "misc.h" #include "common.h" #include "user_errno.h" #include "zlog_module.h" #include "task_manager.h" #include "fs_watch.h" typedef struct { char watchPath[MAX_PATH]; watch_cb pCb; uv_fs_event_t *uv_event; UT_hash_handle hh; ///< UT Hash handle } WATCH_CONTENT, *PWATCH_CONTENT; PWATCH_CONTENT g_watchContent = NULL; static void monitor_cb(uv_fs_event_t *handle, const char *filename, int events, int status) { PWATCH_CONTENT pCtx = (PWATCH_CONTENT)handle->data; char path[1024]; size_t size = 1023; uv_fs_event_getpath(handle, path, &size); path[size] = '\0'; if (pCtx && pCtx->pCb) { pCtx->pCb(path, filename, events, pCtx->watchPath); } #if 1 fprintf(stderr, "Change detected in %s: ", path); if (events & UV_RENAME) { fprintf(stderr, "renamed"); } if (events & UV_CHANGE) { fprintf(stderr, "changed"); } fprintf(stderr, " %s\n", filename ? filename : ""); #endif } int add_watch_path(const char *pFsPath, watch_cb cb) { PWATCH_CONTENT pCtx; if (cb == NULL || pFsPath == NULL || !file_exists(pFsPath)) { LOG_MOD(debug, ZLOG_MOD_WATCH, "Watch path [%s] notify function <%p>\n", pFsPath ? pFsPath : "", cb); return -ERR_INPUT_PARAMS; } HASH_FIND_STR(g_watchContent, pFsPath, pCtx); if (pCtx != NULL) { return -ERR_ITEM_EXISTS; } pCtx = (PWATCH_CONTENT)malloc(sizeof(WATCH_CONTENT)); if (pCtx == NULL) { LOG_MOD(error, ZLOG_MOD_WATCH, "Malloc memory error of %ld size\n", sizeof(WATCH_CONTENT)); return -ERR_MALLOC_MEMORY; } pCtx->uv_event = (uv_fs_event_t *)malloc(sizeof(uv_fs_event_t)); if (pCtx->uv_event == NULL) { LOG_MOD(error, ZLOG_MOD_WATCH, "Malloc memory error of %ld size\n", sizeof(uv_fs_event_t)); free(pCtx); return -ERR_MALLOC_MEMORY; } memset(pCtx, 0, sizeof(WATCH_CONTENT)); strcpy(pCtx->watchPath, pFsPath); pCtx->pCb = cb; pCtx->uv_event->data = pCtx; uv_fs_event_init(get_task_manager(), pCtx->uv_event); uv_fs_event_start(pCtx->uv_event, monitor_cb, pFsPath, UV_FS_EVENT_RECURSIVE); HASH_ADD_STR(g_watchContent, watchPath, pCtx); return ERR_SUCCESS; } int remove_watch_path(const char *pFsPath) { PWATCH_CONTENT pCtx; if (pFsPath == NULL || !file_exists(pFsPath)) { LOG_MOD(debug, ZLOG_MOD_WATCH, "Remove Watch path [%s]\n", pFsPath ? pFsPath : ""); return -ERR_INPUT_PARAMS; } HASH_FIND_STR(g_watchContent, pFsPath, pCtx); if (pCtx != NULL) { HASH_DEL(g_watchContent, pCtx); uv_fs_event_stop(pCtx->uv_event); free(pCtx->uv_event); free(pCtx); } return ERR_SUCCESS; }