From dc1b424b75f200a716c3bd9b91891cf7f818ad32 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Fri, 9 Sep 2016 18:29:37 +0300 Subject: Fix crashing on unhandled system_error thrown by file_exists() --- build2/b.cxx | 4 ++-- build2/cc/link.cxx | 1 + build2/cc/pkgconfig.cxx | 8 ++++---- build2/cc/windows-manifest.cxx | 2 +- build2/cc/windows-rpath.cxx | 4 ++-- build2/config/init.cxx | 4 ++-- build2/dist/operation.cxx | 8 ++++---- build2/file.cxx | 17 ++++++++--------- build2/filesystem | 9 +++++++++ build2/filesystem.cxx | 30 +++++++++++++++++++++++++++++- build2/install/rule.cxx | 2 ++ build2/rule.cxx | 2 +- 12 files changed, 65 insertions(+), 26 deletions(-) diff --git a/build2/b.cxx b/build2/b.cxx index 6d6723a..8031559 100644 --- a/build2/b.cxx +++ b/build2/b.cxx @@ -437,7 +437,7 @@ main (int argc, char* argv[]) // if it doesn't, the diagnostics could be confusing (e.g., // unknown operation because we don't load bootstrap.build). // - if (!dir_exists (src_base)) + if (!exists (src_base)) fail << "src_base directory " << src_base << " does not exist"; if (src_base.relative ()) @@ -841,7 +841,7 @@ main (int argc, char* argv[]) // If we were guessing src_base, check that the buildfile // exists and if not, issue more detailed diagnostics. // - if (guessing && bf.string () != "-" && !file_exists (bf)) + if (guessing && bf.string () != "-" && !exists (bf)) fail << bf << " does not exist" << info << "consider explicitly specifying src_base " << "for " << tn; diff --git a/build2/cc/link.cxx b/build2/cc/link.cxx index 9a8e21c..d36e5e1 100644 --- a/build2/cc/link.cxx +++ b/build2/cc/link.cxx @@ -9,6 +9,7 @@ #include // cerr #include +#include // file_exists() #include #include diff --git a/build2/cc/pkgconfig.cxx b/build2/cc/pkgconfig.cxx index 23128e4..3a7bf82 100644 --- a/build2/cc/pkgconfig.cxx +++ b/build2/cc/pkgconfig.cxx @@ -63,7 +63,7 @@ namespace build2 // dir_path pkgd (dir_path (libd) /= dir); - if (!dir_exists (pkgd)) + if (!exists (pkgd)) return false; // See if there is a corresponding .pc file. About half of them called @@ -82,7 +82,7 @@ namespace build2 f /= stem; f += ".pc"; - if (file_exists (f)) + if (exists (f)) return true; f = pkgd; @@ -90,7 +90,7 @@ namespace build2 f += stem; f += ".pc"; - if (file_exists (f)) + if (exists (f)) return true; if (proj != nullptr) @@ -99,7 +99,7 @@ namespace build2 f /= *proj; f += ".pc"; - if (file_exists (f)) + if (exists (f)) return true; } diff --git a/build2/cc/windows-manifest.cxx b/build2/cc/windows-manifest.cxx index 0666ef5..a3e87fe 100644 --- a/build2/cc/windows-manifest.cxx +++ b/build2/cc/windows-manifest.cxx @@ -99,7 +99,7 @@ namespace build2 // path mf (t.path () + ".manifest"); - if (file_exists (mf)) + if (exists (mf)) { try { diff --git a/build2/cc/windows-rpath.cxx b/build2/cc/windows-rpath.cxx index e27dddb..1bef95c 100644 --- a/build2/cc/windows-rpath.cxx +++ b/build2/cc/windows-rpath.cxx @@ -157,14 +157,14 @@ namespace build2 pdb = f; pdb += ".pdb"; - if (!file_exists (pdb.c_str ())) + if (!exists (path (pdb))) { // Then try the usual naming: foo.pdb. // pdb.assign (f, 0, p); pdb += ".pdb"; - if (!file_exists (pdb.c_str ())) + if (!exists (path (pdb))) pdb.clear (); } diff --git a/build2/config/init.cxx b/build2/config/init.cxx index a5cdf5a..4fdb318 100644 --- a/build2/config/init.cxx +++ b/build2/config/init.cxx @@ -8,7 +8,7 @@ #include #include #include -#include // file_exists() +#include // exists() #include #include @@ -55,7 +55,7 @@ namespace build2 { path f (out_root / config_file); - if (file_exists (f)) + if (exists (f)) { // Check the config version. We assume that old versions cannot // understand new configs and new versions are incompatible with old diff --git a/build2/dist/operation.cxx b/build2/dist/operation.cxx index 4628350..b5ca906 100644 --- a/build2/dist/operation.cxx +++ b/build2/dist/operation.cxx @@ -84,7 +84,7 @@ namespace build2 const dir_path& dist_root (cast (l)); - if (!dir_exists (dist_root)) + if (!exists (dist_root)) fail << "root distribution directory " << dist_root << " does not exist"; @@ -146,7 +146,7 @@ namespace build2 auto add_adhoc = [&trace] (scope& rs, const path& f) { path p (rs.src_path () / f); - if (file_exists (p)) + if (exists (p)) { dir_path d (p.directory ()); @@ -282,7 +282,7 @@ namespace build2 ? t.dir.leaf (src_root) : t.dir.leaf (out_root); - if (!dir_exists (d)) + if (!exists (d)) install (dist_cmd, d); install (dist_cmd, t, d); @@ -413,7 +413,7 @@ namespace build2 // Delete old archive for good measure. // path ap (dir / path (a)); - if (file_exists (ap, false)) + if (exists (ap, false)) rmfile (ap); // Use zip for .zip archives. Everything else goes to tar in the diff --git a/build2/file.cxx b/build2/file.cxx index bf1c4d8..0040fd4 100644 --- a/build2/file.cxx +++ b/build2/file.cxx @@ -6,10 +6,9 @@ #include // cin -#include // file_exists() - #include #include +#include // exists() #include #include @@ -43,13 +42,13 @@ namespace build2 { // @@ Can we have root without bootstrap? I don't think so. // - return file_exists (d / bootstrap_file) || file_exists (d / root_file); + return exists (d / bootstrap_file) || exists (d / root_file); } bool is_out_root (const dir_path& d) { - return file_exists (d / src_root_file); + return exists (d / src_root_file); } dir_path @@ -257,7 +256,7 @@ namespace build2 { path bf (root.out_path () / src_root_file); - if (!file_exists (bf)) + if (!exists (bf)) return; //@@ TODO: if bootstrap files can source other bootstrap files @@ -335,7 +334,7 @@ namespace build2 { path f (out_root / src_root_file); - if (!fallback_src_root.empty () && !file_exists (f)) + if (!fallback_src_root.empty () && !exists (f)) src_root = &fallback_src_root; else { @@ -462,7 +461,7 @@ namespace build2 path bf (src_root / bootstrap_file); - if (file_exists (bf)) + if (exists (bf)) { // We assume that bootstrap out cannot load this file explicitly. It // feels wrong to allow this since that makes the whole bootstrap @@ -575,7 +574,7 @@ namespace build2 // subprojects sps; - if (dir_exists (out_root)) + if (exists (out_root)) { l5 ([&]{trace << "looking for subprojects in " << out_root;}); find_subprojects (sps, out_root, out_root, true); @@ -814,7 +813,7 @@ namespace build2 // path bf (root.src_path () / root_file); - if (file_exists (bf)) + if (exists (bf)) source_once (bf, root, root); } diff --git a/build2/filesystem b/build2/filesystem index 1dcf8bd..1b03c0e 100644 --- a/build2/filesystem +++ b/build2/filesystem @@ -82,6 +82,15 @@ namespace build2 // fs_status rmdir_r (const dir_path&, bool dir = true, uint16_t verbosity = 1); + + // Check for a file or directory existence. Print the diagnostics and fail on + // system error. + // + bool + exists (const path&, bool follow_symlinks = true); + + bool + exists (const dir_path&); } #include diff --git a/build2/filesystem.cxx b/build2/filesystem.cxx index 44b0ba4..c9696dc 100644 --- a/build2/filesystem.cxx +++ b/build2/filesystem.cxx @@ -79,7 +79,7 @@ namespace build2 if (work.sub (d)) // Don't try to remove working directory. return rmdir_status::not_empty; - if (!dir_exists (d)) + if (!exists (d)) return rmdir_status::not_exist; if (verb >= v) @@ -96,4 +96,32 @@ namespace build2 return rmdir_status::success; } + + bool + exists (const path& f, bool fs) + { + try + { + return file_exists (f, fs); + } + catch (const system_error& e) + { + error << "unable to stat path " << f << ": " << e.what (); + throw failed (); + } + } + + bool + exists (const dir_path& d) + { + try + { + return dir_exists (d); + } + catch (const system_error& e) + { + error << "unable to stat path " << d << ": " << e.what (); + throw failed (); + } + } } diff --git a/build2/install/rule.cxx b/build2/install/rule.cxx index f3a9bf4..038b53c 100644 --- a/build2/install/rule.cxx +++ b/build2/install/rule.cxx @@ -4,6 +4,8 @@ #include +#include // dir_exists(), file_exists() + #include #include #include diff --git a/build2/rule.cxx b/build2/rule.cxx index 0fcfde2..58340b5 100644 --- a/build2/rule.cxx +++ b/build2/rule.cxx @@ -208,7 +208,7 @@ namespace build2 // going to get better performance by first checking if it indeed // exists. See try_mkdir() for details. // - if (!dir_exists (d)) + if (!exists (d)) { if (verb >= 2) text << "mkdir " << d; -- cgit v1.1