diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2016-02-15 06:54:17 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2016-02-15 06:54:17 +0200 |
commit | 97779063df86fa8451c62c97139411ad78f75012 (patch) | |
tree | ff5cd340c4b7c06689e199c133d89c0abe130759 | |
parent | 568aab7f19cc9bbb42c7fb4afef541a79459d657 (diff) |
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.
-rw-r--r-- | build2/install/rule.cxx | 94 |
1 files changed, 50 insertions, 44 deletions
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<string> (*l); + if (auto l = s[*var + ".cmd"]) r.cmd = as<string> (*l); + if (auto l = s[*var + ".mode"]) r.mode = as<string> (*l); + if (auto l = s[*var + ".dir_mode"]) r.dir_mode = as<string> (*l); + if (auto l = s[*var + ".options"]) r.options = as<strings> (*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<string> (*l); - if (auto l = s[*var + ".cmd"]) r.cmd = as<string> (*l); - if (auto l = s[*var + ".mode"]) r.mode = as<string> (*l); - if (auto l = s[*var + ".dir_mode"]) r.dir_mode = as<string> (*l); - if (auto l = s[*var + ".options"]) r.options = as<strings> (*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; } |