From 8e4adf000fd7f16aa3d4a28f2a4f2e1d6801b382 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Sun, 24 Mar 2019 21:36:50 +0100 Subject: [PATCH] Make the DirEntry->FileInfo conversion nothrow. Avoids listDirectory/iterateDirectory getting interrupted when stumbling over inaccessible files. The `name` field of the returned file info value is always set, so that these files can still be identified. --- source/vibe/core/file.d | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/source/vibe/core/file.d b/source/vibe/core/file.d index 3bd9baf..192a9c0 100644 --- a/source/vibe/core/file.d +++ b/source/vibe/core/file.d @@ -729,22 +729,33 @@ struct DirectoryChange { private FileInfo makeFileInfo(DirEntry ent) -@trusted { +@trusted nothrow { + import std.algorithm.comparison : among; + FileInfo ret; - auto fullname = ent.name.endsWith('/') || ent.name.endsWith('\\') ? ent.name[0 .. $-1] : ent.name; + if (!ent.name.length) return ret; + + auto fullname = ent.name[$-1].among('/', '\\') ? ent.name[0 .. $-1] : ent.name; ret.name = baseName(fullname); if (ret.name.length == 0) ret.name = fullname; - ret.size = ent.size; - ret.timeModified = ent.timeLastModified; - version(Windows) ret.timeCreated = ent.timeCreated; - else ret.timeCreated = ent.timeLastModified; - ret.isSymlink = ent.isSymlink; - ret.isDirectory = ent.isDir; - ret.isFile = ent.isFile; + + try { + ret.isFile = ent.isFile; + ret.isDirectory = ent.isDir; + ret.isSymlink = ent.isSymlink; + ret.timeModified = ent.timeLastModified; + version(Windows) ret.timeCreated = ent.timeCreated; + else ret.timeCreated = ent.timeLastModified; + ret.size = ent.size; + } catch (Exception e) { + logDebug("Failed to get information for file '%s': %s", fullname, e.msg); + } + version (Windows) { import core.sys.windows.windows : FILE_ATTRIBUTE_HIDDEN; ret.hidden = (ent.attributes & FILE_ATTRIBUTE_HIDDEN) != 0; } - else ret.hidden = ret.name.startsWith('.'); + else ret.hidden = ret.name[0] == '.' && ret.name != "." && ret.name != ".."; + return ret; }