--- dir.m.12.08.beta.2012.12.04	2012-01-03 15:04:48.000000000 +0400
+++ dir.m	2012-12-06 22:34:43.411414500 +0400
@@ -220,6 +220,15 @@
     string::in, bool::in, T::in, io.maybe_partial_res(T)::out,
     io::di, io::uo) is det.
 
+    %
+:- pred dir.foldl2_skip(dir.foldl_pred(T)::in(dir.foldl_pred), string::in,
+    T::in, io.maybe_partial_res(T)::out, io::di, io::uo) is det.
+
+    %
+:- pred dir.recursive_foldl2_skip(dir.foldl_pred(T)::in(dir.foldl_pred),
+    string::in, bool::in, T::in, io.maybe_partial_res(T)::out,
+    io::di, io::uo) is det.
+
 %-----------------------------------------------------------------------------%
 
     % Implement brace expansion, as in sh: return the sequence of strings
@@ -1289,11 +1298,19 @@ dir.check_dir_accessibility(DirName, Res
 
 dir.foldl2(P, DirName, T, Res, !IO) :-
     dir.foldl2_process_dir(no, P, fixup_dirname(DirName), [], no,
-        no, _, T, Res, !IO).
+        no, no, _, T, Res, !IO).
 
 dir.recursive_foldl2(P, DirName, FollowLinks, T, Res, !IO) :-
     dir.foldl2_process_dir(no, P, fixup_dirname(DirName), [], yes,
-        FollowLinks, _, T, Res, !IO).
+        FollowLinks, no, _, T, Res, !IO).
+
+dir.foldl2_skip(P, DirName, T, Res, !IO) :-
+    dir.foldl2_process_dir(no, P, fixup_dirname(DirName), [], no,
+        no, yes, _, T, Res, !IO).
+
+dir.recursive_foldl2_skip(P, DirName, FollowLinks, T, Res, !IO) :-
+    dir.foldl2_process_dir(no, P, fixup_dirname(DirName), [], yes,
+        FollowLinks, yes, _, T, Res, !IO).
 
     %
     % Under windows you cannot list the files of a directory if the directory
@@ -1315,22 +1332,22 @@ fixup_dirname(Dir0) = Dir :-
 
 :- pred dir.foldl2_process_dir(bool::in,
     dir.foldl_pred(T)::in(dir.foldl_pred), string::in,
-    list(file_id)::in, bool::in, bool::in, bool::out, T::in,
+    list(file_id)::in, bool::in, bool::in, bool::in, bool::out, T::in,
     io.maybe_partial_res(T)::out, io::di, io::uo) is det.
 
 :- pred dir.foldl2_process_dir2(dir.stream::in, dir.stream::out, bool::in,
     dir.foldl_pred(T)::in(dir.foldl_pred), string::in,
-    list(file_id)::in, string::in, bool::in, bool::in, T::in,
+    list(file_id)::in, string::in, bool::in, bool::in, bool::in, T::in,
     {io.maybe_partial_res(T), bool}::out, io::di, io::uo) is det.
 
 dir.foldl2_process_dir2(!Dir, SymLinkParent, P, DirName, ParentIds, FirstEntry,
-        Recursive, FollowLinks, T0, {Res, Cont}, !IO) :-
+        Recursive, FollowLinks, SkipInaccessible, T0, {Res, Cont}, !IO) :-
     dir.foldl2_process_entries(!Dir, SymLinkParent, P, DirName,
-        ok(FirstEntry), ParentIds, Recursive, FollowLinks, Cont,
-        T0, Res, !IO).
+        ok(FirstEntry), ParentIds, Recursive, FollowLinks, SkipInaccessible,
+        Cont, T0, Res, !IO).
 
 dir.foldl2_process_dir(SymLinkParent, P, DirName, ParentIds0, Recursive,
-        FollowLinks, Continue, T0, Result, !IO) :-
+        FollowLinks, SkipInaccessible, Continue, T0, Result, !IO) :-
     ( can_implement_dir_foldl ->
         (
             Recursive = yes,
@@ -1355,7 +1372,8 @@ dir.foldl2_process_dir(SymLinkParent, P,
                             IO0::di, IO::uo) is det :-
                         dir.foldl2_process_dir2(Dir0, Dir1, SymLinkParent,
                             P, DirName, ParentIds, FirstEntry, Recursive,
-                            FollowLinks, T0, {DirRes1, Continue1}, IO0, IO)
+                            FollowLinks, SkipInaccessible, T0, {DirRes1, Continue1},
+                            IO0, IO)
                     ),
                 promise_equivalent_solutions [!:IO, ExcpResult] (
                     exception.try_io(ProcessDir, ExcpResult, !IO)
@@ -1390,8 +1408,15 @@ dir.foldl2_process_dir(SymLinkParent, P,
                 Result = ok(T0)
             ;
                 OpenResult = error(Error),
-                Continue = no,
-                Result = error(T0, Error)
+                (
+                    SkipInaccessible = yes,
+                    Continue = yes,
+                    Result = ok(T0)
+                ;
+                    SkipInaccessible = no,                    
+                    Continue = no,
+                    Result = error(T0, Error)
+                )
             )
         ;
             LoopRes = ok(yes),
@@ -1413,14 +1438,14 @@ dir.foldl2_process_dir(SymLinkParent, P,
 :- pred dir.foldl2_process_entries(dir.stream::in, dir.stream::out, bool::in,
     dir.foldl_pred(T)::in(dir.foldl_pred), string::in,
     io.result(string)::in, list(file_id)::in, bool::in,
-    bool::in, bool::out, T::in, io.maybe_partial_res(T)::out,
+    bool::in, bool::in, bool::out, T::in, io.maybe_partial_res(T)::out,
     io::di, io::uo) is det.
 
-dir.foldl2_process_entries(!Dir, _, _, _, error(Error), _, _, _, no,
+dir.foldl2_process_entries(!Dir, _, _, _, error(Error), _, _, _, _, no,
         T0, error(T0, Error), !IO).
-dir.foldl2_process_entries(!Dir, _, _, _, eof, _, _, _, yes, T0, ok(T0), !IO).
+dir.foldl2_process_entries(!Dir, _, _, _, eof, _, _, _, _, yes, T0, ok(T0), !IO).
 dir.foldl2_process_entries(!Dir, SymLinkParent, P, DirName, ok(FileName),
-        ParentIds, Recursive, FollowLinks, Continue, T0, Res, !IO) :-
+        ParentIds, Recursive, FollowLinks, SkipInaccessible, Continue, T0, Res, !IO) :-
     PathName = DirName/FileName,
     io.file_type(no, PathName, FileTypeRes, !IO),
     (
@@ -1433,7 +1458,8 @@ dir.foldl2_process_entries(!Dir, SymLink
                 Type = directory
             ->
                 dir.foldl2_process_dir(SymLinkParent, P, PathName, ParentIds,
-                    Recursive, FollowLinks, Continue2, T1, Res1, !IO)
+                    Recursive, FollowLinks, SkipInaccessible, Continue2, T1, Res1,
+                    !IO)
             ;
                 Recursive = yes,
                 Type = symbolic_link,
@@ -1445,7 +1471,8 @@ dir.foldl2_process_entries(!Dir, SymLink
                     (
                         TargetType = directory,
                         dir.foldl2_process_dir(yes, P, PathName, ParentIds,
-                            Recursive, FollowLinks, Continue2, T1, Res1, !IO)
+                            Recursive, FollowLinks, SkipInaccessible, Continue2,
+                            T1, Res1, !IO)
                     ;
 
                         ( TargetType = regular_file
@@ -1487,8 +1514,8 @@ dir.foldl2_process_entries(!Dir, SymLink
                     EntryResult = error(Error)
                 ),
                 dir.foldl2_process_entries(!Dir, SymLinkParent, P, DirName,
-                    EntryResult, ParentIds, Recursive, FollowLinks, Continue,
-                    T, Res, !IO)
+                    EntryResult, ParentIds, Recursive, FollowLinks, SkipInaccessible,
+                    Continue, T, Res, !IO)
             ;
                 Continue = no,
                 Res = Res1
@@ -1499,9 +1526,28 @@ dir.foldl2_process_entries(!Dir, SymLink
             Continue = no
         )
     ;
-        FileTypeRes = error(Error),
-        Continue = no,
-        Res = error(T0, Error)
+        FileTypeRes = error(ErrorFT),
+        (
+            SkipInaccessible = yes,
+            dir.read_entry(!.Dir, EntryResult0, !IO),
+            (
+                EntryResult0 = ok({!:Dir, FileName1}),
+                EntryResult = ok(FileName1)
+            ;
+                EntryResult0 = eof,
+                EntryResult = eof
+            ;
+                EntryResult0 = error(Error),
+                EntryResult = error(Error)
+            ),
+            dir.foldl2_process_entries(!Dir, SymLinkParent, P, DirName,
+                EntryResult, ParentIds, Recursive, FollowLinks, SkipInaccessible,
+                Continue, T0, Res, !IO)
+        ;
+            SkipInaccessible = no,
+            Continue = no,
+            Res = error(T0, ErrorFT)
+        )
     ).
 
     % Check whether we've seen this directory before in this branch of the
