From 97779063df86fa8451c62c97139411ad78f75012 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 15 Feb 2016 06:54:17 +0200 Subject: Catch system_error thrown by dir_exists() in install For example, we can get EACCES because we don't have permissions for some of the leading components. Of course, if we have sudo, then that may not be the case if we actually tried 'install -d' on it. So this will probably have to be revised at some point. --- build2/install/rule.cxx | 94 ++++++++++++++++++++++++++----------------------- 1 file changed, 50 insertions(+), 44 deletions(-) (limited to 'build2') diff --git a/build2/install/rule.cxx b/build2/install/rule.cxx index ae78981..e8184b9 100644 --- a/build2/install/rule.cxx +++ b/build2/install/rule.cxx @@ -328,58 +328,64 @@ namespace build2 { install_dir r; - if (d.absolute ()) - d.normalize (); - else + try { - // If it is relative, then the first component is treated - // as the installation directory name, e.g., bin, sbin, lib, - // etc. Look it up and recurse. - // - const string& sn (*d.begin ()); - const string var ("install." + sn); - if (const dir_path* dn = lookup (s, var)) + if (d.absolute ()) + r.dir = move (d.normalize ()); + else { - r = resolve (s, *dn, &var); - d = r.dir / dir_path (++d.begin (), d.end ()); - d.normalize (); - - if (!dir_exists (d)) - install (r, d); // install -d + // If it is relative, then the first component is treated + // as the installation directory name, e.g., bin, sbin, lib, + // etc. Look it up and recurse. + // + const string& sn (*d.begin ()); + const string var ("install." + sn); + if (const dir_path* dn = lookup (s, var)) + { + r = resolve (s, *dn, &var); + d = r.dir / dir_path (++d.begin (), d.end ()); + r.dir = move (d.normalize ()); + + if (!dir_exists (r.dir)) // May throw (e.g., EACCES). + install (r, r.dir); // install -d + } + else + fail << "unknown installation directory name " << sn << + info << "did you forget to specify config." << var << "?"; } - else - fail << "unknown installation directory name " << sn << - info << "did you forget to specify config." << var << "?"; - } - r.dir = move (d); + // Override components in install_dir if we have our own. + // + if (var != nullptr) + { + if (auto l = s[*var + ".sudo"]) r.sudo = as (*l); + if (auto l = s[*var + ".cmd"]) r.cmd = as (*l); + if (auto l = s[*var + ".mode"]) r.mode = as (*l); + if (auto l = s[*var + ".dir_mode"]) r.dir_mode = as (*l); + if (auto l = s[*var + ".options"]) r.options = as (*l); + } - // Override components in install_dir if we have our own. - // - if (var != nullptr) + // Set defaults for unspecified components. + // + if (r.cmd.empty ()) r.cmd = "install"; + if (r.mode.empty ()) r.mode = "644"; + if (r.dir_mode.empty ()) r.dir_mode = "755"; + + // If the directory still doesn't exist, then this means it was specified + // as absolute (it will normally be install.root with everything else + // defined in term of it). We used to fail in this case but that proved + // to be just too anal. So now we just create it. + // + if (!dir_exists (r.dir)) // May throw (e.g., EACCES). + // fail << "installation directory " << d << " does not exist"; + install (r, r.dir); // install -d + } + catch (const system_error& e) { - if (auto l = s[*var + ".sudo"]) r.sudo = as (*l); - if (auto l = s[*var + ".cmd"]) r.cmd = as (*l); - if (auto l = s[*var + ".mode"]) r.mode = as (*l); - if (auto l = s[*var + ".dir_mode"]) r.dir_mode = as (*l); - if (auto l = s[*var + ".options"]) r.options = as (*l); + fail << "invalid installation directory " << r.dir << ": " + << e.what (); } - // Set defaults for unspecified components. - // - if (r.cmd.empty ()) r.cmd = "install"; - if (r.mode.empty ()) r.mode = "644"; - if (r.dir_mode.empty ()) r.dir_mode = "755"; - - // If the directory still doesn't exist, then this means it was specified - // as absolute (it will normally be install.root with everything else - // defined in term of it). We used to fail in this case but that proved - // to be just too anal. So now we just create it. - // - if (!dir_exists (r.dir)) - install (r, r.dir); // install -d - // fail << "installation directory " << d << " does not exist"; - return r; } -- cgit v1.1