Exemple #1
0
		void Setup ()
		{	
			var initialFds = new List<int> ();

			// fsw.FullPath may end in '/', see https://bugzilla.xamarin.com/show_bug.cgi?id=5747
			if (fsw.FullPath != "/" && fsw.FullPath.EndsWith ("/", StringComparison.Ordinal))
				fullPathNoLastSlash = fsw.FullPath.Substring (0, fsw.FullPath.Length - 1);
			else
				fullPathNoLastSlash = fsw.FullPath;
				
			// GetFilenameFromFd() returns the *realpath* which can be different than fsw.FullPath because symlinks.
			// If so, introduce a fixup step.
			int fd = open (fullPathNoLastSlash, O_EVTONLY, 0);
			var resolvedFullPath = GetFilenameFromFd (fd);
			close (fd);

			if (resolvedFullPath != fullPathNoLastSlash)
				fixupPath = resolvedFullPath;
			else
				fixupPath = null;

			Scan (fullPathNoLastSlash, false, ref initialFds);

			var immediate_timeout = new timespec { tv_sec = (IntPtr)0, tv_usec = (IntPtr)0 };
			var eventBuffer = new kevent[0]; // we don't want to take any events from the queue at this point
			var changes = CreateChangeList (ref initialFds);

			int numEvents = kevent (conn, changes, changes.Length, eventBuffer, eventBuffer.Length, ref immediate_timeout);

			if (numEvents == -1) {
				var errMsg = String.Format ("kevent() error at initial event registration, error code = '{0}'", Marshal.GetLastWin32Error ());
				throw new IOException (errMsg);
			}
		}
Exemple #2
0
 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;
     }
 }
Exemple #3
0
        void Monitor()
        {
            while (!stop)
            {
                kevent ev = new kevent();
                ev.udata = IntPtr.Zero;
                kevent nullev = new kevent();
                nullev.udata = IntPtr.Zero;
                timespec ts = new timespec();
                ts.tv_sec  = 0;
                ts.tv_usec = 0;
                int haveEvents;
                lock (this) {
                    haveEvents = kevent(conn, ref nullev, 0, ref ev, 1, ref ts);
                }

                if (haveEvents > 0)
                {
                    // Restart monitoring
                    KeventData data = (KeventData)requests [ev.ident];
                    StopMonitoringDirectory(data);
                    StartMonitoringDirectory(data);
                    ProcessEvent(ev);
                }
                else
                {
                    System.Threading.Thread.Sleep(500);
                }
            }

            lock (this) {
                thread = null;
                stop   = false;
            }
        }
Exemple #4
0
 private void Monitor()
 {
     while (!stop)
     {
         kevent evtlist = default(kevent);
         evtlist.udata = IntPtr.Zero;
         kevent ev = default(kevent);
         ev.udata = IntPtr.Zero;
         timespec ts = default(timespec);
         ts.tv_sec  = 0;
         ts.tv_usec = 0;
         int num;
         lock (this)
         {
             num = kevent(conn, ref ev, 0, ref evtlist, 1, ref ts);
         }
         if (num > 0)
         {
             KeventData data = (KeventData)requests[evtlist.ident];
             StopMonitoringDirectory(data);
             StartMonitoringDirectory(data);
             ProcessEvent(evtlist);
         }
         else
         {
             Thread.Sleep(500);
         }
     }
     lock (this)
     {
         thread = null;
         stop   = false;
     }
 }
Exemple #5
0
        void Setup()
        {
            var initialFds = new List <int> ();

            // fsw.FullPath may end in '/', see https://bugzilla.xamarin.com/show_bug.cgi?id=5747
            if (fsw.FullPath != "/" && fsw.FullPath.EndsWith("/", StringComparison.Ordinal))
            {
                fullPathNoLastSlash = fsw.FullPath.Substring(0, fsw.FullPath.Length - 1);
            }
            else
            {
                fullPathNoLastSlash = fsw.FullPath;
            }

            // realpath() returns the *realpath* which can be different than fsw.FullPath because symlinks.
            // If so, introduce a fixup step.
            var sb = new StringBuilder(__DARWIN_MAXPATHLEN);

            if (realpath(fsw.FullPath, sb) == IntPtr.Zero)
            {
                var errMsg = String.Format("realpath({0}) failed, error code = '{1}'", fsw.FullPath, Marshal.GetLastWin32Error());
                throw new IOException(errMsg);
            }
            var resolvedFullPath = sb.ToString();

            if (resolvedFullPath != fullPathNoLastSlash)
            {
                fixupPath = resolvedFullPath;
            }
            else
            {
                fixupPath = null;
            }

            Scan(fullPathNoLastSlash, false, ref initialFds);

            var immediate_timeout = new timespec {
                tv_sec = (IntPtr)0, tv_nsec = (IntPtr)0
            };
            var eventBuffer = new kevent[0];             // we don't want to take any events from the queue at this point
            var changes     = CreateChangeList(ref initialFds);

            int numEvents;
            int errno = 0;

            do
            {
                numEvents = kevent(conn, changes, changes.Length, eventBuffer, eventBuffer.Length, ref immediate_timeout);
                if (numEvents == -1)
                {
                    errno = Marshal.GetLastWin32Error();
                }
            } while (numEvents == -1 && errno == EINTR);

            if (numEvents == -1)
            {
                var errMsg = String.Format("kevent() error at initial event registration, error code = '{0}'", errno);
                throw new IOException(errMsg);
            }
        }
Exemple #6
0
        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;
            }
        }
Exemple #7
0
        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;
            }
        }
Exemple #8
0
        private static void StartMonitoringDirectory(KeventData data)
        {
            DirectoryInfo directoryInfo = new DirectoryInfo(data.Directory);

            if (data.DirEntries == null)
            {
                data.DirEntries = new Hashtable();
                FileSystemInfo[] fileSystemInfos = directoryInfo.GetFileSystemInfos();
                foreach (FileSystemInfo fileSystemInfo in fileSystemInfos)
                {
                    data.DirEntries.Add(fileSystemInfo.FullName, new KeventFileData(fileSystemInfo, fileSystemInfo.LastAccessTime, fileSystemInfo.LastWriteTime));
                }
            }
            int    num = open(data.Directory, 0, 0);
            kevent ev  = default(kevent);

            ev.udata = IntPtr.Zero;
            timespec ts = default(timespec);

            ts.tv_sec  = 0;
            ts.tv_usec = 0;
            if (num > 0)
            {
                ev.ident  = num;
                ev.filter = -4;
                ev.flags  = 21;
                ev.fflags = 31u;
                ev.data   = 0;
                ev.udata  = Marshal.StringToHGlobalAuto(data.Directory);
                kevent evtlist = default(kevent);
                evtlist.udata = IntPtr.Zero;
                kevent(conn, ref ev, 1, ref evtlist, 0, ref ts);
                data.ev       = ev;
                requests[num] = data;
            }
            if (data.IncludeSubdirs)
            {
            }
        }
Exemple #9
0
        void Setup()
        {
            var initialFds = new List <int> ();

            // GetFilenameFromFd() returns the *realpath* which can be different than fsw.FullPath because symlinks.
            // If so, introduce a fixup step.
            int fd = open(fsw.FullPath, O_EVTONLY, 0);
            var resolvedFullPath = GetFilenameFromFd(fd);

            close(fd);

            if (resolvedFullPath != fsw.FullPath)
            {
                fixupPath = resolvedFullPath;
            }
            else
            {
                fixupPath = null;
            }

            Scan(fsw.FullPath, false, ref initialFds);

            var immediate_timeout = new timespec {
                tv_sec = (IntPtr)0, tv_usec = (IntPtr)0
            };
            var eventBuffer = new kevent[0];             // we don't want to take any events from the queue at this point
            var changes     = CreateChangeList(ref initialFds);

            int numEvents = kevent(conn, changes, changes.Length, eventBuffer, eventBuffer.Length, ref immediate_timeout);

            if (numEvents == -1)
            {
                var errMsg = String.Format("kevent() error at initial event registration, error code = '{0}'", Marshal.GetLastWin32Error());
                throw new IOException(errMsg);
            }
        }
Exemple #10
0
		void Setup ()
		{	
			var initialFds = new List<int> ();

			// fsw.FullPath may end in '/', see https://bugzilla.xamarin.com/show_bug.cgi?id=5747
			if (fsw.FullPath != "/" && fsw.FullPath.EndsWith ("/", StringComparison.Ordinal))
				fullPathNoLastSlash = fsw.FullPath.Substring (0, fsw.FullPath.Length - 1);
			else
				fullPathNoLastSlash = fsw.FullPath;
				
			// realpath() returns the *realpath* which can be different than fsw.FullPath because symlinks.
			// If so, introduce a fixup step.
			var sb = new StringBuilder (__DARWIN_MAXPATHLEN);
			if (realpath(fsw.FullPath, sb) == IntPtr.Zero) {
				var errMsg = String.Format ("realpath({0}) failed, error code = '{1}'", fsw.FullPath, Marshal.GetLastWin32Error ());
				throw new IOException (errMsg);
			}
			var resolvedFullPath = sb.ToString();

			if (resolvedFullPath != fullPathNoLastSlash)
				fixupPath = resolvedFullPath;
			else
				fixupPath = null;

			Scan (fullPathNoLastSlash, false, ref initialFds);

			var immediate_timeout = new timespec { tv_sec = (IntPtr)0, tv_nsec = (IntPtr)0 };
			var eventBuffer = new kevent[0]; // we don't want to take any events from the queue at this point
			var changes = CreateChangeList (ref initialFds);

			int numEvents;
			int errno = 0;
			do {
				numEvents = kevent (conn, changes, changes.Length, eventBuffer, eventBuffer.Length, ref immediate_timeout);
				if (numEvents == -1) {
					errno = Marshal.GetLastWin32Error ();
				}
			} while (numEvents == -1 && errno == EINTR);

			if (numEvents == -1) {
				var errMsg = String.Format ("kevent() error at initial event registration, error code = '{0}'", errno);
				throw new IOException (errMsg);
			}
		}
Exemple #11
0
		extern static int kevent(int kqueue, ref kevent ev, int nchanges, ref kevent evtlist,  int nevents, ref timespec ts);
Exemple #12
0
		void Monitor ()
		{
		
			while (!stop) {
				kevent ev = new kevent();
				ev.udata = IntPtr.Zero;
				kevent nullev = new kevent();
				nullev.udata = IntPtr.Zero;
				timespec ts = new timespec();
				ts.tv_sec = 0;
				ts.tv_usec = 0;
				int haveEvents;
				lock (this) {
					haveEvents = kevent (conn, ref nullev, 0, ref ev, 1, ref ts);
				}

				if (haveEvents > 0) {
					// Restart monitoring
					KeventData data = (KeventData) requests [ev.ident];
					StopMonitoringDirectory (data);
					StartMonitoringDirectory (data);
					ProcessEvent (ev);
				} else {
					System.Threading.Thread.Sleep (500);
				}
			}

			lock (this) {
				thread = null;
				stop = false;
			}
		}
Exemple #13
0
		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;

		}
Exemple #14
0
		void Setup ()
		{	
			var initialFds = new List<int> ();

			// fsw.FullPath may end in '/', see https://bugzilla.xamarin.com/show_bug.cgi?id=5747
			if (fsw.FullPath != "/" && fsw.FullPath.EndsWith ("/", StringComparison.Ordinal))
				fullPathNoLastSlash = fsw.FullPath.Substring (0, fsw.FullPath.Length - 1);
			else
				fullPathNoLastSlash = fsw.FullPath;
				
			// GetFilenameFromFd() returns the *realpath* which can be different than fsw.FullPath because symlinks.
			// If so, introduce a fixup step.
			int fd = open (fullPathNoLastSlash, O_EVTONLY, 0);
			var resolvedFullPath = GetFilenameFromFd (fd);
			close (fd);

			if (resolvedFullPath != fullPathNoLastSlash)
				fixupPath = resolvedFullPath;
			else
				fixupPath = null;

			Scan (fullPathNoLastSlash, false, ref initialFds);

			var immediate_timeout = new timespec { tv_sec = (IntPtr)0, tv_nsec = (IntPtr)0 };
			var eventBuffer = new kevent[0]; // we don't want to take any events from the queue at this point
			var changes = CreateChangeList (ref initialFds);

			int numEvents = kevent (conn, changes, changes.Length, eventBuffer, eventBuffer.Length, ref immediate_timeout);

			if (numEvents == -1) {
				var errMsg = String.Format ("kevent() error at initial event registration, error code = '{0}'", Marshal.GetLastWin32Error ());
				throw new IOException (errMsg);
			}
		}
Exemple #15
0
		void Monitor ()
		{
			var timeout = new timespec { tv_sec = (IntPtr)0, tv_usec = (IntPtr)500000000 };
			var eventBuffer = new kevent[32];
			var newFds = new List<int> ();
			List<PathData> removeQueue = new List<PathData> ();
			List<string> rescanQueue = new List<string> ();

			int retries = 0; 

			while (!requestStop) {
				var changes = CreateChangeList (ref newFds);

				int numEvents = kevent (conn, changes, changes.Length, eventBuffer, eventBuffer.Length, ref timeout);

				if (numEvents == -1) {
					if (++retries == 3)
						throw new IOException (String.Format (
							"persistent kevent() error, error code = '{0}'", Marshal.GetLastWin32Error ()));

					continue;
				}

				retries = 0;

				for (var i = 0; i < numEvents; i++) {
					var kevt = eventBuffer [i];
					var pathData = fdsDict [(int)kevt.ident];

					if ((kevt.flags & EventFlags.Error) == EventFlags.Error) {
						var errMsg = String.Format ("kevent() error watching path '{0}', error code = '{1}'", pathData.Path, kevt.data);
						fsw.DispatchErrorEvents (new ErrorEventArgs (new IOException (errMsg)));
						continue;
					}
						
					if ((kevt.fflags & FilterFlags.VNodeDelete) == FilterFlags.VNodeDelete || (kevt.fflags & FilterFlags.VNodeRevoke) == FilterFlags.VNodeRevoke) {
						removeQueue.Add (pathData);
						continue;
					}

					if ((kevt.fflags & FilterFlags.VNodeRename) == FilterFlags.VNodeRename) {
							UpdatePath (pathData);
					} 

					if ((kevt.fflags & FilterFlags.VNodeWrite) == FilterFlags.VNodeWrite) {
						if (pathData.IsDirectory) //TODO: Check if dirs trigger Changed events on .NET
							rescanQueue.Add (pathData.Path);
						else
							PostEvent (FileAction.Modified, pathData.Path);
					}
						
					if ((kevt.fflags & FilterFlags.VNodeAttrib) == FilterFlags.VNodeAttrib || (kevt.fflags & FilterFlags.VNodeExtend) == FilterFlags.VNodeExtend)
						PostEvent (FileAction.Modified, pathData.Path);
				}

				removeQueue.ForEach (Remove);
				removeQueue.Clear ();

				rescanQueue.ForEach (path => {
					Scan (path, true, ref newFds);
				});
				rescanQueue.Clear ();
			}
		}
Exemple #16
0
		void Monitor ()
		{
			var timeout = new timespec { tv_sec = (IntPtr)0, tv_usec = (IntPtr)500000000 };
			var eventBuffer = new kevent[32];
			var newFds = new List<int> ();
			List<PathData> removeQueue = new List<PathData> ();
			List<string> rescanQueue = new List<string> ();

			while (!requestStop) {
				var changes = CreateChangeList (ref newFds);

				int numEvents = kevent (conn, changes, changes.Length, eventBuffer, eventBuffer.Length, ref timeout);

				if (numEvents == -1) {
					var errMsg = String.Format ("kevent() error, error code = '{0}'", Marshal.GetLastWin32Error ());
					fsw.OnError (new ErrorEventArgs (new IOException (errMsg)));
				}

				if (numEvents == 0)
					continue;

				for (var i = 0; i < numEvents; i++) {
					var kevt = eventBuffer [i];
					var pathData = fdsDict [(int)kevt.ident];

					if ((kevt.flags & EventFlags.Error) == EventFlags.Error) {
						var errMsg = String.Format ("kevent() error watching path '{0}', error code = '{1}'", pathData.Path, kevt.data);
						fsw.OnError (new ErrorEventArgs (new IOException (errMsg)));
						continue;
					}

					if ((kevt.fflags & FilterFlags.VNodeDelete) == FilterFlags.VNodeDelete || (kevt.fflags & FilterFlags.VNodeRevoke) == FilterFlags.VNodeRevoke)
						removeQueue.Add (pathData);

					else if ((kevt.fflags & FilterFlags.VNodeWrite) == FilterFlags.VNodeWrite) {
						if (pathData.IsDirectory)
							rescanQueue.Add (pathData.Path);
						else
							PostEvent (FileAction.Modified, pathData.Path);
					} 

					else if ((kevt.fflags & FilterFlags.VNodeRename) == FilterFlags.VNodeRename) {
						var newFilename = GetFilenameFromFd (pathData.Fd);

						if (newFilename.StartsWith (fsw.FullPath))
							Rename (pathData, newFilename);
						else //moved outside of our watched dir so stop watching
								RemoveTree (pathData);
					} 

					else if ((kevt.fflags & FilterFlags.VNodeAttrib) == FilterFlags.VNodeAttrib || (kevt.fflags & FilterFlags.VNodeExtend) == FilterFlags.VNodeExtend)
						PostEvent (FileAction.Modified, pathData.Path);
				}

				removeQueue.ForEach (Remove);
				removeQueue.Clear ();

				rescanQueue.ForEach (path => {
					Scan (path, true, ref newFds);
				});
				rescanQueue.Clear ();
			}
		}
Exemple #17
0
		void Setup ()
		{	
			var initialFds = new List<int> ();

			// GetFilenameFromFd() returns the *realpath* which can be different than fsw.FullPath because symlinks.
			// If so, introduce a fixup step.
			int fd = open (fsw.FullPath, O_EVTONLY, 0);
			var resolvedFullPath = GetFilenameFromFd (fd);
			close (fd);

			if (resolvedFullPath != fsw.FullPath)
				fixupPath = resolvedFullPath;
			else
				fixupPath = null;

			Scan (fsw.FullPath, false, ref initialFds);

			var immediate_timeout = new timespec { tv_sec = (IntPtr)0, tv_usec = (IntPtr)0 };
			var eventBuffer = new kevent[0]; // we don't want to take any events from the queue at this point
			var changes = CreateChangeList (ref initialFds);

			int numEvents = kevent (conn, changes, changes.Length, eventBuffer, eventBuffer.Length, ref immediate_timeout);

			if (numEvents == -1) {
				var errMsg = String.Format ("kevent() error at initial event registration, error code = '{0}'", Marshal.GetLastWin32Error ());
				throw new IOException (errMsg);
			}
		}
Exemple #18
0
        void Monitor()
        {
            var timeout = new timespec {
                tv_sec = (IntPtr)0, tv_usec = (IntPtr)500000000
            };
            var             eventBuffer = new kevent[32];
            var             newFds      = new List <int> ();
            List <PathData> removeQueue = new List <PathData> ();
            List <string>   rescanQueue = new List <string> ();

            int retries = 0;

            while (!requestStop)
            {
                var changes = CreateChangeList(ref newFds);

                int numEvents = kevent(conn, changes, changes.Length, eventBuffer, eventBuffer.Length, ref timeout);

                if (numEvents == -1)
                {
                    if (++retries == 3)
                    {
                        throw new IOException(String.Format(
                                                  "persistent kevent() error, error code = '{0}'", Marshal.GetLastWin32Error()));
                    }

                    continue;
                }

                retries = 0;

                for (var i = 0; i < numEvents; i++)
                {
                    var kevt     = eventBuffer [i];
                    var pathData = fdsDict [(int)kevt.ident];

                    if ((kevt.flags & EventFlags.Error) == EventFlags.Error)
                    {
                        var errMsg = String.Format("kevent() error watching path '{0}', error code = '{1}'", pathData.Path, kevt.data);
                        fsw.DispatchErrorEvents(new ErrorEventArgs(new IOException(errMsg)));
                        continue;
                    }

                    if ((kevt.fflags & FilterFlags.VNodeDelete) == FilterFlags.VNodeDelete || (kevt.fflags & FilterFlags.VNodeRevoke) == FilterFlags.VNodeRevoke)
                    {
                        removeQueue.Add(pathData);
                        continue;
                    }

                    if ((kevt.fflags & FilterFlags.VNodeRename) == FilterFlags.VNodeRename)
                    {
                        UpdatePath(pathData);
                    }

                    if ((kevt.fflags & FilterFlags.VNodeWrite) == FilterFlags.VNodeWrite)
                    {
                        if (pathData.IsDirectory)                         //TODO: Check if dirs trigger Changed events on .NET
                        {
                            rescanQueue.Add(pathData.Path);
                        }
                        else
                        {
                            PostEvent(FileAction.Modified, pathData.Path);
                        }
                    }

                    if ((kevt.fflags & FilterFlags.VNodeAttrib) == FilterFlags.VNodeAttrib || (kevt.fflags & FilterFlags.VNodeExtend) == FilterFlags.VNodeExtend)
                    {
                        PostEvent(FileAction.Modified, pathData.Path);
                    }
                }

                removeQueue.ForEach(Remove);
                removeQueue.Clear();

                rescanQueue.ForEach(path => {
                    Scan(path, true, ref newFds);
                });
                rescanQueue.Clear();
            }
        }
Exemple #19
0
 extern static int kevent(int kqueue, ref kevent ev, int nchanges, ref kevent evtlist, int nevents, ref timespec ts);
Exemple #20
0
        void Monitor()
        {
            var timeout = new timespec {
                tv_sec = (IntPtr)0, tv_usec = (IntPtr)500000000
            };
            var             eventBuffer = new kevent[32];
            var             newFds      = new List <int> ();
            List <PathData> removeQueue = new List <PathData> ();
            List <string>   rescanQueue = new List <string> ();

            while (!requestStop)
            {
                var changes = CreateChangeList(ref newFds);

                int numEvents = kevent(conn, changes, changes.Length, eventBuffer, eventBuffer.Length, ref timeout);

                if (numEvents == -1)
                {
                    var errMsg = String.Format("kevent() error, error code = '{0}'", Marshal.GetLastWin32Error());
                    fsw.OnError(new ErrorEventArgs(new IOException(errMsg)));
                }

                if (numEvents == 0)
                {
                    continue;
                }

                for (var i = 0; i < numEvents; i++)
                {
                    var kevt     = eventBuffer [i];
                    var pathData = fdsDict [(int)kevt.ident];

                    if ((kevt.flags & EventFlags.Error) == EventFlags.Error)
                    {
                        var errMsg = String.Format("kevent() error watching path '{0}', error code = '{1}'", pathData.Path, kevt.data);
                        fsw.OnError(new ErrorEventArgs(new IOException(errMsg)));
                        continue;
                    }

                    if ((kevt.fflags & FilterFlags.VNodeDelete) == FilterFlags.VNodeDelete || (kevt.fflags & FilterFlags.VNodeRevoke) == FilterFlags.VNodeRevoke)
                    {
                        removeQueue.Add(pathData);
                    }

                    else if ((kevt.fflags & FilterFlags.VNodeWrite) == FilterFlags.VNodeWrite)
                    {
                        if (pathData.IsDirectory)
                        {
                            rescanQueue.Add(pathData.Path);
                        }
                        else
                        {
                            PostEvent(FileAction.Modified, pathData.Path);
                        }
                    }

                    else if ((kevt.fflags & FilterFlags.VNodeRename) == FilterFlags.VNodeRename)
                    {
                        var newFilename = GetFilenameFromFd(pathData.Fd);

                        if (newFilename.StartsWith(fsw.FullPath))
                        {
                            Rename(pathData, newFilename);
                        }
                        else                         //moved outside of our watched dir so stop watching
                        {
                            RemoveTree(pathData);
                        }
                    }

                    else if ((kevt.fflags & FilterFlags.VNodeAttrib) == FilterFlags.VNodeAttrib || (kevt.fflags & FilterFlags.VNodeExtend) == FilterFlags.VNodeExtend)
                    {
                        PostEvent(FileAction.Modified, pathData.Path);
                    }
                }

                removeQueue.ForEach(Remove);
                removeQueue.Clear();

                rescanQueue.ForEach(path => {
                    Scan(path, true, ref newFds);
                });
                rescanQueue.Clear();
            }
        }
Exemple #21
0
		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;

		}
Exemple #22
0
 static int kevent(int kqueue, ref kevent ev, int nchanges, ref kevent evtlist, int nevents, ref timespec ts)
 {
     throw new System.NotImplementedException();
 }
Exemple #23
0
 extern static int kevent(int kq, [In] kevent[] ev, int nchanges, [Out] kevent[] evtlist, int nevents, [In] ref timespec time);
		static int kevent(int kqueue, ref kevent ev, int nchanges, ref kevent evtlist,  int nevents, ref timespec ts)
		{
			throw new System.NotImplementedException();
		}