예제 #1
0
        static bool RemoveRequestData(InotifyData data)
        {
            int    wd  = data.Watch;
            object obj = requests [wd];

            if (obj == null)
            {
                return(true);
            }

            if (obj is InotifyData)
            {
                if (obj == data)
                {
                    requests.Remove(wd);
                    return(true);
                }
                return(false);
            }

            ArrayList list = (ArrayList)obj;

            list.Remove(data);
            if (list.Count == 0)
            {
                requests.Remove(wd);
                return(true);
            }
            return(false);
        }
예제 #2
0
        private static bool RemoveRequestData(InotifyData data)
        {
            int    watch = data.Watch;
            object obj   = InotifyWatcher.requests[watch];

            if (obj == null)
            {
                return(true);
            }
            if (obj is InotifyData)
            {
                if (obj == data)
                {
                    InotifyWatcher.requests.Remove(watch);
                    return(true);
                }
                return(false);
            }
            else
            {
                ArrayList arrayList = (ArrayList)obj;
                arrayList.Remove(data);
                if (arrayList.Count == 0)
                {
                    InotifyWatcher.requests.Remove(watch);
                    return(true);
                }
                return(false);
            }
        }
예제 #3
0
 public void StopDispatching(FileSystemWatcher fsw)
 {
     lock (this)
     {
         ParentInotifyData parentInotifyData = (ParentInotifyData)InotifyWatcher.watches[fsw];
         if (parentInotifyData != null)
         {
             if (InotifyWatcher.RemoveRequestData(parentInotifyData.data))
             {
                 InotifyWatcher.StopMonitoringDirectory(parentInotifyData.data);
             }
             InotifyWatcher.watches.Remove(fsw);
             if (InotifyWatcher.watches.Count == 0)
             {
                 InotifyWatcher.stop = true;
                 IntPtr fd = InotifyWatcher.FD;
                 InotifyWatcher.FD = (IntPtr)(-1);
                 InotifyWatcher.Close(fd);
             }
             if (parentInotifyData.IncludeSubdirs)
             {
                 foreach (object obj in parentInotifyData.children)
                 {
                     InotifyData data = (InotifyData)obj;
                     if (InotifyWatcher.RemoveRequestData(data))
                     {
                         InotifyWatcher.StopMonitoringDirectory(data);
                     }
                 }
             }
         }
     }
 }
예제 #4
0
        public void StartDispatching(object handle)
        {
            if (handle == null)
            {
                return;
            }
            var fsw = handle as FileSystemWatcher;
            ParentInotifyData parent;

            lock (this) {
                if ((long)FD == -1)
                {
                    FD = GetInotifyInstance();
                }

                if (thread == null)
                {
                    thread = new Thread(new ThreadStart(Monitor));
                    thread.IsBackground = true;
                    thread.Start();
                }

                parent = (ParentInotifyData)watches [fsw];
            }

            if (parent == null)
            {
                InotifyData data = new InotifyData();
                data.FSW       = fsw;
                data.Directory = fsw.FullPath;

                parent = new ParentInotifyData();
                parent.IncludeSubdirs = fsw.IncludeSubdirectories;
                parent.Enabled        = true;
                parent.children       = new ArrayList();
                parent.data           = data;

                watches [fsw] = parent;

                try {
                    StartMonitoringDirectory(data, false);
                    lock (this) {
                        AppendRequestData(data);
                        stop = false;
                    }
                } catch {}                 // ignore the directory if StartMonitoringDirectory fails.
            }
        }
예제 #5
0
        public void StartDispatching(FileSystemWatcher fsw)
        {
            InotifyData data;

            lock (this) {
                if ((long)FD == -1)
                {
                    FD = GetInotifyInstance();
                }

                if (thread == null)
                {
                    thread = new Thread(new ThreadStart(Monitor));
                    thread.IsBackground = true;
                    thread.Start();
                }

                data = (InotifyData)watches [fsw];
            }

            if (data == null)
            {
                data                = new InotifyData();
                data.FSW            = fsw;
                data.Directory      = fsw.FullPath;
                data.FileMask       = fsw.MangledFilter;
                data.IncludeSubdirs = fsw.IncludeSubdirectories;
                if (data.IncludeSubdirs)
                {
                    data.SubDirs = new Hashtable();
                }

                data.Enabled = true;
                try {
                    StartMonitoringDirectory(data, false);
                    lock (this) {
                        watches [fsw] = data;
                        AppendRequestData(data);
                        stop = false;
                    }
                } catch {}                 // ignore the directory if StartMonitoringDirectory fails.
            }
        }
예제 #6
0
        public void StartDispatching(FileSystemWatcher fsw)
        {
            ParentInotifyData parentInotifyData;

            lock (this)
            {
                if ((long)FD == -1)
                {
                    FD = GetInotifyInstance();
                }
                if (thread == null)
                {
                    thread = new Thread(Monitor);
                    thread.IsBackground = true;
                    thread.Start();
                }
                parentInotifyData = (ParentInotifyData)watches[fsw];
            }
            if (parentInotifyData == null)
            {
                InotifyData inotifyData = new InotifyData();
                inotifyData.FSW                  = fsw;
                inotifyData.Directory            = fsw.FullPath;
                parentInotifyData                = new ParentInotifyData();
                parentInotifyData.IncludeSubdirs = fsw.IncludeSubdirectories;
                parentInotifyData.Enabled        = true;
                parentInotifyData.children       = new ArrayList();
                parentInotifyData.data           = inotifyData;
                watches[fsw] = parentInotifyData;
                try
                {
                    StartMonitoringDirectory(inotifyData, justcreated: false);
                    lock (this)
                    {
                        AppendRequestData(inotifyData);
                        stop = false;
                    }
                }
                catch
                {
                }
            }
        }
예제 #7
0
        public void StartDispatching(FileSystemWatcher fsw)
        {
            ParentInotifyData parentInotifyData;

            lock (this)
            {
                if ((long)InotifyWatcher.FD == -1L)
                {
                    InotifyWatcher.FD = InotifyWatcher.GetInotifyInstance();
                }
                if (InotifyWatcher.thread == null)
                {
                    InotifyWatcher.thread = new Thread(new ThreadStart(this.Monitor));
                    InotifyWatcher.thread.IsBackground = true;
                    InotifyWatcher.thread.Start();
                }
                parentInotifyData = (ParentInotifyData)InotifyWatcher.watches[fsw];
            }
            if (parentInotifyData == null)
            {
                InotifyData inotifyData = new InotifyData();
                inotifyData.FSW                  = fsw;
                inotifyData.Directory            = fsw.FullPath;
                parentInotifyData                = new ParentInotifyData();
                parentInotifyData.IncludeSubdirs = fsw.IncludeSubdirectories;
                parentInotifyData.Enabled        = true;
                parentInotifyData.children       = new ArrayList();
                parentInotifyData.data           = inotifyData;
                InotifyWatcher.watches[fsw]      = parentInotifyData;
                try
                {
                    InotifyWatcher.StartMonitoringDirectory(inotifyData, false);
                    lock (this)
                    {
                        InotifyWatcher.AppendRequestData(inotifyData);
                        InotifyWatcher.stop = false;
                    }
                }
                catch
                {
                }
            }
        }
예제 #8
0
        private static void AppendRequestData(InotifyData data)
        {
            int    watch = data.Watch;
            object obj   = InotifyWatcher.requests[watch];

            if (obj == null)
            {
                InotifyWatcher.requests[data.Watch] = data;
            }
            else if (obj is InotifyData)
            {
                ArrayList arrayList = new ArrayList();
                arrayList.Add(obj);
                arrayList.Add(data);
                InotifyWatcher.requests[data.Watch] = arrayList;
            }
            else
            {
                ArrayList arrayList = (ArrayList)obj;
                arrayList.Add(data);
            }
        }
예제 #9
0
        static void AppendRequestData(InotifyData data)
        {
            int       wd   = data.Watch;
            object    obj  = requests [wd];
            ArrayList list = null;

            if (obj == null)
            {
                requests [data.Watch] = data;
            }
            else if (obj is InotifyData)
            {
                list = new ArrayList();
                list.Add(obj);
                list.Add(data);
                requests [data.Watch] = list;
            }
            else
            {
                list = (ArrayList)obj;
                list.Add(data);
            }
        }
예제 #10
0
		static bool RemoveRequestData (InotifyData data)
		{
			int wd = data.Watch;
			object obj = requests [wd];
			if (obj == null)
				return true;

			if (obj is InotifyData) {
				if (obj == data) {
					requests.Remove (wd);
					return true;
				}
				return false;
			}

			ArrayList list = (ArrayList) obj;
			list.Remove (data);
			if (list.Count == 0) {
				requests.Remove (wd);
				return true;
			}
			return false;
		}
예제 #11
0
 private static void StopMonitoringDirectory(InotifyData data)
 {
     InotifyWatcher.RemoveWatch(InotifyWatcher.FD, data.Watch);
 }
예제 #12
0
		static void StartMonitoringDirectory (InotifyData data, bool justcreated)
		{
			InotifyMask mask = GetMaskFromFilters (data.FSW.NotifyFilter);
			int wd = AddDirectoryWatch (FD, data.Directory, mask);
			if (wd == -1) {
				int error = Marshal.GetLastWin32Error ();
				if (error == 4) { // Too many open watches
					string nr_watches = "(unknown)";
					try {
						using (StreamReader reader = new StreamReader ("/proc/sys/fs/inotify/max_user_watches")) {
							nr_watches = reader.ReadLine ();
						}
					} catch {}

					string msg = String.Format ("The per-user inotify watches limit of {0} has been reached. " +
								"If you're experiencing problems with your application, increase that limit " +
								"in /proc/sys/fs/inotify/max_user_watches.", nr_watches);
					
					throw new Win32Exception (error, msg);
				}
				throw new Win32Exception (error);
			}

			FileSystemWatcher fsw = data.FSW;
			data.Watch = wd;

			ParentInotifyData parent = (ParentInotifyData) watches[fsw];

			if (parent.IncludeSubdirs) {
				foreach (string directory in Directory.GetDirectories (data.Directory)) {
					InotifyData fd = new InotifyData ();
					fd.FSW = fsw;
					fd.Directory = directory;

					if (justcreated) {
						lock (fsw) {
							RenamedEventArgs renamed = null;
							if (fsw.Pattern.IsMatch (directory)) {
								fsw.DispatchEvents (FileAction.Added, directory, ref renamed);
								if (fsw.Waiting) {
									fsw.Waiting = false;
									System.Threading.Monitor.PulseAll (fsw);
								}
							}
						}
					}

					try {
						StartMonitoringDirectory (fd, justcreated);
						AppendRequestData (fd);
					        parent.children.Add(fd);
					} catch {} // ignore errors and don't add directory.
				}
			}

			if (justcreated) {
				foreach (string filename in Directory.GetFiles (data.Directory)) {
					lock (fsw) {
						RenamedEventArgs renamed = null;
						if (fsw.Pattern.IsMatch (filename)) {
							fsw.DispatchEvents (FileAction.Added, filename, ref renamed);
							/* If a file has been created, then it has been written to */
							fsw.DispatchEvents (FileAction.Modified, filename, ref renamed);

							if (fsw.Waiting) {
								fsw.Waiting = false;
								System.Threading.Monitor.PulseAll(fsw);
							}
						}
					}
				}
			}
		}
예제 #13
0
        private static void StartMonitoringDirectory(InotifyData data, bool justcreated)
        {
            InotifyMask maskFromFilters = InotifyWatcher.GetMaskFromFilters(data.FSW.NotifyFilter);
            int         num             = InotifyWatcher.AddDirectoryWatch(InotifyWatcher.FD, data.Directory, maskFromFilters);

            if (num != -1)
            {
                FileSystemWatcher fsw = data.FSW;
                data.Watch = num;
                ParentInotifyData parentInotifyData = (ParentInotifyData)InotifyWatcher.watches[fsw];
                if (parentInotifyData.IncludeSubdirs)
                {
                    foreach (string text in Directory.GetDirectories(data.Directory))
                    {
                        InotifyData inotifyData = new InotifyData();
                        inotifyData.FSW       = fsw;
                        inotifyData.Directory = text;
                        if (justcreated)
                        {
                            FileSystemWatcher obj = fsw;
                            lock (obj)
                            {
                                RenamedEventArgs renamedEventArgs = null;
                                if (fsw.Pattern.IsMatch(text))
                                {
                                    fsw.DispatchEvents(FileAction.Added, text, ref renamedEventArgs);
                                    if (fsw.Waiting)
                                    {
                                        fsw.Waiting = false;
                                        System.Threading.Monitor.PulseAll(fsw);
                                    }
                                }
                            }
                        }
                        try
                        {
                            InotifyWatcher.StartMonitoringDirectory(inotifyData, justcreated);
                            InotifyWatcher.AppendRequestData(inotifyData);
                            parentInotifyData.children.Add(inotifyData);
                        }
                        catch
                        {
                        }
                    }
                }
                if (justcreated)
                {
                    foreach (string text2 in Directory.GetFiles(data.Directory))
                    {
                        FileSystemWatcher obj2 = fsw;
                        lock (obj2)
                        {
                            RenamedEventArgs renamedEventArgs2 = null;
                            if (fsw.Pattern.IsMatch(text2))
                            {
                                fsw.DispatchEvents(FileAction.Added, text2, ref renamedEventArgs2);
                                fsw.DispatchEvents(FileAction.Modified, text2, ref renamedEventArgs2);
                                if (fsw.Waiting)
                                {
                                    fsw.Waiting = false;
                                    System.Threading.Monitor.PulseAll(fsw);
                                }
                            }
                        }
                    }
                }
                return;
            }
            int lastWin32Error = Marshal.GetLastWin32Error();

            if (lastWin32Error == 4)
            {
                string arg = "(unknown)";
                try
                {
                    using (StreamReader streamReader = new StreamReader("/proc/sys/fs/inotify/max_user_watches"))
                    {
                        arg = streamReader.ReadLine();
                    }
                }
                catch
                {
                }
                string message = string.Format("The per-user inotify watches limit of {0} has been reached. If you're experiencing problems with your application, increase that limit in /proc/sys/fs/inotify/max_user_watches.", arg);
                throw new System.ComponentModel.Win32Exception(lastWin32Error, message);
            }
            throw new System.ComponentModel.Win32Exception(lastWin32Error);
        }
예제 #14
0
        void ProcessEvents(byte [] buffer, int length)
        {
            ArrayList        newdirs = null;
            InotifyEvent     evt;
            int              nread   = 0;
            RenamedEventArgs renamed = null;

            while (length > nread)
            {
                int bytes_read = ReadEvent(buffer, nread, length, out evt);
                if (bytes_read <= 0)
                {
                    break;
                }

                nread += bytes_read;

                InotifyMask mask         = evt.Mask;
                bool        is_directory = (mask & InotifyMask.Directory) != 0;
                mask = (mask & Interesting);                 // Clear out all the bits that we don't need
                if (mask == 0)
                {
                    continue;
                }

                foreach (InotifyData data in GetEnumerator(requests [evt.WatchDescriptor]))
                {
                    ParentInotifyData parent = (ParentInotifyData)watches[data.FSW];

                    if (data == null || parent.Enabled == false)
                    {
                        continue;
                    }

                    string directory = data.Directory;
                    string filename  = evt.Name;
                    if (filename == null)
                    {
                        filename = directory;
                    }

                    FileSystemWatcher fsw    = data.FSW;
                    FileAction        action = 0;
                    if ((mask & (InotifyMask.Modify | InotifyMask.Attrib)) != 0)
                    {
                        action = FileAction.Modified;
                    }
                    else if ((mask & InotifyMask.Create) != 0)
                    {
                        action = FileAction.Added;
                    }
                    else if ((mask & InotifyMask.Delete) != 0)
                    {
                        action = FileAction.Removed;
                    }
                    else if ((mask & InotifyMask.DeleteSelf) != 0)
                    {
                        if (data.Watch != parent.data.Watch)
                        {
                            // To avoid duplicate events handle DeleteSelf only for the top level directory.
                            continue;
                        }
                        action = FileAction.Removed;
                    }
                    else if ((mask & InotifyMask.MoveSelf) != 0)
                    {
                        //action = FileAction.Removed;
                        continue;                         // Ignore this one
                    }
                    else if ((mask & InotifyMask.MovedFrom) != 0)
                    {
                        InotifyEvent to;
                        int          i = ReadEvent(buffer, nread, length, out to);
                        if (i == -1 || (to.Mask & InotifyMask.MovedTo) == 0 || evt.WatchDescriptor != to.WatchDescriptor)
                        {
                            action = FileAction.Removed;
                        }
                        else
                        {
                            nread  += i;
                            action  = FileAction.RenamedNewName;
                            renamed = new RenamedEventArgs(WatcherChangeTypes.Renamed, data.Directory, to.Name, evt.Name);
                            if (evt.Name != data.Directory && !fsw.Pattern.IsMatch(evt.Name))
                            {
                                filename = to.Name;
                            }
                        }
                    }
                    else if ((mask & InotifyMask.MovedTo) != 0)
                    {
                        action = FileAction.Added;
                    }
                    if (fsw.IncludeSubdirectories)
                    {
                        string full    = fsw.FullPath;
                        string datadir = data.Directory;
                        if (datadir != full)
                        {
                            int len   = full.Length;
                            int slash = 1;
                            if (len > 1 && full [len - 1] == Path.DirectorySeparatorChar)
                            {
                                slash = 0;
                            }
                            string reldir = datadir.Substring(full.Length + slash);
                            datadir  = Path.Combine(datadir, filename);
                            filename = Path.Combine(reldir, filename);
                        }
                        else
                        {
                            datadir = Path.Combine(full, filename);
                        }

                        if (action == FileAction.Added && is_directory)
                        {
                            if (newdirs == null)
                            {
                                newdirs = new ArrayList(2);
                            }

                            InotifyData fd = new InotifyData();
                            fd.FSW       = fsw;
                            fd.Directory = datadir;
                            newdirs.Add(fd);
                        }

                        if (action == FileAction.RenamedNewName && is_directory)
                        {
                            string renamedOldFullPath       = renamed.OldFullPath;
                            string renamedFullPath          = renamed.FullPath;
                            int    renamedOldFullPathLength = renamedOldFullPath.Length;

                            foreach (InotifyData child in parent.children)
                            {
                                if (child.Directory.StartsWith(renamedOldFullPath
#if NET_2_0
                                                               , StringComparison.Ordinal
#endif
                                                               ))
                                {
                                    child.Directory = renamedFullPath +
                                                      child.Directory.Substring(renamedOldFullPathLength);
                                }
                            }
                        }
                    }

                    if (action == FileAction.Removed && filename == data.Directory)
                    {
                        int idx = parent.children.IndexOf(data);
                        if (idx != -1)
                        {
                            parent.children.RemoveAt(idx);
                            if (!fsw.Pattern.IsMatch(Path.GetFileName(filename)))
                            {
                                continue;
                            }
                        }
                    }

                    if (filename != data.Directory && !fsw.Pattern.IsMatch(Path.GetFileName(filename)))
                    {
                        continue;
                    }

                    lock (fsw) {
                        fsw.DispatchEvents(action, filename, ref renamed);
                        if (action == FileAction.RenamedNewName)
                        {
                            renamed = null;
                        }
                        if (fsw.Waiting)
                        {
                            fsw.Waiting = false;
                            System.Threading.Monitor.PulseAll(fsw);
                        }
                    }
                }
            }

            if (newdirs != null)
            {
                foreach (InotifyData newdir in newdirs)
                {
                    try {
                        StartMonitoringDirectory(newdir, true);
                        AppendRequestData(newdir);
                        ((ParentInotifyData)watches[newdir.FSW]).children.Add(newdir);
                    } catch {}                     // ignore the given directory
                }
                newdirs.Clear();
            }
        }
예제 #15
0
		static void StopMonitoringDirectory (InotifyData data)
		{
			RemoveWatch (FD, data.Watch);
		}
예제 #16
0
        static void StartMonitoringDirectory(InotifyData data, bool justcreated)
        {
            InotifyMask mask = GetMaskFromFilters(data.FSW.NotifyFilter);
            int         wd   = AddDirectoryWatch(FD, data.Directory, mask);

            if (wd == -1)
            {
                int error = Marshal.GetLastWin32Error();
                if (error == 4)                   // Too many open watches
                {
                    string nr_watches = "(unknown)";
                    try {
                        using (StreamReader reader = new StreamReader("/proc/sys/fs/inotify/max_user_watches")) {
                            nr_watches = reader.ReadLine();
                        }
                    } catch {}

                    string msg = String.Format("The per-user inotify watches limit of {0} has been reached. " +
                                               "If you're experiencing problems with your application, increase that limit " +
                                               "in /proc/sys/fs/inotify/max_user_watches.", nr_watches);

                    throw new Win32Exception(error, msg);
                }
                throw new Win32Exception(error);
            }

            FileSystemWatcher fsw = data.FSW;

            data.Watch = wd;

            ParentInotifyData parent = (ParentInotifyData)watches[fsw];

            if (parent.IncludeSubdirs)
            {
                foreach (string directory in Directory.GetDirectories(data.Directory))
                {
                    InotifyData fd = new InotifyData();
                    fd.FSW       = fsw;
                    fd.Directory = directory;

                    if (justcreated)
                    {
                        lock (fsw) {
                            RenamedEventArgs renamed = null;
                            if (fsw.Pattern.IsMatch(directory))
                            {
                                fsw.DispatchEvents(FileAction.Added, directory, ref renamed);
                                if (fsw.Waiting)
                                {
                                    fsw.Waiting = false;
                                    System.Threading.Monitor.PulseAll(fsw);
                                }
                            }
                        }
                    }

                    try {
                        StartMonitoringDirectory(fd, justcreated);
                        AppendRequestData(fd);
                        parent.children.Add(fd);
                    } catch {}                     // ignore errors and don't add directory.
                }
            }

            if (justcreated)
            {
                foreach (string filename in Directory.GetFiles(data.Directory))
                {
                    lock (fsw) {
                        RenamedEventArgs renamed = null;
                        if (fsw.Pattern.IsMatch(filename))
                        {
                            fsw.DispatchEvents(FileAction.Added, filename, ref renamed);
                            /* If a file has been created, then it has been written to */
                            fsw.DispatchEvents(FileAction.Modified, filename, ref renamed);

                            if (fsw.Waiting)
                            {
                                fsw.Waiting = false;
                                System.Threading.Monitor.PulseAll(fsw);
                            }
                        }
                    }
                }
            }
        }
예제 #17
0
 static void StopMonitoringDirectory(InotifyData data)
 {
     RemoveWatch(FD, data.Watch);
 }
예제 #18
0
		void ProcessEvents (byte [] buffer, int length)
		{
			ArrayList newdirs = null;
			InotifyEvent evt;
			int nread = 0;
			RenamedEventArgs renamed = null;
			while (length > nread) {
				int bytes_read = ReadEvent (buffer, nread, length, out evt);
				if (bytes_read <= 0)
					break;

				nread += bytes_read;

				InotifyMask mask = evt.Mask;
				bool is_directory = (mask & InotifyMask.Directory) != 0;
				mask = (mask & Interesting); // Clear out all the bits that we don't need
				if (mask == 0)
					continue;

				foreach (InotifyData data in GetEnumerator (requests [evt.WatchDescriptor])) {
				        ParentInotifyData parent = (ParentInotifyData) watches[data.FSW];

					if (data == null || parent.Enabled == false)
						continue;

					string directory = data.Directory;
					string filename = evt.Name;
					if (filename == null)
						filename = directory;

					FileSystemWatcher fsw = data.FSW;
					FileAction action = 0;
					if ((mask & (InotifyMask.Modify | InotifyMask.Attrib)) != 0) {
						action = FileAction.Modified;
					} else if ((mask & InotifyMask.Create) != 0) {
						action = FileAction.Added;
					} else if ((mask & InotifyMask.Delete) != 0) {
						action = FileAction.Removed;
					} else if ((mask & InotifyMask.DeleteSelf) != 0) {
						if (data.Watch != parent.data.Watch) {
							// To avoid duplicate events handle DeleteSelf only for the top level directory.
							continue;
						}
						action = FileAction.Removed;
					} else if ((mask & InotifyMask.MoveSelf) != 0) {
						//action = FileAction.Removed;
						continue; // Ignore this one
					} else if ((mask & InotifyMask.MovedFrom) != 0) {
						InotifyEvent to;
						int i = ReadEvent (buffer, nread, length, out to);
						if (i == -1 || (to.Mask & InotifyMask.MovedTo) == 0 || evt.WatchDescriptor != to.WatchDescriptor) {
							action = FileAction.Removed;
						} else {
							nread += i;
							action = FileAction.RenamedNewName;
							renamed = new RenamedEventArgs (WatcherChangeTypes.Renamed, data.Directory, to.Name, evt.Name);
							if (evt.Name != data.Directory && !fsw.Pattern.IsMatch (evt.Name))
								filename = to.Name;
						}
					} else if ((mask & InotifyMask.MovedTo) != 0) {
						action = FileAction.Added;
					}
					if (fsw.IncludeSubdirectories) {
						string full = fsw.FullPath;
						string datadir = data.Directory;
						if (datadir != full) {
							int len = full.Length;
							int slash = 1;
							if (len > 1 && full [len - 1] == Path.DirectorySeparatorChar)
								slash = 0;
							string reldir = datadir.Substring (full.Length + slash);
							datadir = Path.Combine (datadir, filename);
							filename = Path.Combine (reldir, filename);
						} else {
							datadir = Path.Combine (full, filename);
						}

						if (action == FileAction.Added && is_directory) {
							if (newdirs == null)
								newdirs = new ArrayList (2);

							InotifyData fd = new InotifyData ();
							fd.FSW = fsw;
							fd.Directory = datadir;
							newdirs.Add (fd);
						}

						if (action == FileAction.RenamedNewName && is_directory) {
							string renamedOldFullPath = renamed.OldFullPath;
							string renamedFullPath = renamed.FullPath;
							int renamedOldFullPathLength = renamedOldFullPath.Length;
							
							foreach (InotifyData child in parent.children) {
									
								if (child.Directory.StartsWith (renamedOldFullPath
												, StringComparison.Ordinal
								    )) {
									child.Directory = renamedFullPath +
										child.Directory.Substring (renamedOldFullPathLength);
								}
							}
						}
					}

					if (action == FileAction.Removed && filename == data.Directory) {
						int idx = parent.children.IndexOf (data);
						if (idx != -1) {
							parent.children.RemoveAt (idx);
							if (!fsw.Pattern.IsMatch (Path.GetFileName (filename))) {
								continue;
							}
						}
					}

					if (filename != data.Directory && !fsw.Pattern.IsMatch (Path.GetFileName (filename))) {
						continue;
					}

					lock (fsw) {
						fsw.DispatchEvents (action, filename, ref renamed);
						if (action == FileAction.RenamedNewName)
							renamed = null;
						if (fsw.Waiting) {
							fsw.Waiting = false;
							System.Threading.Monitor.PulseAll (fsw);
						}
					}
				}
			}

			if (newdirs != null) {
			        foreach (InotifyData newdir in newdirs) {
					try {
						StartMonitoringDirectory (newdir, true);
						AppendRequestData (newdir);
					        ((ParentInotifyData) watches[newdir.FSW]).children.Add(newdir);
					} catch {} // ignore the given directory
				}
				newdirs.Clear ();
			}
		}
예제 #19
0
		static void AppendRequestData (InotifyData data)
		{
			int wd = data.Watch;

			object obj = requests [wd];
			ArrayList list = null;
			if (obj == null) {
				requests [data.Watch] = data;
			} else if (obj is InotifyData) {
				list = new ArrayList ();
				list.Add (obj);
				list.Add (data);
				requests [data.Watch] = list;
			} else {
				list = (ArrayList) obj;
				list.Add (data);
			}
		}
예제 #20
0
        private void ProcessEvents(byte[] buffer, int length)
        {
            ArrayList        arrayList        = null;
            int              num              = 0;
            RenamedEventArgs renamedEventArgs = null;

            while (length > num)
            {
                InotifyEvent inotifyEvent;
                int          num2 = InotifyWatcher.ReadEvent(buffer, num, length, out inotifyEvent);
                if (num2 <= 0)
                {
                    break;
                }
                num += num2;
                InotifyMask inotifyMask = inotifyEvent.Mask;
                bool        flag        = (inotifyMask & InotifyMask.Directory) != (InotifyMask)0u;
                inotifyMask &= InotifyWatcher.Interesting;
                if (inotifyMask != (InotifyMask)0u)
                {
                    foreach (object obj in InotifyWatcher.GetEnumerator(InotifyWatcher.requests[inotifyEvent.WatchDescriptor]))
                    {
                        InotifyData       inotifyData       = (InotifyData)obj;
                        ParentInotifyData parentInotifyData = (ParentInotifyData)InotifyWatcher.watches[inotifyData.FSW];
                        if (inotifyData != null && parentInotifyData.Enabled)
                        {
                            string directory = inotifyData.Directory;
                            string text      = inotifyEvent.Name;
                            if (text == null)
                            {
                                text = directory;
                            }
                            FileSystemWatcher fsw        = inotifyData.FSW;
                            FileAction        fileAction = (FileAction)0;
                            if ((inotifyMask & (InotifyMask.Modify | InotifyMask.Attrib)) != (InotifyMask)0u)
                            {
                                fileAction = FileAction.Modified;
                            }
                            else if ((inotifyMask & InotifyMask.Create) != (InotifyMask)0u)
                            {
                                fileAction = FileAction.Added;
                            }
                            else if ((inotifyMask & InotifyMask.Delete) != (InotifyMask)0u)
                            {
                                fileAction = FileAction.Removed;
                            }
                            else if ((inotifyMask & InotifyMask.DeleteSelf) != (InotifyMask)0u)
                            {
                                if (inotifyData.Watch != parentInotifyData.data.Watch)
                                {
                                    continue;
                                }
                                fileAction = FileAction.Removed;
                            }
                            else
                            {
                                if ((inotifyMask & InotifyMask.MoveSelf) != (InotifyMask)0u)
                                {
                                    continue;
                                }
                                if ((inotifyMask & InotifyMask.MovedFrom) != (InotifyMask)0u)
                                {
                                    InotifyEvent inotifyEvent2;
                                    int          num3 = InotifyWatcher.ReadEvent(buffer, num, length, out inotifyEvent2);
                                    if (num3 == -1 || (inotifyEvent2.Mask & InotifyMask.MovedTo) == (InotifyMask)0u || inotifyEvent.WatchDescriptor != inotifyEvent2.WatchDescriptor)
                                    {
                                        fileAction = FileAction.Removed;
                                    }
                                    else
                                    {
                                        num             += num3;
                                        fileAction       = FileAction.RenamedNewName;
                                        renamedEventArgs = new RenamedEventArgs(WatcherChangeTypes.Renamed, inotifyData.Directory, inotifyEvent2.Name, inotifyEvent.Name);
                                        if (inotifyEvent.Name != inotifyData.Directory && !fsw.Pattern.IsMatch(inotifyEvent.Name))
                                        {
                                            text = inotifyEvent2.Name;
                                        }
                                    }
                                }
                                else if ((inotifyMask & InotifyMask.MovedTo) != (InotifyMask)0u)
                                {
                                    fileAction = FileAction.Added;
                                }
                            }
                            if (fsw.IncludeSubdirectories)
                            {
                                string fullPath = fsw.FullPath;
                                string text2    = inotifyData.Directory;
                                if (text2 != fullPath)
                                {
                                    int length2 = fullPath.Length;
                                    int num4    = 1;
                                    if (length2 > 1 && fullPath[length2 - 1] == Path.DirectorySeparatorChar)
                                    {
                                        num4 = 0;
                                    }
                                    string path = text2.Substring(fullPath.Length + num4);
                                    text2 = Path.Combine(text2, text);
                                    text  = Path.Combine(path, text);
                                }
                                else
                                {
                                    text2 = Path.Combine(fullPath, text);
                                }
                                if (fileAction == FileAction.Added && flag)
                                {
                                    if (arrayList == null)
                                    {
                                        arrayList = new ArrayList(2);
                                    }
                                    arrayList.Add(new InotifyData
                                    {
                                        FSW       = fsw,
                                        Directory = text2
                                    });
                                }
                                if (fileAction == FileAction.RenamedNewName && flag)
                                {
                                    string oldFullPath = renamedEventArgs.OldFullPath;
                                    string fullPath2   = renamedEventArgs.FullPath;
                                    int    length3     = oldFullPath.Length;
                                    foreach (object obj2 in parentInotifyData.children)
                                    {
                                        InotifyData inotifyData2 = (InotifyData)obj2;
                                        if (inotifyData2.Directory.StartsWith(oldFullPath, StringComparison.Ordinal))
                                        {
                                            inotifyData2.Directory = fullPath2 + inotifyData2.Directory.Substring(length3);
                                        }
                                    }
                                }
                            }
                            if (fileAction == FileAction.Removed && text == inotifyData.Directory)
                            {
                                int num5 = parentInotifyData.children.IndexOf(inotifyData);
                                if (num5 != -1)
                                {
                                    parentInotifyData.children.RemoveAt(num5);
                                    if (!fsw.Pattern.IsMatch(Path.GetFileName(text)))
                                    {
                                        continue;
                                    }
                                }
                            }
                            if (!(text != inotifyData.Directory) || fsw.Pattern.IsMatch(Path.GetFileName(text)))
                            {
                                FileSystemWatcher obj3 = fsw;
                                lock (obj3)
                                {
                                    fsw.DispatchEvents(fileAction, text, ref renamedEventArgs);
                                    if (fileAction == FileAction.RenamedNewName)
                                    {
                                        renamedEventArgs = null;
                                    }
                                    if (fsw.Waiting)
                                    {
                                        fsw.Waiting = false;
                                        System.Threading.Monitor.PulseAll(fsw);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (arrayList != null)
            {
                foreach (object obj4 in arrayList)
                {
                    InotifyData inotifyData3 = (InotifyData)obj4;
                    try
                    {
                        InotifyWatcher.StartMonitoringDirectory(inotifyData3, true);
                        InotifyWatcher.AppendRequestData(inotifyData3);
                        ((ParentInotifyData)InotifyWatcher.watches[inotifyData3.FSW]).children.Add(inotifyData3);
                    }
                    catch
                    {
                    }
                }
                arrayList.Clear();
            }
        }
예제 #21
0
        private static void StartMonitoringDirectory(InotifyData data, bool justcreated)
        {
            InotifyMask maskFromFilters = GetMaskFromFilters(data.FSW.NotifyFilter);
            int         num             = AddDirectoryWatch(FD, data.Directory, maskFromFilters);

            if (num == -1)
            {
                int lastWin32Error = Marshal.GetLastWin32Error();
                if (lastWin32Error == 4)
                {
                    string arg = "(unknown)";
                    try
                    {
                        using (StreamReader streamReader = new StreamReader("/proc/sys/fs/inotify/max_user_watches"))
                        {
                            arg = streamReader.ReadLine();
                        }
                    }
                    catch
                    {
                    }
                    string message = $"The per-user inotify watches limit of {arg} has been reached. If you're experiencing problems with your application, increase that limit in /proc/sys/fs/inotify/max_user_watches.";
                    throw new Win32Exception(lastWin32Error, message);
                }
                throw new Win32Exception(lastWin32Error);
            }
            FileSystemWatcher fSW = data.FSW;

            data.Watch = num;
            ParentInotifyData parentInotifyData = (ParentInotifyData)watches[fSW];

            if (parentInotifyData.IncludeSubdirs)
            {
                string[] directories = Directory.GetDirectories(data.Directory);
                foreach (string text in directories)
                {
                    InotifyData inotifyData = new InotifyData();
                    inotifyData.FSW       = fSW;
                    inotifyData.Directory = text;
                    if (justcreated)
                    {
                        lock (fSW)
                        {
                            RenamedEventArgs renamed = null;
                            if (fSW.Pattern.IsMatch(text))
                            {
                                fSW.DispatchEvents(FileAction.Added, text, ref renamed);
                                if (fSW.Waiting)
                                {
                                    fSW.Waiting = false;
                                    System.Threading.Monitor.PulseAll(fSW);
                                }
                            }
                        }
                    }
                    try
                    {
                        StartMonitoringDirectory(inotifyData, justcreated);
                        AppendRequestData(inotifyData);
                        parentInotifyData.children.Add(inotifyData);
                    }
                    catch
                    {
                    }
                }
            }
            if (justcreated)
            {
                string[] files = Directory.GetFiles(data.Directory);
                foreach (string text2 in files)
                {
                    lock (fSW)
                    {
                        RenamedEventArgs renamed2 = null;
                        if (fSW.Pattern.IsMatch(text2))
                        {
                            fSW.DispatchEvents(FileAction.Added, text2, ref renamed2);
                            fSW.DispatchEvents(FileAction.Modified, text2, ref renamed2);
                            if (fSW.Waiting)
                            {
                                fSW.Waiting = false;
                                System.Threading.Monitor.PulseAll(fSW);
                            }
                        }
                    }
                }
            }
        }
예제 #22
0
        private void ProcessEvents(byte[] buffer, int length)
        {
            ArrayList        arrayList = null;
            int              num       = 0;
            RenamedEventArgs renamed   = null;

            while (length > num)
            {
                InotifyEvent evt;
                int          num2 = ReadEvent(buffer, num, length, out evt);
                if (num2 <= 0)
                {
                    break;
                }
                num += num2;
                InotifyMask mask = evt.Mask;
                bool        flag = (mask & InotifyMask.Directory) != (InotifyMask)0u;
                mask &= Interesting;
                if (mask != 0)
                {
                    foreach (InotifyData item in GetEnumerator(requests[evt.WatchDescriptor]))
                    {
                        ParentInotifyData parentInotifyData = (ParentInotifyData)watches[item.FSW];
                        if (item != null && parentInotifyData.Enabled)
                        {
                            string directory = item.Directory;
                            string text      = evt.Name;
                            if (text == null)
                            {
                                text = directory;
                            }
                            FileSystemWatcher fSW        = item.FSW;
                            FileAction        fileAction = (FileAction)0;
                            if ((mask & (InotifyMask.Modify | InotifyMask.Attrib)) != 0)
                            {
                                fileAction = FileAction.Modified;
                            }
                            else if ((mask & InotifyMask.Create) != 0)
                            {
                                fileAction = FileAction.Added;
                            }
                            else if ((mask & InotifyMask.Delete) != 0)
                            {
                                fileAction = FileAction.Removed;
                            }
                            else if ((mask & InotifyMask.DeleteSelf) != 0)
                            {
                                if (item.Watch != parentInotifyData.data.Watch)
                                {
                                    continue;
                                }
                                fileAction = FileAction.Removed;
                            }
                            else
                            {
                                if ((mask & InotifyMask.MoveSelf) != 0)
                                {
                                    continue;
                                }
                                if ((mask & InotifyMask.MovedFrom) != 0)
                                {
                                    InotifyEvent evt2;
                                    int          num3 = ReadEvent(buffer, num, length, out evt2);
                                    if (num3 == -1 || (evt2.Mask & InotifyMask.MovedTo) == (InotifyMask)0u || evt.WatchDescriptor != evt2.WatchDescriptor)
                                    {
                                        fileAction = FileAction.Removed;
                                    }
                                    else
                                    {
                                        num       += num3;
                                        fileAction = FileAction.RenamedNewName;
                                        renamed    = new RenamedEventArgs(WatcherChangeTypes.Renamed, item.Directory, evt2.Name, evt.Name);
                                        if (evt.Name != item.Directory && !fSW.Pattern.IsMatch(evt.Name))
                                        {
                                            text = evt2.Name;
                                        }
                                    }
                                }
                                else if ((mask & InotifyMask.MovedTo) != 0)
                                {
                                    fileAction = FileAction.Added;
                                }
                            }
                            if (fSW.IncludeSubdirectories)
                            {
                                string fullPath   = fSW.FullPath;
                                string directory2 = item.Directory;
                                if (directory2 != fullPath)
                                {
                                    int length2 = fullPath.Length;
                                    int num4    = 1;
                                    if (length2 > 1 && fullPath[length2 - 1] == Path.DirectorySeparatorChar)
                                    {
                                        num4 = 0;
                                    }
                                    string path = directory2.Substring(fullPath.Length + num4);
                                    directory2 = Path.Combine(directory2, text);
                                    text       = Path.Combine(path, text);
                                }
                                else
                                {
                                    directory2 = Path.Combine(fullPath, text);
                                }
                                if (fileAction == FileAction.Added && flag)
                                {
                                    if (arrayList == null)
                                    {
                                        arrayList = new ArrayList(2);
                                    }
                                    InotifyData inotifyData2 = new InotifyData();
                                    inotifyData2.FSW       = fSW;
                                    inotifyData2.Directory = directory2;
                                    arrayList.Add(inotifyData2);
                                }
                                if (fileAction == FileAction.RenamedNewName && flag)
                                {
                                    string oldFullPath = renamed.OldFullPath;
                                    string fullPath2   = renamed.FullPath;
                                    int    length3     = oldFullPath.Length;
                                    foreach (InotifyData child in parentInotifyData.children)
                                    {
                                        if (child.Directory.StartsWith(oldFullPath, StringComparison.Ordinal))
                                        {
                                            child.Directory = fullPath2 + child.Directory.Substring(length3);
                                        }
                                    }
                                }
                            }
                            if (fileAction == FileAction.Removed && text == item.Directory)
                            {
                                int num5 = parentInotifyData.children.IndexOf(item);
                                if (num5 != -1)
                                {
                                    parentInotifyData.children.RemoveAt(num5);
                                    if (!fSW.Pattern.IsMatch(Path.GetFileName(text)))
                                    {
                                        continue;
                                    }
                                }
                            }
                            if (!(text != item.Directory) || fSW.Pattern.IsMatch(Path.GetFileName(text)))
                            {
                                lock (fSW)
                                {
                                    fSW.DispatchEvents(fileAction, text, ref renamed);
                                    if (fileAction == FileAction.RenamedNewName)
                                    {
                                        renamed = null;
                                    }
                                    if (fSW.Waiting)
                                    {
                                        fSW.Waiting = false;
                                        System.Threading.Monitor.PulseAll(fSW);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (arrayList != null)
            {
                foreach (InotifyData item2 in arrayList)
                {
                    try
                    {
                        StartMonitoringDirectory(item2, justcreated: true);
                        AppendRequestData(item2);
                        ((ParentInotifyData)watches[item2.FSW]).children.Add(item2);
                    }
                    catch
                    {
                    }
                }
                arrayList.Clear();
            }
        }
예제 #23
0
        void ProcessEvents(byte [] buffer, int length)
        {
            ArrayList        newdirs = null;
            InotifyEvent     evt;
            int              nread           = 0;
            bool             new_name_needed = false;
            RenamedEventArgs renamed         = null;

            while (length > nread)
            {
                int bytes_read = ReadEvent(buffer, nread, length, out evt);
                if (bytes_read <= 0)
                {
                    break;
                }

                nread += bytes_read;

                InotifyMask mask         = evt.Mask;
                bool        is_directory = (mask & InotifyMask.Directory) != 0;
                mask = (mask & Interesting);                 // Clear out all the bits that we don't need
                if (mask == 0)
                {
                    continue;
                }

                foreach (InotifyData data in GetEnumerator(requests [evt.WatchDescriptor]))
                {
                    if (data == null || data.Enabled == false)
                    {
                        continue;
                    }

                    string directory = data.Directory;
                    string filename  = evt.Name;
                    if (filename == null)
                    {
                        filename = directory;
                    }

                    FileSystemWatcher fsw    = data.FSW;
                    FileAction        action = 0;
                    if ((mask & (InotifyMask.Modify | InotifyMask.CloseWrite | InotifyMask.Attrib)) != 0)
                    {
                        action = FileAction.Modified;
                    }
                    else if ((mask & InotifyMask.Create) != 0)
                    {
                        action = FileAction.Added;
                    }
                    else if ((mask & InotifyMask.Delete) != 0)
                    {
                        action = FileAction.Removed;
                    }
                    else if ((mask & InotifyMask.DeleteSelf) != 0)
                    {
                        action = FileAction.Removed;
                    }
                    else if ((mask & InotifyMask.MoveSelf) != 0)
                    {
                        //action = FileAction.Removed;
                        continue;                         // Ignore this one
                    }
                    else if ((mask & InotifyMask.MovedFrom) != 0)
                    {
                        InotifyEvent to;
                        int          i = ReadEvent(buffer, nread, length, out to);
                        if (i == -1 || (to.Mask & InotifyMask.MovedTo) == 0)
                        {
                            action = FileAction.Removed;
                        }
                        else
                        {
                            nread += i;
                            action = FileAction.RenamedNewName;
                            if (evt.Name == data.Directory || fsw.Pattern.IsMatch(evt.Name))
                            {
                                renamed = new RenamedEventArgs(WatcherChangeTypes.Renamed, data.Directory, to.Name, evt.Name);
                            }
                            else
                            {
                                renamed  = new RenamedEventArgs(WatcherChangeTypes.Renamed, data.Directory, evt.Name, to.Name);
                                filename = to.Name;
                            }
                        }
                    }
                    else if ((mask & InotifyMask.MovedTo) != 0)
                    {
                        action          = (new_name_needed) ? FileAction.RenamedNewName : FileAction.Added;
                        new_name_needed = false;
                    }

                    if (fsw.IncludeSubdirectories)
                    {
                        string full    = fsw.FullPath;
                        string datadir = data.Directory;
                        if (datadir != full)
                        {
                            int len   = full.Length;
                            int slash = 1;
                            if (len > 1 && full [len - 1] == Path.DirectorySeparatorChar)
                            {
                                slash = 0;
                            }
                            string reldir = datadir.Substring(full.Length + slash);
                            datadir  = Path.Combine(datadir, filename);
                            filename = Path.Combine(reldir, filename);
                        }
                        else
                        {
                            datadir = Path.Combine(full, filename);
                        }

                        if (action == FileAction.Added && is_directory)
                        {
                            if (newdirs == null)
                            {
                                newdirs = new ArrayList(4);
                            }

                            InotifyData fd = new InotifyData();
                            fd.FSW            = fsw;
                            fd.Directory      = datadir;
                            fd.FileMask       = fsw.MangledFilter;
                            fd.IncludeSubdirs = true;
                            fd.SubDirs        = new Hashtable();
                            fd.Enabled        = true;
                            newdirs.Add(fd);
                            newdirs.Add(data);
                        }
                    }

                    if (filename != data.Directory && !fsw.Pattern.IsMatch(filename))
                    {
                        continue;
                    }

                    lock (fsw) {
                        fsw.DispatchEvents(action, filename, ref renamed);
                        if (action == FileAction.RenamedNewName)
                        {
                            renamed = null;
                        }
                        if (fsw.Waiting)
                        {
                            fsw.Waiting = false;
                            System.Threading.Monitor.PulseAll(fsw);
                        }
                    }
                }
            }

            if (newdirs != null)
            {
                int count = newdirs.Count;
                for (int n = 0; n < count; n += 2)
                {
                    InotifyData newdir = (InotifyData)newdirs [n];
                    InotifyData parent = (InotifyData)newdirs [n + 1];
                    try {
                        StartMonitoringDirectory(newdir, true);
                        AppendRequestData(newdir);
                        lock (parent) {
                            parent.SubDirs [newdir.Directory] = newdir;
                        }
                    } catch {}                     // ignore the given directory
                }
                newdirs.Clear();
            }
        }
예제 #24
0
		public void StartDispatching (FileSystemWatcher fsw)
		{
			ParentInotifyData parent;
			lock (this) {
				if ((long) FD == -1)
					FD = GetInotifyInstance ();

				if (thread == null) {
					thread = new Thread (new ThreadStart (Monitor));
					thread.IsBackground = true;
					thread.Start ();
				}

				parent = (ParentInotifyData) watches [fsw];
			}

			if (parent == null) {
				InotifyData data = new InotifyData ();
				data.FSW = fsw;
				data.Directory = fsw.FullPath;

				parent = new ParentInotifyData();
				parent.IncludeSubdirs = fsw.IncludeSubdirectories;
				parent.Enabled = true;
				parent.children = new ArrayList();
				parent.data = data;

				watches [fsw] = parent;

				try {
					StartMonitoringDirectory (data, false);
					lock (this) {
						AppendRequestData (data);
						stop = false;
					}
				} catch {} // ignore the directory if StartMonitoringDirectory fails.
			}
		}