コード例 #1
0
            internal unsafe RunningInstance(
                FileSystemWatcher watcher,
                string directory,
                bool includeChildren,
                FSEventStreamEventFlags filter)
            {
                Debug.Assert(!string.IsNullOrEmpty(directory));

                // Make sure _fullPath doesn't contain a link or alias since the OS will give back the actual,
                // non link'd or alias'd paths.
                _fullDirectory = System.IO.Path.GetFullPath(directory);
                _fullDirectory = Interop.Sys.RealPath(_fullDirectory);
                if (_fullDirectory is null)
                {
                    throw Interop.GetExceptionForIoErrno(Interop.Sys.GetLastErrorInfo(), _fullDirectory, isDirectory: true);
                }

                // Also ensure it has a trailing slash.
                if (!_fullDirectory.EndsWith('/'))
                {
                    _fullDirectory += "/";
                }

                _callback        = new Interop.EventStream.FSEventStreamCallback(FileSystemEventCallback);
                _weakWatcher     = new WeakReference <FileSystemWatcher>(watcher);
                _includeChildren = includeChildren;
                _filterFlags     = filter;
            }
コード例 #2
0
        private static Interop.EventStream.FSEventStreamEventFlags TranslateFlags(NotifyFilters flagsToTranslate)
        {
            Interop.EventStream.FSEventStreamEventFlags flags = 0;

            // Always re-create the filter flags when start is called since they could have changed
            if ((flagsToTranslate & (NotifyFilters.Attributes | NotifyFilters.CreationTime | NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.Size)) != 0)
            {
                flags = Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemInodeMetaMod |
                        Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemFinderInfoMod |
                        Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemModified |
                        Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemChangeOwner;
            }
            if ((flagsToTranslate & NotifyFilters.Security) != 0)
            {
                flags |= Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemChangeOwner | Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemXattrMod;
            }
            if ((flagsToTranslate & NotifyFilters.DirectoryName) != 0)
            {
                flags |= Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemIsDir |
                         Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemIsSymlink |
                         Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemCreated |
                         Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemRemoved |
                         Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemRenamed;
            }
            if ((flagsToTranslate & NotifyFilters.FileName) != 0)
            {
                flags |= Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemIsFile |
                         Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemIsSymlink |
                         Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemCreated |
                         Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemRemoved |
                         Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemRenamed;
            }

            return(flags);
        }
コード例 #3
0
            /// <summary>
            /// Compares the given event flags to the filter flags and returns which event (if any) corresponds
            /// to those flags.
            /// </summary>
            private WatcherChangeTypes FilterEvents(Interop.EventStream.FSEventStreamEventFlags eventFlags, string fullPath)
            {
                const Interop.EventStream.FSEventStreamEventFlags changedFlags = Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemInodeMetaMod |
                                                                                 Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemFinderInfoMod |
                                                                                 Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemModified |
                                                                                 Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemChangeOwner |
                                                                                 Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemXattrMod;

                // If any of the Changed flags are set in both Filter and Event then a Changed event has occurred.
                if (((_filterFlags & changedFlags) & (eventFlags & changedFlags)) > 0)
                {
                    return(WatcherChangeTypes.Changed);
                }

                // Disallow event coalescing. OSX likes to add a Created event to everything, particularly Changed events.
                if ((eventFlags & changedFlags) > 0)
                {
                    return(0);
                }

                // Notify created/deleted/renamed events if they pass through the filters
                bool allowDirs          = (_filterFlags & Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemIsDir) > 0;
                bool allowFiles         = (_filterFlags & Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemIsFile) > 0;
                bool isDir              = (eventFlags & Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemIsDir) > 0;
                bool isFile             = (eventFlags & Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemIsFile) > 0;
                bool eventIsCorrectType = (isDir && allowDirs) || (isFile && allowFiles);
                bool eventIsLink        = (eventFlags & (Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemIsHardlink | Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemIsSymlink | Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemIsLastHardlink)) > 0;

                if (eventIsCorrectType || ((allowDirs || allowFiles) && (eventIsLink)))
                {
                    // Notify Renamed events.
                    if (IsFlagSet(eventFlags, Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemRenamed))
                    {
                        return(WatcherChangeTypes.Renamed);
                    }
                    else
                    {
                        // Notify Created/Deleted events.
                        if ((IsFlagSet(eventFlags, Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemCreated)) &&
                            (IsFlagSet(eventFlags, Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemRemoved)))
                        {
                            // OS X is wonky where it can give back kFSEventStreamEventFlagItemCreated and kFSEventStreamEventFlagItemRemoved
                            // for the same item. The only option we have is to stat and see if the item exists; if so send created, otherwise send deleted.
                            WatcherChangeTypes wct = DoesItemExist(fullPath, IsFlagSet(eventFlags, Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemIsFile)) ?
                                                     WatcherChangeTypes.Created :
                                                     WatcherChangeTypes.Deleted;
                            return(wct);
                        }
                        else if (IsFlagSet(eventFlags, Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemCreated))
                        {
                            return(WatcherChangeTypes.Created);
                        }
                        else if (IsFlagSet(eventFlags, Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemRemoved))
                        {
                            return(WatcherChangeTypes.Deleted);
                        }
                    }
                }
                return(0);
            }
コード例 #4
0
 private bool ShouldRescanOccur(Interop.EventStream.FSEventStreamEventFlags flags)
 {
     // Check if any bit is set that signals that the caller should rescan
     return(IsFlagSet(flags, Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagMustScanSubDirs) ||
            IsFlagSet(flags, Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagUserDropped) ||
            IsFlagSet(flags, Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagKernelDropped) ||
            IsFlagSet(flags, Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagRootChanged) ||
            IsFlagSet(flags, Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagMount) ||
            IsFlagSet(flags, Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagUnmount));
 }
コード例 #5
0
            internal RunningInstance(
                FileSystemWatcher watcher,
                string directory,
                bool includeChildren,
                Interop.EventStream.FSEventStreamEventFlags filter,
                CancellationToken cancelToken)
            {
                Debug.Assert(string.IsNullOrEmpty(directory) == false);
                Debug.Assert(!cancelToken.IsCancellationRequested);

                _weakWatcher       = new WeakReference <FileSystemWatcher>(watcher);
                _fullDirectory     = System.IO.Path.GetFullPath(directory);
                _includeChildren   = includeChildren;
                _filterFlags       = filter;
                _cancellationToken = cancelToken;
                _cancellationToken.Register(obj => ((RunningInstance)obj).CancellationCallback(), this);
                _stopping = false;
            }
コード例 #6
0
            /// <summary>
            /// Compares the given event flags to the filter flags and returns which event (if any) corresponds
            /// to those flags.
            /// </summary>
            private WatcherChangeTypes FilterEvents(Interop.EventStream.FSEventStreamEventFlags eventFlags, string fullPath)
            {
                const Interop.EventStream.FSEventStreamEventFlags changedFlags = Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemInodeMetaMod |
                                                                                 Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemFinderInfoMod |
                                                                                 Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemModified |
                                                                                 Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemChangeOwner |
                                                                                 Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemXattrMod;
                WatcherChangeTypes eventType = 0;

                // If any of the Changed flags are set in both Filter and Event then a Changed event has occurred.
                if (((_filterFlags & changedFlags) & (eventFlags & changedFlags)) > 0)
                {
                    eventType |= WatcherChangeTypes.Changed;
                }

                // Notify created/deleted/renamed events if they pass through the filters
                bool allowDirs          = (_filterFlags & Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemIsDir) > 0;
                bool allowFiles         = (_filterFlags & Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemIsFile) > 0;
                bool isDir              = (eventFlags & Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemIsDir) > 0;
                bool isFile             = (eventFlags & Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemIsFile) > 0;
                bool eventIsCorrectType = (isDir && allowDirs) || (isFile && allowFiles);
                bool eventIsLink        = (eventFlags & (Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemIsHardlink | Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemIsSymlink | Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemIsLastHardlink)) > 0;

                if (eventIsCorrectType || ((allowDirs || allowFiles) && (eventIsLink)))
                {
                    // Notify Created/Deleted/Renamed events.
                    if (IsFlagSet(eventFlags, Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemRenamed))
                    {
                        eventType |= WatcherChangeTypes.Renamed;
                    }
                    if (IsFlagSet(eventFlags, Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemCreated))
                    {
                        eventType |= WatcherChangeTypes.Created;
                    }
                    if (IsFlagSet(eventFlags, Interop.EventStream.FSEventStreamEventFlags.kFSEventStreamEventFlagItemRemoved))
                    {
                        eventType |= WatcherChangeTypes.Deleted;
                    }
                }
                return(eventType);
            }
コード例 #7
0
 private static bool IsFlagSet(Interop.EventStream.FSEventStreamEventFlags flags, Interop.EventStream.FSEventStreamEventFlags value)
 {
     return((value & flags) == value);
 }
コード例 #8
0
 private static bool IsFlagSet(FSEventStreamEventFlags flags, FSEventStreamEventFlags value)
 {
     return((value & flags) == value);
 }