aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/build
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2/build')
-rw-r--r--libbuild2/build/script/runner.cxx97
-rw-r--r--libbuild2/build/script/script.cxx4
-rw-r--r--libbuild2/build/script/script.hxx14
3 files changed, 108 insertions, 7 deletions
diff --git a/libbuild2/build/script/runner.cxx b/libbuild2/build/script/runner.cxx
index 5535bbb..c4a93fd 100644
--- a/libbuild2/build/script/runner.cxx
+++ b/libbuild2/build/script/runner.cxx
@@ -3,8 +3,12 @@
#include <libbuild2/build/script/runner.hxx>
+#include <libbutl/filesystem.mxx>
+
#include <libbuild2/script/run.hxx>
+using namespace butl;
+
namespace build2
{
namespace build
@@ -12,15 +16,104 @@ namespace build2
namespace script
{
void default_runner::
- enter (environment&, const location&)
+ enter (environment& env, const location& ll)
{
- // Noop.
+ // Create the temporary directory for this run regardless of the
+ // dry-run mode, since some commands still can be executed (see run()
+ // for details). This also a reason for not using the build2
+ // filesystem API that considers the dry-run mode.
+ //
+ // Note that the directory auto-removal is active.
+ //
+ dir_path& td (env.temp_dir.path);
+
+ try
+ {
+ td = dir_path::temp_path ("build2-build-script");
+ }
+ catch (const system_error& e)
+ {
+ // While there can be no fault of the script being currently
+ // executed let's add the location anyway to ease the
+ // troubleshooting. And let's stick to that principle down the road.
+ //
+ fail (ll) << "unable to obtain temporary directory for buildscript "
+ << "execution" << e;
+ }
+
+ mkdir_status r;
+
+ try
+ {
+ r = try_mkdir (td);
+ }
+ catch (const system_error& e)
+ {
+ fail(ll) << "unable to create temporary directory '" << td << "': "
+ << e << endf;
+ }
+
+ // Note that the temporary directory can potentially stay after some
+ // abnormally terminated script run. Clean it up and reuse if that's
+ // the case.
+ //
+ if (r == mkdir_status::already_exists)
+ try
+ {
+ butl::rmdir_r (td, false /* dir */);
+ }
+ catch (const system_error& e)
+ {
+ fail (ll) << "unable to cleanup temporary directory '" << td
+ << "': " << e;
+ }
+
+ if (verb >= 3)
+ text << "mkdir " << td;
}
void default_runner::
leave (environment& env, const location& ll)
{
clean (env, ll);
+
+ // Note that since the temporary directory may only contain special
+ // files that are created and registered for cleanup by the script
+ // running machinery and should all be removed by the above clean()
+ // function call, its removal failure may not be the script fault but
+ // potentially a bug or a filesystem problem. Thus, we don't ignore
+ // the errors and report them.
+ //
+ env.temp_dir.cancel ();
+
+ const dir_path& td (env.temp_dir.path);
+
+ try
+ {
+ // Note that the temporary directory must be empty to date.
+ //
+ rmdir_status r (try_rmdir (td));
+
+ if (r != rmdir_status::success)
+ {
+ diag_record dr (fail (ll));
+ dr << "temporary directory '" << td
+ << (r == rmdir_status::not_exist
+ ? "' does not exist"
+ : "' is not empty");
+
+ if (r == rmdir_status::not_empty)
+ build2::script::print_dir (dr, td, ll);
+ }
+ }
+ catch (const system_error& e)
+ {
+ fail (ll) << "unable to remove temporary directory '" << td << "': "
+ << e;
+ }
+
+ if (verb >= 3)
+ text << "rmdir " << td;
}
void default_runner::
diff --git a/libbuild2/build/script/script.cxx b/libbuild2/build/script/script.cxx
index cbd41c7..b43203c 100644
--- a/libbuild2/build/script/script.cxx
+++ b/libbuild2/build/script/script.cxx
@@ -24,8 +24,8 @@ namespace build2
: build2::script::environment (
pt.ctx,
cast<target_triplet> (pt.ctx.global_scope["build.host"]),
- work,
- wd_name,
+ work, wd_name,
+ temp_dir.path, false /* temp_dir_keep */,
redirect (redirect_type::none),
redirect (redirect_type::merge, 2),
redirect (redirect_type::pass)),
diff --git a/libbuild2/build/script/script.hxx b/libbuild2/build/script/script.hxx
index 29d62aa..f8306e1 100644
--- a/libbuild2/build/script/script.hxx
+++ b/libbuild2/build/script/script.hxx
@@ -9,6 +9,7 @@
#include <libbuild2/utility.hxx>
#include <libbuild2/variable.hxx>
+#include <libbuild2/filesystem.hxx> // auto_rmdir
#include <libbuild2/script/script.hxx>
@@ -58,9 +59,6 @@ namespace build2
location end_loc;
};
- //@@ Does environment need script? Can't we just pass it to parser along
- // with environment.
- //
class environment: public build2::script::environment
{
public:
@@ -83,6 +81,16 @@ namespace build2
//
variable_map vars;
+ // Temporary directory for the script run (see build2::script::
+ // environment::temp_dir for details).
+ //
+ // Currently this directory is removed regardless of the script
+ // execution success or failure. Later, to ease the troubleshooting,
+ // we may invent the build2 option suppressing the directory removal
+ // on failure.
+ //
+ auto_rmdir temp_dir;
+
virtual void
set_variable (string&& name, names&&, const string& attrs) override;