aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-02-15 06:54:17 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-02-15 06:54:17 +0200
commit97779063df86fa8451c62c97139411ad78f75012 (patch)
treeff5cd340c4b7c06689e199c133d89c0abe130759
parent568aab7f19cc9bbb42c7fb4afef541a79459d657 (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.cxx94
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;
}