public void StartDispatching(FileSystemWatcher fsw) { KeventData keventData; lock (this) { if (KeventWatcher.thread == null) { KeventWatcher.thread = new Thread(new ThreadStart(this.Monitor)); KeventWatcher.thread.IsBackground = true; KeventWatcher.thread.Start(); } keventData = (KeventData)KeventWatcher.watches[fsw]; } if (keventData == null) { keventData = new KeventData(); keventData.FSW = fsw; keventData.Directory = fsw.FullPath; keventData.FileMask = fsw.MangledFilter; keventData.IncludeSubdirs = fsw.IncludeSubdirectories; keventData.Enabled = true; lock (this) { KeventWatcher.StartMonitoringDirectory(keventData); KeventWatcher.watches[fsw] = keventData; KeventWatcher.stop = false; } } }
private void Monitor() { while (!KeventWatcher.stop) { kevent ev = default(kevent); ev.udata = IntPtr.Zero; kevent kevent = default(kevent); kevent.udata = IntPtr.Zero; timespec timespec = default(timespec); timespec.tv_sec = 0; timespec.tv_usec = 0; int num; lock (this) { num = KeventWatcher.kevent(KeventWatcher.conn, ref kevent, 0, ref ev, 1, ref timespec); } if (num > 0) { KeventData data = (KeventData)KeventWatcher.requests[ev.ident]; KeventWatcher.StopMonitoringDirectory(data); KeventWatcher.StartMonitoringDirectory(data); this.ProcessEvent(ev); } else { Thread.Sleep(500); } } lock (this) { KeventWatcher.thread = null; KeventWatcher.stop = false; } }
private void PostEvent (string filename, FileSystemWatcher fsw, FileAction fa, FileSystemInfo changedFsi) { RenamedEventArgs renamed = null; if (fa == 0) return; if (fsw.IncludeSubdirectories && fa == FileAction.Added) { if (changedFsi is DirectoryInfo) { KeventData newdirdata = new KeventData (); newdirdata.FSW = fsw; newdirdata.Directory = changedFsi.FullName; newdirdata.FileMask = fsw.MangledFilter; newdirdata.IncludeSubdirs = fsw.IncludeSubdirectories; newdirdata.Enabled = true; lock (this) { StartMonitoringDirectory (newdirdata); } } } if (!fsw.Pattern.IsMatch(filename, true)) return; lock (fsw) { if (changedFsi.FullName.StartsWith (fsw.FullPath, StringComparison.Ordinal)) filename = changedFsi.FullName.Substring (fsw.FullPath.Length + 1); fsw.DispatchEvents (fa, filename, ref renamed); if (fsw.Waiting) { fsw.Waiting = false; System.Threading.Monitor.PulseAll (fsw); } } }
static void StopMonitoringDirectory (KeventData data) { close(data.ev.ident); }
static void StartMonitoringDirectory (KeventData data) { DirectoryInfo dir = new DirectoryInfo (data.Directory); if(data.DirEntries == null) { data.DirEntries = new Hashtable(); foreach (FileSystemInfo fsi in dir.GetFileSystemInfos() ) data.DirEntries.Add(fsi.FullName, new KeventFileData(fsi, fsi.LastAccessTime, fsi.LastWriteTime)); } int fd = open(data.Directory, 0, 0); kevent ev = new kevent(); ev.udata = IntPtr.Zero; timespec nullts = new timespec(); nullts.tv_sec = 0; nullts.tv_usec = 0; if (fd > 0) { ev.ident = fd; ev.filter = -4; ev.flags = 1 | 4 | 20; ev.fflags = 20 | 2 | 1 | 8; ev.data = 0; ev.udata = Marshal.StringToHGlobalAuto (data.Directory); kevent outev = new kevent(); outev.udata = IntPtr.Zero; kevent (conn, ref ev, 1, ref outev, 0, ref nullts); data.ev = ev; requests [fd] = data; } if (!data.IncludeSubdirs) return; }
public void StartDispatching (FileSystemWatcher fsw) { KeventData data; lock (this) { if (thread == null) { thread = new Thread (new ThreadStart (Monitor)); thread.IsBackground = true; thread.Start (); } data = (KeventData) watches [fsw]; } if (data == null) { data = new KeventData (); data.FSW = fsw; data.Directory = fsw.FullPath; data.FileMask = fsw.MangledFilter; data.IncludeSubdirs = fsw.IncludeSubdirectories; data.Enabled = true; lock (this) { StartMonitoringDirectory (data); watches [fsw] = data; stop = false; } } }
static void StartMonitoringDirectory (KeventData data) { DirectoryInfo dir = new DirectoryInfo (data.Directory); if(data.DirEntries == null) { data.DirEntries = new Hashtable(); foreach (FileSystemInfo fsi in dir.GetFileSystemInfos() ) data.DirEntries.Add(fsi.FullName, new KeventFileData(fsi, fsi.LastAccessTime, fsi.LastWriteTime)); } int fd = open(data.Directory, 0, 0); kevent ev = new kevent(); ev.udata = IntPtr.Zero; timespec nullts = new timespec(); nullts.tv_sec = 0; nullts.tv_usec = 0; if (fd > 0) { ev.ident = fd; ev.filter = EventFilter.Vnode; ev.flags = EventFlags.Add | EventFlags.Enable | EventFlags.OneShot; ev.fflags = // 20 | 2 | 1 | 8; FilterFlags.VNodeDelete | FilterFlags.VNodeWrite | FilterFlags.VNodeAttrib | // The following two values are the equivalent of the original value "20", but we suspect the original author meant // 0x20, we will review later with some test cases FilterFlags.VNodeLink | FilterFlags.VNodeExtend; ev.data = 0; ev.udata = Marshal.StringToHGlobalAuto (data.Directory); kevent outev = new kevent(); outev.udata = IntPtr.Zero; kevent (conn, ref ev, 1, ref outev, 0, ref nullts); data.ev = ev; requests [fd] = data; } if (!data.IncludeSubdirs) return; }
private void ProcessEvent(kevent ev) { lock (this) { KeventData keventData = (KeventData)KeventWatcher.requests[ev.ident]; if (keventData.Enabled) { string text = string.Empty; FileSystemWatcher fsw = keventData.FSW; DirectoryInfo directoryInfo = new DirectoryInfo(keventData.Directory); FileSystemInfo changedFsi = null; try { foreach (FileSystemInfo fileSystemInfo in directoryInfo.GetFileSystemInfos()) { if (keventData.DirEntries.ContainsKey(fileSystemInfo.FullName) && fileSystemInfo is FileInfo) { KeventFileData keventFileData = (KeventFileData)keventData.DirEntries[fileSystemInfo.FullName]; if (keventFileData.LastWriteTime != fileSystemInfo.LastWriteTime) { text = fileSystemInfo.Name; FileAction fa = FileAction.Modified; keventData.DirEntries[fileSystemInfo.FullName] = new KeventFileData(fileSystemInfo, fileSystemInfo.LastAccessTime, fileSystemInfo.LastWriteTime); if (fsw.IncludeSubdirectories && fileSystemInfo is DirectoryInfo) { keventData.Directory = text; KeventWatcher.requests[ev.ident] = keventData; this.ProcessEvent(ev); } this.PostEvent(text, fsw, fa, changedFsi); } } } } catch (Exception) { } try { bool flag = true; while (flag) { foreach (object obj in keventData.DirEntries.Values) { KeventFileData keventFileData2 = (KeventFileData)obj; if (!File.Exists(keventFileData2.fsi.FullName) && !Directory.Exists(keventFileData2.fsi.FullName)) { text = keventFileData2.fsi.Name; FileAction fa = FileAction.Removed; keventData.DirEntries.Remove(keventFileData2.fsi.FullName); this.PostEvent(text, fsw, fa, changedFsi); break; } } flag = false; } } catch (Exception) { } try { foreach (FileSystemInfo fileSystemInfo2 in directoryInfo.GetFileSystemInfos()) { if (!keventData.DirEntries.ContainsKey(fileSystemInfo2.FullName)) { changedFsi = fileSystemInfo2; text = fileSystemInfo2.Name; FileAction fa = FileAction.Added; keventData.DirEntries[fileSystemInfo2.FullName] = new KeventFileData(fileSystemInfo2, fileSystemInfo2.LastAccessTime, fileSystemInfo2.LastWriteTime); this.PostEvent(text, fsw, fa, changedFsi); } } } catch (Exception) { } } } }
private static void StopMonitoringDirectory(KeventData data) { KeventWatcher.close(data.ev.ident); }