mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-14 18:05:27 +07:00
[vfs] updating logging in Linux/WSL fsnotifier
Dropping unwarranted use of varargs; reusing printing code; warnings; formatting GitOrigin-RevId: 9661fafcb44df27adcfe2a7821ea42f7fac37dd7
This commit is contained in:
committed by
intellij-monorepo-bot
parent
2b44bce1b2
commit
d44629ff7d
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -2,12 +2,15 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define VERSION "20210416.1152"
|
#define VERSION "20210416.2304"
|
||||||
|
|
||||||
#define _DEFAULT_SOURCE
|
#define _DEFAULT_SOURCE
|
||||||
|
#define _FILE_OFFSET_BITS 64
|
||||||
|
|
||||||
#include <features.h>
|
#include <features.h>
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
@@ -17,11 +20,11 @@ void message(const char *text);
|
|||||||
enum { LOG_ERR = 0, LOG_WARNING = 1, LOG_INFO = 2 };
|
enum { LOG_ERR = 0, LOG_WARNING = 1, LOG_INFO = 2 };
|
||||||
void userlog(int priority, const char* format, ...);
|
void userlog(int priority, const char* format, ...);
|
||||||
|
|
||||||
#define CHECK_NULL(p, r) if (p == NULL) { userlog(LOG_ERR, "out of memory"); return r; }
|
#define CHECK_NULL(p, r) if ((p) == NULL) { userlog(LOG_ERR, "out of memory"); return r; }
|
||||||
|
|
||||||
|
|
||||||
// variable-length array
|
// variable-length array
|
||||||
typedef struct __array array;
|
typedef struct array_str array;
|
||||||
|
|
||||||
array* array_create(int initial_capacity);
|
array* array_create(int initial_capacity);
|
||||||
int array_size(array* a);
|
int array_size(array* a);
|
||||||
@@ -35,7 +38,7 @@ void array_delete_data(array* a);
|
|||||||
|
|
||||||
|
|
||||||
// poor man's hash table
|
// poor man's hash table
|
||||||
typedef struct __table table;
|
typedef struct table_str table;
|
||||||
|
|
||||||
table* table_create(int capacity);
|
table* table_create(int capacity);
|
||||||
void* table_put(table* t, int key, void* value);
|
void* table_put(table* t, int key, void* value);
|
||||||
@@ -52,7 +55,8 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
bool init_inotify();
|
bool init_inotify();
|
||||||
void set_inotify_callback(void (* callback)(const char*, int));
|
|
||||||
|
void set_inotify_callback(void (*callback)(const char *, uint32_t));
|
||||||
int get_inotify_fd();
|
int get_inotify_fd();
|
||||||
int watch(const char* root, array* mounts);
|
int watch(const char* root, array* mounts);
|
||||||
void unwatch(int id);
|
void unwatch(int id);
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <linux/limits.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -17,11 +16,11 @@
|
|||||||
|
|
||||||
#define DEFAULT_SUBDIR_COUNT 5
|
#define DEFAULT_SUBDIR_COUNT 5
|
||||||
|
|
||||||
typedef struct __watch_node {
|
typedef struct watch_node_str {
|
||||||
int wd;
|
int wd;
|
||||||
struct __watch_node* parent;
|
struct watch_node_str* parent;
|
||||||
array* kids;
|
array* kids;
|
||||||
int path_len;
|
unsigned int path_len;
|
||||||
char path[];
|
char path[];
|
||||||
} watch_node;
|
} watch_node;
|
||||||
|
|
||||||
@@ -29,7 +28,7 @@ static int inotify_fd = -1;
|
|||||||
static int watch_count = 0;
|
static int watch_count = 0;
|
||||||
static table* watches;
|
static table* watches;
|
||||||
static bool limit_reached = false;
|
static bool limit_reached = false;
|
||||||
static void (* callback)(const char*, int) = NULL;
|
static void (* callback)(const char*, uint32_t) = NULL;
|
||||||
|
|
||||||
#define EVENT_SIZE (sizeof(struct inotify_event))
|
#define EVENT_SIZE (sizeof(struct inotify_event))
|
||||||
#define EVENT_BUF_LEN (2048 * (EVENT_SIZE + 16))
|
#define EVENT_BUF_LEN (2048 * (EVENT_SIZE + 16))
|
||||||
@@ -83,14 +82,14 @@ static void read_watch_descriptors_count() {
|
|||||||
userlog(LOG_ERR, "can't read from %s", WATCH_COUNT_NAME);
|
userlog(LOG_ERR, "can't read from %s", WATCH_COUNT_NAME);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
watch_count = atoi(str);
|
watch_count = (int)strtol(str, NULL, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void set_inotify_callback(void (* _callback)(const char*, int)) {
|
void set_inotify_callback(void (* _callback)(const char*, uint32_t)) {
|
||||||
callback = _callback;
|
callback = _callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,9 +99,9 @@ int get_inotify_fd() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define EVENT_MASK IN_MODIFY | IN_ATTRIB | IN_CREATE | IN_DELETE | IN_MOVE | IN_DELETE_SELF | IN_MOVE_SELF
|
#define EVENT_MASK (IN_MODIFY | IN_ATTRIB | IN_CREATE | IN_DELETE | IN_MOVE | IN_DELETE_SELF | IN_MOVE_SELF)
|
||||||
|
|
||||||
static int add_watch(int path_len, watch_node* parent) {
|
static int add_watch(unsigned int path_len, watch_node* parent) {
|
||||||
int wd = inotify_add_watch(inotify_fd, path_buf, EVENT_MASK);
|
int wd = inotify_add_watch(inotify_fd, path_buf, EVENT_MASK);
|
||||||
if (wd < 0) {
|
if (wd < 0) {
|
||||||
if (errno == EACCES || errno == ENOENT) {
|
if (errno == EACCES || errno == ENOENT) {
|
||||||
@@ -147,7 +146,7 @@ static int add_watch(int path_len, watch_node* parent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
node = malloc(sizeof(watch_node) + path_len + 1);
|
node = malloc(sizeof(watch_node) + path_len + 1);
|
||||||
CHECK_NULL(node, ERR_ABORT);
|
CHECK_NULL(node, ERR_ABORT)
|
||||||
memcpy(node->path, path_buf, path_len + 1);
|
memcpy(node->path, path_buf, path_len + 1);
|
||||||
node->path_len = path_len;
|
node->path_len = path_len;
|
||||||
node->wd = wd;
|
node->wd = wd;
|
||||||
@@ -157,9 +156,9 @@ static int add_watch(int path_len, watch_node* parent) {
|
|||||||
if (parent != NULL) {
|
if (parent != NULL) {
|
||||||
if (parent->kids == NULL) {
|
if (parent->kids == NULL) {
|
||||||
parent->kids = array_create(DEFAULT_SUBDIR_COUNT);
|
parent->kids = array_create(DEFAULT_SUBDIR_COUNT);
|
||||||
CHECK_NULL(parent->kids, ERR_ABORT);
|
CHECK_NULL(parent->kids, ERR_ABORT)
|
||||||
}
|
}
|
||||||
CHECK_NULL(array_push(parent->kids, node), ERR_ABORT);
|
CHECK_NULL(array_push(parent->kids, node), ERR_ABORT)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table_put(watches, wd, node) == NULL) {
|
if (table_put(watches, wd, node) == NULL) {
|
||||||
@@ -189,7 +188,7 @@ static void rm_watch(int wd, bool update_parent) {
|
|||||||
userlog(LOG_INFO, "inotify_rm_watch(%d:%s): %s", node->wd, node->path, strerror(errno));
|
userlog(LOG_INFO, "inotify_rm_watch(%d:%s): %s", node->wd, node->path, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<array_size(node->kids); i++) {
|
for (int i = 0; i < array_size(node->kids); i++) {
|
||||||
watch_node* kid = array_get(node->kids, i);
|
watch_node* kid = array_get(node->kids, i);
|
||||||
if (kid != NULL) {
|
if (kid != NULL) {
|
||||||
rm_watch(kid->wd, false);
|
rm_watch(kid->wd, false);
|
||||||
@@ -197,7 +196,7 @@ static void rm_watch(int wd, bool update_parent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (update_parent && node->parent != NULL) {
|
if (update_parent && node->parent != NULL) {
|
||||||
for (int i=0; i<array_size(node->parent->kids); i++) {
|
for (int i = 0; i < array_size(node->parent->kids); i++) {
|
||||||
if (array_get(node->parent->kids, i) == node) {
|
if (array_get(node->parent->kids, i) == node) {
|
||||||
array_put(node->parent->kids, i, NULL);
|
array_put(node->parent->kids, i, NULL);
|
||||||
break;
|
break;
|
||||||
@@ -211,8 +210,8 @@ static void rm_watch(int wd, bool update_parent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int walk_tree(int path_len, watch_node* parent, bool recursive, array* mounts) {
|
static int walk_tree(unsigned int path_len, watch_node* parent, bool recursive, array* mounts) {
|
||||||
for (int j=0; j<array_size(mounts); j++) {
|
for (int j = 0; j < array_size(mounts); j++) {
|
||||||
char* mount = array_get(mounts, j);
|
char* mount = array_get(mounts, j);
|
||||||
if (strncmp(path_buf, mount, strlen(mount)) == 0) {
|
if (strncmp(path_buf, mount, strlen(mount)) == 0) {
|
||||||
userlog(LOG_INFO, "watch path '%s' crossed mount point '%s' - skipping", path_buf, mount);
|
userlog(LOG_INFO, "watch path '%s' crossed mount point '%s' - skipping", path_buf, mount);
|
||||||
@@ -255,7 +254,7 @@ static int walk_tree(int path_len, watch_node* parent, bool recursive, array* mo
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int name_len = strlen(entry->d_name);
|
unsigned int name_len = strlen(entry->d_name);
|
||||||
memcpy(path_buf + path_len + 1, entry->d_name, name_len + 1);
|
memcpy(path_buf + path_len + 1, entry->d_name, name_len + 1);
|
||||||
|
|
||||||
if (entry->d_type == DT_UNKNOWN) {
|
if (entry->d_type == DT_UNKNOWN) {
|
||||||
@@ -289,7 +288,7 @@ int watch(const char* root, array* mounts) {
|
|||||||
recursive = false;
|
recursive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int path_len = strlen(root);
|
size_t path_len = strlen(root);
|
||||||
if (root[path_len - 1] == '/') {
|
if (root[path_len - 1] == '/') {
|
||||||
--path_len;
|
--path_len;
|
||||||
}
|
}
|
||||||
@@ -337,11 +336,11 @@ static bool process_inotify_event(struct inotify_event* event) {
|
|||||||
bool is_dir = (event->mask & IN_ISDIR) == IN_ISDIR;
|
bool is_dir = (event->mask & IN_ISDIR) == IN_ISDIR;
|
||||||
userlog(LOG_INFO, "inotify: wd=%d mask=%d dir=%d name=%s", event->wd, event->mask & (~IN_ISDIR), is_dir, node->path);
|
userlog(LOG_INFO, "inotify: wd=%d mask=%d dir=%d name=%s", event->wd, event->mask & (~IN_ISDIR), is_dir, node->path);
|
||||||
|
|
||||||
int path_len = node->path_len;
|
unsigned int path_len = node->path_len;
|
||||||
memcpy(path_buf, node->path, path_len + 1);
|
memcpy(path_buf, node->path, path_len + 1);
|
||||||
if (event->len > 0) {
|
if (event->len > 0) {
|
||||||
path_buf[path_len] = '/';
|
path_buf[path_len] = '/';
|
||||||
int name_len = strlen(event->name);
|
unsigned int name_len = strlen(event->name);
|
||||||
memcpy(path_buf + path_len + 1, event->name, name_len + 1);
|
memcpy(path_buf + path_len + 1, event->name, name_len + 1);
|
||||||
path_len += name_len + 1;
|
path_len += name_len + 1;
|
||||||
}
|
}
|
||||||
@@ -358,7 +357,7 @@ static bool process_inotify_event(struct inotify_event* event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_dir && event->mask & (IN_DELETE | IN_MOVED_FROM)) {
|
if (is_dir && event->mask & (IN_DELETE | IN_MOVED_FROM)) {
|
||||||
for (int i=0; i<array_size(node->kids); i++) {
|
for (int i = 0; i < array_size(node->kids); i++) {
|
||||||
watch_node* kid = array_get(node->kids, i);
|
watch_node* kid = array_get(node->kids, i);
|
||||||
if (kid != NULL && strncmp(path_buf, kid->path, kid->path_len) == 0) {
|
if (kid != NULL && strncmp(path_buf, kid->path, kid->path_len) == 0) {
|
||||||
rm_watch(kid->wd, false);
|
rm_watch(kid->wd, false);
|
||||||
@@ -379,10 +378,10 @@ bool process_inotify_input() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = 0;
|
ssize_t i = 0;
|
||||||
while (i < len) {
|
while (i < len) {
|
||||||
struct inotify_event* event = (struct inotify_event*) &event_buf[i];
|
struct inotify_event *event = (struct inotify_event *) &event_buf[i];
|
||||||
i += EVENT_SIZE + event->len;
|
i += (int)EVENT_SIZE + event->len;
|
||||||
|
|
||||||
if (event->mask & IN_IGNORED) {
|
if (event->mask & IN_IGNORED) {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/inotify.h>
|
#include <sys/inotify.h>
|
||||||
#include <sys/select.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@@ -42,9 +41,9 @@ static bool update_roots(array* new_roots);
|
|||||||
static void unregister_roots();
|
static void unregister_roots();
|
||||||
static bool register_roots(array* new_roots, array* unwatchable, array* mounts);
|
static bool register_roots(array* new_roots, array* unwatchable, array* mounts);
|
||||||
static array* unwatchable_mounts();
|
static array* unwatchable_mounts();
|
||||||
static void inotify_callback(const char* path, int event);
|
static void inotify_callback(const char* path, uint32_t event);
|
||||||
static void report_event(const char* event, const char* path);
|
static void report_event(const char* event, const char* path);
|
||||||
static void output(const char* format, ...);
|
static void output(const char* line, bool flush);
|
||||||
static void check_missing_roots();
|
static void check_missing_roots();
|
||||||
static void check_root_removal(const char*);
|
static void check_root_removal(const char*);
|
||||||
|
|
||||||
@@ -78,19 +77,17 @@ int main(int argc, char** argv) {
|
|||||||
if (roots != NULL && init_inotify()) {
|
if (roots != NULL && init_inotify()) {
|
||||||
set_inotify_callback(&inotify_callback);
|
set_inotify_callback(&inotify_callback);
|
||||||
|
|
||||||
if (!self_test) {
|
if (self_test) {
|
||||||
if (!main_loop()) {
|
|
||||||
rv = 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
run_self_test();
|
run_self_test();
|
||||||
}
|
}
|
||||||
|
else if (!main_loop()) {
|
||||||
|
rv = 3;
|
||||||
|
}
|
||||||
|
|
||||||
unregister_roots();
|
unregister_roots();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
output("GIVEUP\n");
|
output("GIVEUP", true);
|
||||||
rv = 2;
|
rv = 2;
|
||||||
}
|
}
|
||||||
close_inotify();
|
close_inotify();
|
||||||
@@ -102,7 +99,8 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
|
|
||||||
void message(const char *text) {
|
void message(const char *text) {
|
||||||
output("MESSAGE\n%s\n", text);
|
output("MESSAGE", false);
|
||||||
|
output(text, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -172,14 +170,12 @@ static bool main_loop() {
|
|||||||
|
|
||||||
static int read_input() {
|
static int read_input() {
|
||||||
char* line = read_line(stdin);
|
char* line = read_line(stdin);
|
||||||
|
|
||||||
if (line == NULL || strcmp(line, "EXIT") == 0) {
|
if (line == NULL || strcmp(line, "EXIT") == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else if (strcmp(line, "ROOTS") == 0) {
|
||||||
if (strcmp(line, "ROOTS") == 0) {
|
|
||||||
array* new_roots = array_create(20);
|
array* new_roots = array_create(20);
|
||||||
CHECK_NULL(new_roots, ERR_ABORT);
|
CHECK_NULL(new_roots, ERR_ABORT)
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
line = read_line(stdin);
|
line = read_line(stdin);
|
||||||
@@ -190,17 +186,18 @@ static int read_input() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int l = strlen(line);
|
size_t l = strlen(line);
|
||||||
if (l > 1 && line[l-1] == '/') line[l-1] = '\0';
|
if (l > 1 && line[l-1] == '/') line[l-1] = '\0';
|
||||||
CHECK_NULL(array_push(new_roots, strdup(line)), ERR_ABORT);
|
CHECK_NULL(array_push(new_roots, strdup(line)), ERR_ABORT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return update_roots(new_roots) ? ERR_CONTINUE : ERR_ABORT;
|
return update_roots(new_roots) ? ERR_CONTINUE : ERR_ABORT;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
userlog(LOG_WARNING, "unrecognised command: %s", line);
|
userlog(LOG_WARNING, "unrecognised command: '%s'", line);
|
||||||
return ERR_CONTINUE;
|
return ERR_CONTINUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -209,14 +206,8 @@ static bool update_roots(array* new_roots) {
|
|||||||
|
|
||||||
unregister_roots();
|
unregister_roots();
|
||||||
|
|
||||||
if (array_size(new_roots) == 0) {
|
if (array_size(new_roots) == 0 || (array_size(new_roots) == 1 && strcmp(array_get(new_roots, 0), "/") == 0)) {
|
||||||
output("UNWATCHEABLE\n#\n");
|
output("UNWATCHEABLE\n#", true);
|
||||||
array_delete(new_roots);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (array_size(new_roots) == 1 && strcmp(array_get(new_roots, 0), "/") == 0) { // refuse to watch the entire tree
|
|
||||||
output("UNWATCHEABLE\n/\n#\n");
|
|
||||||
userlog(LOG_INFO, "unwatchable: /");
|
|
||||||
array_delete_vs_data(new_roots);
|
array_delete_vs_data(new_roots);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -231,13 +222,11 @@ static bool update_roots(array* new_roots) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
output("UNWATCHEABLE\n");
|
output("UNWATCHEABLE", false);
|
||||||
for (int i=0; i<array_size(unwatchable); i++) {
|
for (int i = 0; i < array_size(unwatchable); i++) {
|
||||||
char* s = array_get(unwatchable, i);
|
output(array_get(unwatchable, i), false);
|
||||||
output("%s\n", s);
|
|
||||||
userlog(LOG_INFO, "unwatchable: %s", s);
|
|
||||||
}
|
}
|
||||||
output("#\n");
|
output("#", true);
|
||||||
|
|
||||||
array_delete_vs_data(unwatchable);
|
array_delete_vs_data(unwatchable);
|
||||||
array_delete_vs_data(mounts);
|
array_delete_vs_data(mounts);
|
||||||
@@ -254,12 +243,12 @@ static void unregister_roots() {
|
|||||||
unwatch(root->id);
|
unwatch(root->id);
|
||||||
free(root->path);
|
free(root->path);
|
||||||
free(root);
|
free(root);
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool register_roots(array* new_roots, array* unwatchable, array* mounts) {
|
static bool register_roots(array* new_roots, array* unwatchable, array* mounts) {
|
||||||
for (int i=0; i<array_size(new_roots); i++) {
|
for (int i = 0; i < array_size(new_roots); i++) {
|
||||||
char* new_root = array_get(new_roots, i);
|
char* new_root = array_get(new_roots, i);
|
||||||
char* unflattened = UNFLATTEN(new_root);
|
char* unflattened = UNFLATTEN(new_root);
|
||||||
userlog(LOG_INFO, "registering root: %s", new_root);
|
userlog(LOG_INFO, "registering root: %s", new_root);
|
||||||
@@ -270,22 +259,22 @@ static bool register_roots(array* new_roots, array* unwatchable, array* mounts)
|
|||||||
}
|
}
|
||||||
|
|
||||||
array* inner_mounts = array_create(5);
|
array* inner_mounts = array_create(5);
|
||||||
CHECK_NULL(inner_mounts, false);
|
CHECK_NULL(inner_mounts, false)
|
||||||
|
|
||||||
bool skip = false;
|
bool skip = false;
|
||||||
for (int j=0; j<array_size(mounts); j++) {
|
for (int j = 0; j < array_size(mounts); j++) {
|
||||||
char* mount = array_get(mounts, j);
|
char* mount = array_get(mounts, j);
|
||||||
if (is_parent_path(mount, unflattened)) {
|
if (is_parent_path(mount, unflattened)) {
|
||||||
userlog(LOG_INFO, "watch root '%s' is under mount point '%s' - skipping", unflattened, mount);
|
userlog(LOG_INFO, "watch root '%s' is under mount point '%s' - skipping", unflattened, mount);
|
||||||
CHECK_NULL(array_push(unwatchable, strdup(unflattened)), false);
|
CHECK_NULL(array_push(unwatchable, strdup(unflattened)), false)
|
||||||
skip = true;
|
skip = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (is_parent_path(unflattened, mount)) {
|
else if (is_parent_path(unflattened, mount)) {
|
||||||
userlog(LOG_INFO, "watch root '%s' contains mount point '%s' - partial watch", unflattened, mount);
|
userlog(LOG_INFO, "watch root '%s' contains mount point '%s' - partial watch", unflattened, mount);
|
||||||
char* copy = strdup(mount);
|
char* copy = strdup(mount);
|
||||||
CHECK_NULL(array_push(unwatchable, copy), false);
|
CHECK_NULL(array_push(unwatchable, copy), false)
|
||||||
CHECK_NULL(array_push(inner_mounts, copy), false);
|
CHECK_NULL(array_push(inner_mounts, copy), false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (skip) {
|
if (skip) {
|
||||||
@@ -297,18 +286,18 @@ static bool register_roots(array* new_roots, array* unwatchable, array* mounts)
|
|||||||
|
|
||||||
if (id >= 0 || id == ERR_MISSING) {
|
if (id >= 0 || id == ERR_MISSING) {
|
||||||
watch_root* root = malloc(sizeof(watch_root));
|
watch_root* root = malloc(sizeof(watch_root));
|
||||||
CHECK_NULL(root, false);
|
CHECK_NULL(root, false)
|
||||||
root->id = id;
|
root->id = id;
|
||||||
root->path = strdup(new_root);
|
root->path = strdup(new_root);
|
||||||
CHECK_NULL(root->path, false);
|
CHECK_NULL(root->path, false)
|
||||||
CHECK_NULL(array_push(roots, root), false);
|
CHECK_NULL(array_push(roots, root), false)
|
||||||
}
|
}
|
||||||
else if (id == ERR_ABORT) {
|
else if (id == ERR_ABORT) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (id != ERR_IGNORE) {
|
else if (id != ERR_IGNORE) {
|
||||||
userlog(LOG_WARNING, "watch root '%s' cannot be watched: %d", unflattened, id);
|
userlog(LOG_WARNING, "watch root '%s' cannot be watched: %d", unflattened, id);
|
||||||
CHECK_NULL(array_push(unwatchable, strdup(unflattened)), false);
|
CHECK_NULL(array_push(unwatchable, strdup(unflattened)), false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -320,7 +309,7 @@ static bool is_watchable(const char* fs) {
|
|||||||
// don't watch special and network filesystems
|
// don't watch special and network filesystems
|
||||||
return !(strncmp(fs, "dev", 3) == 0 || strcmp(fs, "proc") == 0 || strcmp(fs, "sysfs") == 0 || strcmp(fs, MNTTYPE_SWAP) == 0 ||
|
return !(strncmp(fs, "dev", 3) == 0 || strcmp(fs, "proc") == 0 || strcmp(fs, "sysfs") == 0 || strcmp(fs, MNTTYPE_SWAP) == 0 ||
|
||||||
(strncmp(fs, "fuse", 4) == 0 && strcmp(fs + 4, "blk") != 0 && strcmp(fs + 4, ".osxfs") != 0) ||
|
(strncmp(fs, "fuse", 4) == 0 && strcmp(fs + 4, "blk") != 0 && strcmp(fs + 4, ".osxfs") != 0) ||
|
||||||
strcmp(fs, "cifs") == 0 || strcmp(fs, MNTTYPE_NFS) == 0);
|
strcmp(fs, "cifs") == 0 || strcmp(fs, MNTTYPE_NFS) == 0|| strcmp(fs, "9p") == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static array* unwatchable_mounts() {
|
static array* unwatchable_mounts() {
|
||||||
@@ -334,13 +323,13 @@ static array* unwatchable_mounts() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
array* mounts = array_create(20);
|
array* mounts = array_create(20);
|
||||||
CHECK_NULL(mounts, NULL);
|
CHECK_NULL(mounts, NULL)
|
||||||
|
|
||||||
struct mntent* ent;
|
struct mntent* ent;
|
||||||
while ((ent = getmntent(mtab)) != NULL) {
|
while ((ent = getmntent(mtab)) != NULL) {
|
||||||
userlog(LOG_INFO, "mtab: %s : %s", ent->mnt_dir, ent->mnt_type);
|
userlog(LOG_INFO, "mtab: %s : %s", ent->mnt_dir, ent->mnt_type);
|
||||||
if (strcmp(ent->mnt_type, MNTTYPE_IGNORE) != 0 && !is_watchable(ent->mnt_type)) {
|
if (strcmp(ent->mnt_type, MNTTYPE_IGNORE) != 0 && !is_watchable(ent->mnt_type)) {
|
||||||
CHECK_NULL(array_push(mounts, strdup(ent->mnt_dir)), NULL);
|
CHECK_NULL(array_push(mounts, strdup(ent->mnt_dir)), NULL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,7 +338,7 @@ static array* unwatchable_mounts() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void inotify_callback(const char* path, int event) {
|
static void inotify_callback(const char* path, uint32_t event) {
|
||||||
if (event & (IN_CREATE | IN_MOVED_TO)) {
|
if (event & (IN_CREATE | IN_MOVED_TO)) {
|
||||||
report_event("CREATE", path);
|
report_event("CREATE", path);
|
||||||
report_event("CHANGE", path);
|
report_event("CHANGE", path);
|
||||||
@@ -367,7 +356,7 @@ static void inotify_callback(const char* path, int event) {
|
|||||||
check_root_removal(path);
|
check_root_removal(path);
|
||||||
}
|
}
|
||||||
else if (event & IN_UNMOUNT) {
|
else if (event & IN_UNMOUNT) {
|
||||||
output("RESET\n");
|
output("RESET", true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,36 +375,27 @@ static void report_event(const char* event, const char* path) {
|
|||||||
}
|
}
|
||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
|
|
||||||
fputs(event, stdout);
|
output(event, false);
|
||||||
fputc('\n', stdout);
|
output(copy, true);
|
||||||
fwrite(copy, (p - copy), 1, stdout);
|
|
||||||
fputc('\n', stdout);
|
|
||||||
|
|
||||||
if (copy != path) {
|
if (copy != path) {
|
||||||
free(copy);
|
free(copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
fflush(stdout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void output(const char* format, ...) {
|
static void output(const char* line, bool flush) {
|
||||||
if (self_test) {
|
fputs(line, stdout);
|
||||||
return;
|
fputc('\n', stdout);
|
||||||
|
if (flush) {
|
||||||
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, format);
|
|
||||||
vprintf(format, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
fflush(stdout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void check_missing_roots() {
|
static void check_missing_roots() {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
for (int i=0; i<array_size(roots); i++) {
|
for (int i = 0; i < array_size(roots); i++) {
|
||||||
watch_root* root = array_get(roots, i);
|
watch_root* root = array_get(roots, i);
|
||||||
if (root->id < 0) {
|
if (root->id < 0) {
|
||||||
char* unflattened = UNFLATTEN(root->path);
|
char* unflattened = UNFLATTEN(root->path);
|
||||||
@@ -430,7 +410,7 @@ static void check_missing_roots() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void check_root_removal(const char* path) {
|
static void check_root_removal(const char* path) {
|
||||||
for (int i=0; i<array_size(roots); i++) {
|
for (int i = 0; i < array_size(roots); i++) {
|
||||||
watch_root* root = array_get(roots, i);
|
watch_root* root = array_get(roots, i);
|
||||||
if (root->id >= 0 && strcmp(path, UNFLATTEN(root->path)) == 0) {
|
if (root->id >= 0 && strcmp(path, UNFLATTEN(root->path)) == 0) {
|
||||||
unwatch(root->id);
|
unwatch(root->id);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
#define REALLOC_FACTOR 2
|
#define REALLOC_FACTOR 2
|
||||||
|
|
||||||
struct __array {
|
struct array_str {
|
||||||
void** data;
|
void** data;
|
||||||
int size;
|
int size;
|
||||||
int capacity;
|
int capacity;
|
||||||
@@ -101,7 +101,7 @@ void array_delete_vs_data(array* a) {
|
|||||||
|
|
||||||
void array_delete_data(array* a) {
|
void array_delete_data(array* a) {
|
||||||
if (a != NULL) {
|
if (a != NULL) {
|
||||||
for (int i=0; i<a->size; i++) {
|
for (int i = 0; i < a->size; i++) {
|
||||||
if (a->data[i] != NULL) {
|
if (a->data[i] != NULL) {
|
||||||
free(a->data[i]);
|
free(a->data[i]);
|
||||||
}
|
}
|
||||||
@@ -111,7 +111,7 @@ void array_delete_data(array* a) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct __table {
|
struct table_str {
|
||||||
void** data;
|
void** data;
|
||||||
int capacity;
|
int capacity;
|
||||||
};
|
};
|
||||||
@@ -170,11 +170,11 @@ void table_delete(table* t) {
|
|||||||
static char input_buf[INPUT_BUF_LEN];
|
static char input_buf[INPUT_BUF_LEN];
|
||||||
|
|
||||||
char* read_line(FILE* stream) {
|
char* read_line(FILE* stream) {
|
||||||
char* retval = fgets(input_buf, INPUT_BUF_LEN, stream);
|
char* result = fgets(input_buf, INPUT_BUF_LEN, stream);
|
||||||
if (retval == NULL || feof(stream)) {
|
if (result == NULL || feof(stream)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
int pos = strlen(input_buf) - 1;
|
size_t pos = strlen(input_buf) - 1;
|
||||||
if (input_buf[pos] == '\n') {
|
if (input_buf[pos] == '\n') {
|
||||||
input_buf[pos] = '\0';
|
input_buf[pos] = '\0';
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user