fsnotifier: reported path corruption fixed
authorRoman Shevchenko <roman.shevchenko@jetbrains.com>
Mon, 15 Jul 2013 12:27:27 +0000 (14:27 +0200)
committerRoman Shevchenko <roman.shevchenko@jetbrains.com>
Mon, 15 Jul 2013 13:48:22 +0000 (15:48 +0200)
bin/linux/fsnotifier
bin/linux/fsnotifier64
native/fsNotifier/linux/fsnotifier.h
native/fsNotifier/linux/inotify.c
native/fsNotifier/linux/main.c

index 37430c7dc6754bac9969c0af98ce032784394756..f79a688a18bdd7e22dfad319c782bb470892fba3 100755 (executable)
Binary files a/bin/linux/fsnotifier and b/bin/linux/fsnotifier differ
index 1bd81797640c477f59bcaf23331d309c80e0fa8b..a967353d6294910d64d28b216eca6baa91a4f129 100755 (executable)
Binary files a/bin/linux/fsnotifier64 and b/bin/linux/fsnotifier64 differ
index 0bcfaa5f9644a2d1c3868a30cdc89f37cfc387fd..087246e9864486ed12e8949f011b20affe318321 100644 (file)
@@ -67,7 +67,7 @@ enum {
 };
 
 bool init_inotify();
-void set_inotify_callback(void (* callback)(char*, int));
+void set_inotify_callback(void (* callback)(const char*, int));
 int get_inotify_fd();
 int watch(const char* root, array* mounts);
 void unwatch(int id);
index 77536dc3dcba4970d4fea9d1c6bd230eb7aa55f6..713d09c54a38ae8c1686aa54e3fa7440eeeb2bdd 100644 (file)
@@ -50,7 +50,7 @@ static int inotify_fd = -1;
 static int watch_count = 0;
 static table* watches;
 static bool limit_reached = false;
-static void (* callback)(char*, int) = NULL;
+static void (* callback)(const char*, int) = NULL;
 
 #define EVENT_SIZE (sizeof(struct inotify_event))
 #define EVENT_BUF_LEN (2048 * (EVENT_SIZE + 16))
@@ -112,7 +112,7 @@ static void read_watch_descriptors_count() {
 }
 
 
-inline void set_inotify_callback(void (* _callback)(char*, int)) {
+inline void set_inotify_callback(void (* _callback)(const char*, int)) {
   callback = _callback;
 }
 
@@ -346,15 +346,19 @@ static bool process_inotify_event(struct inotify_event* event) {
   bool is_dir = (event->mask & IN_ISDIR) == IN_ISDIR;
   userlog(LOG_DEBUG, "inotify: wd=%d mask=%d dir=%d name=%s", event->wd, event->mask & (~IN_ISDIR), is_dir, node->path);
 
-  memcpy(path_buf, node->path, node->path_len + 1);
   int path_len = node->path_len;
+  memcpy(path_buf, node->path, path_len + 1);
   if (event->len > 0) {
-    path_buf[node->path_len] = '/';
+    path_buf[path_len] = '/';
     int name_len = strlen(event->name);
     memcpy(path_buf + path_len + 1, event->name, name_len + 1);
     path_len += name_len + 1;
   }
 
+  if (callback != NULL) {
+    (*callback)(path_buf, event->mask);
+  }
+
   if (is_dir && event->mask & (IN_CREATE | IN_MOVED_TO)) {
     int result = walk_tree(path_len, node, true, NULL);
     if (result < 0 && result != ERR_IGNORE && result != ERR_CONTINUE) {
@@ -373,10 +377,6 @@ static bool process_inotify_event(struct inotify_event* event) {
     }
   }
 
-  if (callback != NULL) {
-    (*callback)(path_buf, event->mask);
-  }
-
   return true;
 }
 
index 3cd65e28fc549b38cea2b7c0342b3a82fc6d946c..95a22b41568361e84b29e1ab4aabb7f1052ab619 100644 (file)
@@ -36,7 +36,7 @@
 #define LOG_ENV_ERROR "error"
 #define LOG_ENV_OFF "off"
 
-#define VERSION "20130617.1935"
+#define VERSION "20130715.1353"
 #define VERSION_MSG "fsnotifier " VERSION "\n"
 
 #define USAGE_MSG \
@@ -79,11 +79,11 @@ static bool update_roots(array* new_roots);
 static void unregister_roots();
 static bool register_roots(array* new_roots, array* unwatchable, array* mounts);
 static array* unwatchable_mounts();
-static void inotify_callback(char* path, int event);
-static void report_event(char* event, char* path);
+static void inotify_callback(const char* path, int event);
+static void report_event(const char* event, const char* path);
 static void output(const char* format, ...);
 static void check_missing_roots();
-static void check_root_removal(char*);
+static void check_root_removal(const char*);
 
 
 int main(int argc, char** argv) {
@@ -434,7 +434,7 @@ static array* unwatchable_mounts() {
 }
 
 
-static void inotify_callback(char* path, int event) {
+static void inotify_callback(const char* path, int event) {
   if (event & (IN_CREATE | IN_MOVED_TO)) {
     report_event("CREATE", path);
     report_event("CHANGE", path);
@@ -457,21 +457,32 @@ static void inotify_callback(char* path, int event) {
   }
 }
 
-static void report_event(char* event, char* path) {
+static void report_event(const char* event, const char* path) {
   userlog(LOG_DEBUG, "%s: %s", event, path);
 
-  int len = strlen(path);
-  for (char* p = path; *p != '\0'; p++) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
+  char* copy = path, *p;
+  for (p = copy; *p != '\0'; ++p) {
     if (*p == '\n') {
+      if (copy == path) {
+        copy = strdup(path);
+        p = copy + (p - path);
+      }
       *p = '\0';
     }
   }
+#pragma clang diagnostic pop
 
   fputs(event, stdout);
   fputc('\n', stdout);
-  fwrite(path, len, 1, stdout);
+  fwrite(copy, (p - copy), 1, stdout);
   fputc('\n', stdout);
 
+  if (copy != path) {
+    free(copy);
+  }
+
   fflush(stdout);
 }
 
@@ -506,7 +517,7 @@ static void check_missing_roots() {
   }
 }
 
-static void check_root_removal(char* path) {
+static void check_root_removal(const char* path) {
   for (int i=0; i<array_size(roots); i++) {
     watch_root* root = array_get(roots, i);
     if (root->id >= 0 && strcmp(path, UNFLATTEN(root->path)) == 0) {