aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbuild2/algorithm.cxx3
-rw-r--r--libbuild2/cc/guess.cxx2
-rw-r--r--libbuild2/cc/types.cxx15
-rw-r--r--libbuild2/dist/operation.cxx2
-rw-r--r--libbuild2/file.cxx20
-rw-r--r--libbuild2/filesystem.cxx2
-rw-r--r--libbuild2/functions-filesystem.cxx30
-rw-r--r--libbuild2/parser.cxx15
-rw-r--r--libbuild2/script/run.cxx3
-rw-r--r--libbuild2/target.cxx24
10 files changed, 99 insertions, 17 deletions
diff --git a/libbuild2/algorithm.cxx b/libbuild2/algorithm.cxx
index cc48a38..597ab6c 100644
--- a/libbuild2/algorithm.cxx
+++ b/libbuild2/algorithm.cxx
@@ -1821,8 +1821,7 @@ namespace build2
try_mkdir (to);
- for (const auto& de:
- dir_iterator (fr, false /* ignore_dangling */))
+ for (const auto& de: dir_iterator (fr, dir_iterator::no_follow))
{
path f (fr / de.path ());
path t (to / de.path ());
diff --git a/libbuild2/cc/guess.cxx b/libbuild2/cc/guess.cxx
index 2a6ae67..c7aef7b 100644
--- a/libbuild2/cc/guess.cxx
+++ b/libbuild2/cc/guess.cxx
@@ -761,7 +761,7 @@ namespace build2
//
for (const dir_entry& de:
dir_iterator (r.psdk_dir / dir_path ("Include"),
- false /* ignore_dangling */))
+ dir_iterator::no_follow))
{
if (de.type () == entry_type::directory)
{
diff --git a/libbuild2/cc/types.cxx b/libbuild2/cc/types.cxx
index 8ee4fa9..c6cfae9 100644
--- a/libbuild2/cc/types.cxx
+++ b/libbuild2/cc/types.cxx
@@ -6,6 +6,7 @@
#include <libbuild2/cc/utility.hxx>
using namespace std;
+using namespace butl;
namespace build2
{
@@ -123,6 +124,8 @@ namespace build2
size_t importable_headers::
insert_angle_pattern (const dir_paths& sys_hdr_dirs, const string& pat)
{
+ tracer trace ("importable_headers::insert_angle_pattern");
+
assert (pat.front () == '<' && pat.back () == '>' && path_pattern (pat));
// First see if it has already been inserted.
@@ -172,7 +175,17 @@ namespace build2
try
{
- path_search (f, process, dir);
+ path_search (
+ f,
+ process,
+ dir,
+ path_match_flags::follow_symlinks,
+ [&trace] (const dir_entry& de)
+ {
+ l5 ([&]{trace << "skipping inaccessible/dangling entry "
+ << de.base () / de.path ();});
+ return true;
+ });
}
catch (const system_error& e)
{
diff --git a/libbuild2/dist/operation.cxx b/libbuild2/dist/operation.cxx
index af7b40b..0a75afe 100644
--- a/libbuild2/dist/operation.cxx
+++ b/libbuild2/dist/operation.cxx
@@ -152,7 +152,7 @@ namespace build2
try
{
- for (const dir_entry& e: dir_iterator (d, false /* ignore_dangling */))
+ for (const dir_entry& e: dir_iterator (d, dir_iterator::no_follow))
{
const path& n (e.path ());
diff --git a/libbuild2/file.cxx b/libbuild2/file.cxx
index 03dea5f..bf50a25 100644
--- a/libbuild2/file.cxx
+++ b/libbuild2/file.cxx
@@ -358,7 +358,7 @@ namespace build2
//
try
{
- for (const dir_entry& de: dir_iterator (d, false /* ignore_dangling */))
+ for (const dir_entry& de: dir_iterator (d, dir_iterator::no_follow))
{
// If this is a link, then type() will try to stat() it. And if the
// link is dangling or points to something inaccessible, it will fail.
@@ -847,10 +847,26 @@ namespace build2
try
{
- for (const dir_entry& de: dir_iterator (d, true /* ignore_dangling */))
+ // It's probably possible that a subproject can be a symlink with the
+ // link target, for example, being in a git submodule. Considering that,
+ // it makes sense to warn about dangling symlinks.
+ //
+ for (const dir_entry& de:
+ dir_iterator (d, dir_iterator::detect_dangling))
{
if (de.type () != entry_type::directory)
+ {
+ if (de.type () == entry_type::unknown)
+ {
+ bool sl (de.ltype () == entry_type::symlink);
+
+ warn << "skipping "
+ << (sl ? "dangling symlink" : "inaccessible entry") << ' '
+ << d / de.path ();
+ }
+
continue;
+ }
dir_path sd (d / path_cast<dir_path> (de.path ()));
diff --git a/libbuild2/filesystem.cxx b/libbuild2/filesystem.cxx
index 196d9bd..f340dd7 100644
--- a/libbuild2/filesystem.cxx
+++ b/libbuild2/filesystem.cxx
@@ -291,7 +291,7 @@ namespace build2
{
try
{
- for (const dir_entry& de: dir_iterator (d, false /* ignore_dangling */))
+ for (const dir_entry& de: dir_iterator (d, dir_iterator::no_follow))
{
// The .buildignore filesystem entry should be of the regular file
// type.
diff --git a/libbuild2/functions-filesystem.cxx b/libbuild2/functions-filesystem.cxx
index ef7bfc5..1acb3d1 100644
--- a/libbuild2/functions-filesystem.cxx
+++ b/libbuild2/functions-filesystem.cxx
@@ -7,6 +7,7 @@
#include <libbuild2/variable.hxx>
using namespace std;
+using namespace butl;
namespace build2
{
@@ -29,12 +30,27 @@ namespace build2
return true;
};
+ auto dangling = [] (const dir_entry& de)
+ {
+ bool sl (de.ltype () == entry_type::symlink);
+
+ warn << "skipping "
+ << (sl ? "dangling symlink" : "inaccessible entry") << ' '
+ << de.base () / de.path ();
+
+ return true;
+ };
+
// Print paths "as is" in the diagnostics.
//
try
{
if (pattern.absolute ())
- path_search (pattern, add);
+ path_search (pattern,
+ add,
+ dir_path () /* start */,
+ path_match_flags::follow_symlinks,
+ dangling);
else
{
// An absolute start directory must be specified for the relative
@@ -54,7 +70,11 @@ namespace build2
<< "' is relative";
}
- path_search (pattern, add, *start);
+ path_search (pattern,
+ add,
+ *start,
+ path_match_flags::follow_symlinks,
+ dangling);
}
}
catch (const system_error& e)
@@ -83,7 +103,7 @@ namespace build2
function_family f (m, "filesystem");
- // path_search
+ // $path_search(<pattern> [, <start-dir>])
//
// Return filesystem paths that match the pattern. If the pattern is an
// absolute path, then the start directory is ignored (if present).
@@ -91,6 +111,9 @@ namespace build2
//
// Note that this function is not pure.
//
+ // @@ In the future we may want to add a flag that controls the
+ // dangling/inaccessible treatment.
+ //
{
auto e (f.insert ("path_search", false));
@@ -115,6 +138,5 @@ namespace build2
convert<dir_path> (move (start)));
};
}
-
}
}
diff --git a/libbuild2/parser.cxx b/libbuild2/parser.cxx
index 13a3b12..dd2944d 100644
--- a/libbuild2/parser.cxx
+++ b/libbuild2/parser.cxx
@@ -6042,7 +6042,20 @@ namespace build2
try
{
- path_search (path (move (p)), process, *sp);
+ path_search (path (move (p)),
+ process,
+ *sp,
+ path_match_flags::follow_symlinks,
+ [] (const dir_entry& de)
+ {
+ bool sl (de.ltype () == entry_type::symlink);
+
+ warn << "skipping "
+ << (sl ? "dangling symlink" : "inaccessible entry")
+ << ' ' << de.base () / de.path ();
+
+ return true;
+ });
}
catch (const system_error& e)
{
diff --git a/libbuild2/script/run.cxx b/libbuild2/script/run.cxx
index f486138..6f5934e 100644
--- a/libbuild2/script/run.cxx
+++ b/libbuild2/script/run.cxx
@@ -3353,8 +3353,7 @@ namespace build2
try
{
size_t n (0);
- for (const dir_entry& de: dir_iterator (p,
- false /* ignore_dangling */))
+ for (const dir_entry& de: dir_iterator (p, dir_iterator::no_follow))
{
if (n++ < 10)
dr << '\n' << (de.ltype () == entry_type::directory
diff --git a/libbuild2/target.cxx b/libbuild2/target.cxx
index 76d45c7..16aec49 100644
--- a/libbuild2/target.cxx
+++ b/libbuild2/target.cxx
@@ -1253,7 +1253,7 @@ namespace build2
{
try
{
- for (const dir_entry& e: dir_iterator (d, true /* ignore_dangling */))
+ for (const dir_entry& e: dir_iterator (d, dir_iterator::detect_dangling))
{
switch (e.type ())
{
@@ -1271,6 +1271,16 @@ namespace build2
break;
}
+ case entry_type::unknown:
+ {
+ bool sl (e.ltype () == entry_type::symlink);
+
+ warn << "skipping "
+ << (sl ? "dangling symlink" : "inaccessible entry") << ' '
+ << d / e.path ();
+
+ break;
+ }
default:
break;
}
@@ -1292,9 +1302,10 @@ namespace build2
try
{
- for (const dir_entry& e: dir_iterator (d, true /* ignore_dangling */))
+ for (const dir_entry& e: dir_iterator (d, dir_iterator::detect_dangling))
{
if (e.type () == entry_type::directory)
+ {
r.push_back (
prerequisite (nullopt,
dir::static_type,
@@ -1303,6 +1314,15 @@ namespace build2
string (),
nullopt,
bs));
+ }
+ else if (e.type () == entry_type::unknown)
+ {
+ bool sl (e.ltype () == entry_type::symlink);
+
+ warn << "skipping "
+ << (sl ? "dangling symlink" : "inaccessible entry") << ' '
+ << d / e.path ();
+ }
}
}
catch (const system_error& e)