diff options
Diffstat (limited to 'libbuild2/build/script/runner.cxx')
-rw-r--r-- | libbuild2/build/script/runner.cxx | 97 |
1 files changed, 95 insertions, 2 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:: |