www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - dirEntries() and exceptions

reply doc <wagn3r ya.ru> writes:
I'm trying recursively find files, and have some trouble to catch 
exceptions if have no permission to read directory.

[code]
void main() {
import std.file,std.stdio;
auto farray = dirEntries("/tmp", "*.{d,py,pl,sh}", 
SpanMode.breadth);
foreach (f; farray){writeln(f);}}
[/code]

std.file.FileException std/file.d(3798): 
/tmp/systemd-private-8338348a306b4d589e3f6ba2bfd0c8fe-systemd-times
ncd.service-3374MK: Permission denied
----------------
??:?  safe core.sys.posix.dirent.DIR* 
std.file.cenforce!(core.sys.posix.dirent.DIR*).cenforce(core.sy
.posix.dirent.DIR*, lazy const(char)[], immutable(char)[], ulong) [0xd31f7ce7]
??:? bool std.file.DirIteratorImpl.stepIn(immutable(char)[]) 
[0xd31f7119]
??:? void std.file.DirIteratorImpl.popFront() [0xd31f7641]
??:? void std.file.DirIterator.popFront() [0xd31f78dc]
??:? _Dmain [0xd31f1ff2]
============================================================================

Example structure /tmp

.
├── 374e60aa-296f-4499-9d12-36626a105069
├── 6787feed-013f-4907-bf86-b18a5a7c966f
├── dub_platform_probe-0d2aed9d-4a4f-4da3-a9fe-af705fb4914c.d
├── dub_platform_probe-3e5246ea-7158-4184-865e-8f15ec149b6f.d
├── dub_platform_probe-724ee4cf-bdc9-4137-b25a-4893323922ac.d
├── dub_platform_probe-9a0c98e4-3077-460c-9309-b8066be1b353.d
├── dub_platform_probe-be30fcdc-3eb2-4a0c-88bd-49a8507eb48b.d
├── dub_platform_probe-dc6d01e2-4f5d-4e71-adde-70131b8a0587.d
├── dub_platform_probe-dcd282e3-1b9c-486a-84ee-5eee5c60790f.d
├── dub_platform_probe-e2dfd83f-5f21-401c-a450-20bf5e73a678.d
├── ls
├── ls.d
├── ls.o
├── 
systemd-private-8338348a306b4d589e3f6ba2bfd0c8fe-systemd-time
yncd.service-3374MK [error opening dir]
├── vscode-e6da53a1363a02042f56966c5464593959886044.sock

drwx------ 3 root root    60 ноя 24 08:32  
systemd-private-8338348a306b4d589e3f6ba2bfd0c8fe-systemd-timesyncd.service-3374MK

This dir have permission 0700, only root can read in this dir. 
Also, in /tmp I'm create at root a new dir /tmp/www with 0700 
perm. But my program has exit when exception on 
/tmp/systed-private... and can't write any messages when can't 
read /tmp/www.

So, how I can skip any exceptions and continue program?

[code]
void main() {
import std.stdio, std.file;

try {
auto farray = dirEntries("/tmp", "*.{d,py,ph,sh}", 
SpanMode.breadth);
foreach (f; farray) {
writeln(f);
}
catch (FileException e) {
writeln(e.msg);
}
}
[/code]

This not work, after writeln(e.msg); program is exit.
Nov 24
parent rjframe <dlang ryanjframe.com> writes:
On Fri, 24 Nov 2017 12:02:47 +0000, doc wrote:

 I'm trying recursively find files, and have some trouble to catch
 exceptions if have no permission to read directory.
 
...
 
 std.file.FileException std/file.d(3798):
 /tmp/systemd-private-8338348a306b4d589e3f6ba2bfd0c8fe-systemd-
timesyncd.service-3374MK:
 Permission denied ----------------
 
 [code]
 void main() {
 import std.stdio, std.file;
 
 try {
 auto farray = dirEntries("/tmp", "*.{d,py,ph,sh}",
 SpanMode.breadth);
 foreach (f; farray) {
 writeln(f);
 }
 catch (FileException e) {
 writeln(e.msg);
 }
 }
 [/code]
 
 This not work, after writeln(e.msg); program is exit.
The exception for dirEntries was reported as a bug here[1]; there is a workaround listed on that page that silently skips directories it can't read, but you'll need to modify it a bit to maintain a breadth search. As to why your code stops after catching the exception, the try/catch block does not place you back in the block that threw the exception, but drops you off in the outer scope. You would need to place the code in some sort of loop to run until all input was consumed in order continue past the exception. [1]: https://issues.dlang.org/show_bug.cgi?id=12391
Nov 24