EA-42778 (escape line breaks in file names)
authorRoman Shevchenko <roman.shevchenko@jetbrains.com>
Thu, 17 Jan 2013 20:56:46 +0000 (21:56 +0100)
committerRoman Shevchenko <roman.shevchenko@jetbrains.com>
Thu, 17 Jan 2013 20:57:21 +0000 (21:57 +0100)
bin/linux/fsnotifier
bin/linux/fsnotifier64
bin/mac/fsnotifier
native/fsNotifier/linux/main.c
native/fsNotifier/mac/fsnotifier.c
platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java
platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/FileWatcherTest.java

index 3918875ad48e361c23c3e457f1cb493c78b74de1..436cfc3d68b8d811eaed2ebc1097b4b678513c20 100755 (executable)
Binary files a/bin/linux/fsnotifier and b/bin/linux/fsnotifier differ
index 3ec94a535f0a98e329761bfd1b8d0f7154b363dc..d7c47273bd3d50e078c7f55ef65947721016a32e 100755 (executable)
Binary files a/bin/linux/fsnotifier64 and b/bin/linux/fsnotifier64 differ
index fbace740489b0127aecd10c677b1d6834ba95492..4fff2f1d13209a5b7c143b03fce7644d4bc996cd 100755 (executable)
Binary files a/bin/mac/fsnotifier and b/bin/mac/fsnotifier differ
index 606e914dbc2ee0e18a08d65afe1438c5f8aac676..25c04350d1bdad598ab329d4b5616b8305d3f7c7 100644 (file)
@@ -71,6 +71,7 @@ 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 output(const char* format, ...);
 
 
@@ -398,26 +399,23 @@ static array* unwatchable_mounts() {
 
 static void inotify_callback(char* path, int event) {
   if (event & IN_CREATE || event & IN_MOVED_TO) {
-    output("CREATE\n%s\nCHANGE\n%s\n", path, path);
-    userlog(LOG_DEBUG, "CREATE: %s", path);
+    report_event("CREATE", path);
+    report_event("CHANGE", path);
     return;
   }
 
   if (event & IN_MODIFY) {
-    output("CHANGE\n%s\n", path);
-    userlog(LOG_DEBUG, "CHANGE: %s", path);
+    report_event("CHANGE", path);
     return;
   }
 
   if (event & IN_ATTRIB) {
-    output("STATS\n%s\n", path);
-    userlog(LOG_DEBUG, "STATS: %s", path);
+    report_event("STATS", path);
     return;
   }
 
   if (event & IN_DELETE || event & IN_MOVED_FROM) {
-    output("DELETE\n%s\n", path);
-    userlog(LOG_DEBUG, "DELETE: %s", path);
+    report_event("DELETE", path);
     return;
   }
 
@@ -428,6 +426,22 @@ static void inotify_callback(char* path, int event) {
   }
 }
 
+static void report_event(char* event, char* path) {
+  userlog(LOG_DEBUG, "%s: %s", event, path);
+
+  int len = strlen(path);
+  for (char* p = path; *p != '\0'; p++){
+    if (*p == '\n') {
+      *p = '\0';
+    }
+  }
+
+  fputs(event, stdout);
+  fputc('\n', stdout);
+  fwrite(path, len, 1, stdout);
+  fputc('\n', stdout);
+}
+
 
 static void output(const char* format, ...) {
   if (self_test) {
index df4a14348185cf706a716cf344007e65710509c5..f7b044074eaaab754e07b9e5ace079ef6dbdc920 100644 (file)
 
 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
 
+static void reportEvent(char *event, char *path) {
+    int len = 0;
+    if (path != NULL) {
+        len = strlen(path);
+        for (char* p = path; *p != '\0'; p++){
+            if (*p == '\n') {
+                *p = '\0';
+            }
+        }
+    }
+
+    pthread_mutex_lock(&lock);
+
+    fputs(event, stdout);
+    fputc('\n', stdout);
+    if (path != NULL) {
+        fwrite(path, len, 1, stdout);
+        fputc('\n', stdout);
+    }
+
+    fflush(stdout);
+    pthread_mutex_unlock(&lock);
+}
+
 static void callback(ConstFSEventStreamRef streamRef,
                      void *clientCallBackInfo,
                      size_t numEvents,
@@ -32,22 +56,13 @@ static void callback(ConstFSEventStreamRef streamRef,
         // TODO[max] Lion has much more detailed flags we need accurately process. For now just reduce to SL events range.
         FSEventStreamEventFlags flags = eventFlags[i] & 0xFF;
         if ((flags & kFSEventStreamEventFlagMustScanSubDirs) != 0) {
-            pthread_mutex_lock(&lock);
-            printf("RECDIRTY\n%s\n", paths[i]);
-            fflush(stdout);
-            pthread_mutex_unlock(&lock);
+            reportEvent("RECDIRTY", paths[i]);
         }
         else if (flags != kFSEventStreamEventFlagNone) {
-            pthread_mutex_lock(&lock);
-            printf("RESET\n");
-            fflush(stdout);
-            pthread_mutex_unlock(&lock);
+            reportEvent("RESET", NULL);
         }
         else {
-            pthread_mutex_lock(&lock);
-            printf("DIRTY\n%s\n", paths[i]);
-            fflush(stdout);
-            pthread_mutex_unlock(&lock);
+            reportEvent("DIRTY", paths[i]);
         }
     }
 }
index 5e068ae74aa5b6bc626f0bf87d48ef9e2a63afa1..e3fbdff786fe8c6afdf5ad81e2748801594a2700 100644 (file)
@@ -463,7 +463,7 @@ public class FileWatcher {
         }
       }
       else {
-        processChange(line, myLastOp);
+        processChange(line.replace('\0', '\n'), myLastOp);
         myLastOp = null;
       }
     }
index ee03f738bdee1bc39ec5a2dbb398038923d21ef4..4b916b08396690399dfa661d3fc349c5f2281ad7 100644 (file)
@@ -550,6 +550,45 @@ public class FileWatcherTest extends PlatformLangTestCase {
     myTimeout = NATIVE_PROCESS_DELAY;
   }
 
+  /*public void testUnicodePaths() throws Exception {
+    File topDir = IoTestUtil.createTestDir("topDir");
+    File testDir = IoTestUtil.createTestDir(topDir, "unicode директория");
+    File testFile = IoTestUtil.createTestFile(testDir, "unicode файл");
+    refresh(topDir);
+
+    LocalFileSystem.WatchRequest request = watch(topDir);
+    try {
+      myAccept = true;
+      FileUtil.writeToFile(testFile, "abc");
+      assertEvent(VFileContentChangeEvent.class, testFile.getPath());
+    }
+    finally {
+      unwatch(request);
+    }
+  }*/
+
+  public void testLineBreaksInName() throws Exception {
+    if (!SystemInfo.isUnix) {
+      System.err.println("Ignored: Unix required");
+      return;
+    }
+
+    File topDir = IoTestUtil.createTestDir("topDir");
+    File testDir = IoTestUtil.createTestDir(topDir, "weird\ndir\nname");
+    File testFile = IoTestUtil.createTestFile(testDir, "weird\nfile\nname");
+    refresh(topDir);
+
+    LocalFileSystem.WatchRequest request = watch(topDir);
+    try {
+      myAccept = true;
+      FileUtil.writeToFile(testFile, "abc");
+      assertEvent(VFileContentChangeEvent.class, testFile.getPath());
+    }
+    finally {
+      unwatch(request);
+    }
+  }
+
 
   @NotNull
   private LocalFileSystem.WatchRequest watch(final File watchFile) {