Exemplo n.º 1
0
 private static Microsoft.Win32.SafeHandles.SafeDirectoryHandle OpenDirectory(string fullPath)
 {
     Microsoft.Win32.SafeHandles.SafeDirectoryHandle handle = Interop.Sys.OpenDir(fullPath);
     if (handle.IsInvalid)
     {
         throw Interop.GetExceptionForIoErrno(Interop.Sys.GetLastErrorInfo(), fullPath, isDirectory: true);
     }
     return(handle);
 }
Exemplo n.º 2
0
            private IEnumerator <T> Enumerate(Microsoft.Win32.SafeHandles.SafeDirectoryHandle dirHandle)
            {
                if (dirHandle == null)
                {
                    // Empty search
                    yield break;
                }

                Debug.Assert(!dirHandle.IsInvalid);
                Debug.Assert(!dirHandle.IsClosed);

                // Maintain a stack of the directories to explore, in the case of SearchOption.AllDirectories
                // Lazily-initialized only if we find subdirectories that will be explored.
                Stack <PathPair> toExplore = null;
                PathPair         dirPath   = _initialDirectory;

                while (dirHandle != null)
                {
                    try
                    {
                        // Read each entry from the enumerator
                        Interop.Sys.DirectoryEntry dirent;
                        while (Interop.Sys.ReadDir(dirHandle, out dirent) == 0)
                        {
                            // Get from the dir entry whether the entry is a file or directory.
                            // We classify everything as a file unless we know it to be a directory.
                            bool isDir;
                            if (dirent.InodeType == Interop.Sys.NodeType.DT_DIR)
                            {
                                // We know it's a directory.
                                isDir = true;
                            }
                            else if (dirent.InodeType == Interop.Sys.NodeType.DT_LNK || dirent.InodeType == Interop.Sys.NodeType.DT_UNKNOWN)
                            {
                                // It's a symlink or unknown: stat to it to see if we can resolve it to a directory.
                                // If we can't (e.g. symlink to a file, broken symlink, etc.), we'll just treat it as a file.
                                Interop.ErrorInfo errnoIgnored;
                                isDir = DirectoryExists(Path.Combine(dirPath.FullPath, dirent.InodeName), out errnoIgnored);
                            }
                            else
                            {
                                // Otherwise, treat it as a file.  This includes regular files, FIFOs, etc.
                                isDir = false;
                            }

                            // Yield the result if the user has asked for it.  In the case of directories,
                            // always explore it by pushing it onto the stack, regardless of whether
                            // we're returning directories.
                            if (isDir)
                            {
                                if (!ShouldIgnoreDirectory(dirent.InodeName))
                                {
                                    string userPath = null;
                                    if (_searchOption == SearchOption.AllDirectories)
                                    {
                                        if (toExplore == null)
                                        {
                                            toExplore = new Stack <PathPair>();
                                        }
                                        userPath = Path.Combine(dirPath.UserPath, dirent.InodeName);
                                        toExplore.Push(new PathPair(userPath, Path.Combine(dirPath.FullPath, dirent.InodeName)));
                                    }
                                    if (_includeDirectories &&
                                        Interop.Sys.FnMatch(_searchPattern, dirent.InodeName, Interop.Sys.FnMatchFlags.FNM_NONE) == 0)
                                    {
                                        yield return(_translateResult(userPath ?? Path.Combine(dirPath.UserPath, dirent.InodeName), /*isDirectory*/ true));
                                    }
                                }
                            }
                            else if (_includeFiles &&
                                     Interop.Sys.FnMatch(_searchPattern, dirent.InodeName, Interop.Sys.FnMatchFlags.FNM_NONE) == 0)
                            {
                                yield return(_translateResult(Path.Combine(dirPath.UserPath, dirent.InodeName), /*isDirectory*/ false));
                            }
                        }
                    }
                    finally
                    {
                        // Close the directory enumerator
                        dirHandle.Dispose();
                        dirHandle = null;
                    }

                    if (toExplore != null && toExplore.Count > 0)
                    {
                        // Open the next directory.
                        dirPath   = toExplore.Pop();
                        dirHandle = OpenDirectory(dirPath.FullPath);
                    }
                }
            }