aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-02-13 17:12:42 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-02-13 17:12:42 +0000
commit6455b9ad3f9f5247468486cd2b0cb8291a18171f (patch)
tree909c4211795985f974241e9d1d1c85a2cee8836e
parent0152333f45030c199848b220b3ee0224bb98648f (diff)
downloadpaludis-6455b9ad3f9f5247468486cd2b0cb8291a18171f.tar.gz
paludis-6455b9ad3f9f5247468486cd2b0cb8291a18171f.tar.xz
New command wrapper that has no limit upon env size. Fixes: ticket:84
-rw-r--r--paludis/environment/default/default_environment.cc16
-rw-r--r--paludis/repositories/cran/cran_installed_repository.cc12
-rw-r--r--paludis/repositories/cran/cran_repository.cc89
-rw-r--r--paludis/repositories/gentoo/ebuild.cc238
-rw-r--r--paludis/repositories/gentoo/ebuild.hh24
-rw-r--r--paludis/syncer.cc12
-rw-r--r--paludis/util/Makefile.am.m42
-rw-r--r--paludis/util/pstream.cc19
-rw-r--r--paludis/util/pstream.hh13
-rw-r--r--paludis/util/system.cc220
-rw-r--r--paludis/util/system.hh81
-rw-r--r--paludis/util/system_TEST.cc51
-rw-r--r--src/clients/paludis/applets.cc7
13 files changed, 396 insertions, 388 deletions
diff --git a/paludis/environment/default/default_environment.cc b/paludis/environment/default/default_environment.cc
index 656756c..f86ffe9 100644
--- a/paludis/environment/default/default_environment.cc
+++ b/paludis/environment/default/default_environment.cc
@@ -566,16 +566,16 @@ namespace
Log::get_instance()->message(ll_debug, lc_no_context, "Starting hook script '" +
stringify(f) + "' for '" + hook.name() + "'");
- MakeEnvCommand cmd(make_env_command("bash '" + stringify(f) + "'")
- ("ROOT", DefaultConfig::get_instance()->root())
- ("HOOK", hook.name())
- ("HOOK_LOG_LEVEL", stringify(Log::get_instance()->log_level()))
- ("HOOK_CONFIG_SUFFIX", DefaultConfig::config_suffix())
- ("PALUDIS_EBUILD_DIR", getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis"))
- ("PALUDIS_COMMAND", paludis_command));
+ Command cmd(Command("bash '" + stringify(f) + "'")
+ .with_setenv("ROOT", DefaultConfig::get_instance()->root())
+ .with_setenv("HOOK", hook.name())
+ .with_setenv("HOOK_LOG_LEVEL", stringify(Log::get_instance()->log_level()))
+ .with_setenv("HOOK_CONFIG_SUFFIX", DefaultConfig::config_suffix())
+ .with_setenv("PALUDIS_EBUILD_DIR", getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis"))
+ .with_setenv("PALUDIS_COMMAND", paludis_command));
for (Hook::Iterator h(hook.begin()), h_end(hook.end()) ; h != h_end ; ++h)
- cmd = cmd(h->first, h->second);
+ cmd.with_setenv(h->first, h->second);
int exit_status(run_command(cmd));
if (0 == exit_status)
diff --git a/paludis/repositories/cran/cran_installed_repository.cc b/paludis/repositories/cran/cran_installed_repository.cc
index 5c7fc76..2d6ca7b 100644
--- a/paludis/repositories/cran/cran_installed_repository.cc
+++ b/paludis/repositories/cran/cran_installed_repository.cc
@@ -528,12 +528,12 @@ CRANInstalledRepository::do_uninstall(const QualifiedPackageName & q, const Vers
std::tr1::shared_ptr<const VersionMetadata> vm(do_version_metadata(q, v));
- MakeEnvCommand cmd(LIBEXECDIR "/paludis/cran.bash unmerge", "");
- cmd = cmd("PN", vm->cran_interface->package);
- cmd = cmd("PV", stringify(v));
- cmd = cmd("PALUDIS_CRAN_LIBRARY", stringify(_imp->location));
- cmd = cmd("PALUDIS_EBUILD_DIR", std::string(LIBEXECDIR "/paludis/"));
- cmd = cmd("PALUDIS_BASHRC_FILES", _imp->env->bashrc_files());
+ Command cmd(Command(LIBEXECDIR "/paludis/cran.bash unmerge")
+ .with_setenv("PN", vm->cran_interface->package)
+ .with_setenv("PV", stringify(v))
+ .with_setenv("PALUDIS_CRAN_LIBRARY", stringify(_imp->location))
+ .with_setenv("PALUDIS_EBUILD_DIR", std::string(LIBEXECDIR "/paludis/"))
+ .with_setenv("PALUDIS_BASHRC_FILES", _imp->env->bashrc_files()));
if (0 != run_command(cmd))
throw PackageUninstallActionError("Couldn't unmerge '" + stringify(q) + "-" + stringify(v) + "'");
diff --git a/paludis/repositories/cran/cran_repository.cc b/paludis/repositories/cran/cran_repository.cc
index 46e5c60..3598952 100644
--- a/paludis/repositories/cran/cran_repository.cc
+++ b/paludis/repositories/cran/cran_repository.cc
@@ -482,27 +482,21 @@ CRANRepository::do_install(const QualifiedPackageName &q, const VersionSpec &vn,
std::tr1::shared_ptr<const VersionMetadata> vm(do_version_metadata(q, vn));
if (vm->cran_interface->is_bundle_member)
- {
- MakeEnvCommand cmd(LIBEXECDIR "/paludis/cran.bash skip", "");
- cmd = cmd("CATEGORY", "cran");
- cmd = cmd("PN", stringify(pn));
- cmd = cmd("PV", stringify(vn));
return;
- }
std::string p(vm->cran_interface->package);
std::string v(vm->cran_interface->version);
- MakeEnvCommand cmd(LIBEXECDIR "/paludis/cran.bash fetch", "");
- cmd = cmd("CATEGORY", "cran");
- cmd = cmd("DISTDIR", stringify(_imp->distdir));
- cmd = cmd("DISTFILE", std::string(p + "_" + v + ".tar.gz"));
- cmd = cmd("PN", stringify(pn));
- cmd = cmd("PV", stringify(vn));
- cmd = cmd("PALUDIS_CRAN_MIRRORS", _imp->mirror);
- cmd = cmd("PALUDIS_EBUILD_DIR", std::string(LIBEXECDIR "/paludis/"));
- cmd = cmd("PALUDIS_EBUILD_LOG_LEVEL", stringify(Log::get_instance()->log_level()));
- cmd = cmd("PALUDIS_BASHRC_FILES", _imp->env->bashrc_files());
+ Command cmd(Command(LIBEXECDIR "/paludis/cran.bash fetch")
+ .with_setenv("CATEGORY", "cran")
+ .with_setenv("DISTDIR", stringify(_imp->distdir))
+ .with_setenv("DISTFILE", std::string(p + "_" + v + ".tar.gz"))
+ .with_setenv("PN", stringify(pn))
+ .with_setenv("PV", stringify(vn))
+ .with_setenv("PALUDIS_CRAN_MIRRORS", _imp->mirror)
+ .with_setenv("PALUDIS_EBUILD_DIR", std::string(LIBEXECDIR "/paludis/"))
+ .with_setenv("PALUDIS_EBUILD_LOG_LEVEL", stringify(Log::get_instance()->log_level()))
+ .with_setenv("PALUDIS_BASHRC_FILES", _imp->env->bashrc_files()));
if (0 != run_command(cmd))
@@ -514,40 +508,41 @@ CRANRepository::do_install(const QualifiedPackageName &q, const VersionSpec &vn,
std::string image(stringify(_imp->buildroot / stringify(q) / "image"));
std::string workdir(stringify(_imp->buildroot / stringify(q) / "work"));
- cmd = MakeEnvCommand(make_sandbox_command(LIBEXECDIR "/paludis/cran.bash clean install"), "");
- cmd = cmd("CATEGORY", "cran");
- cmd = cmd("DISTDIR", stringify(_imp->distdir));
- cmd = cmd("DISTFILE", std::string(p + "_" + v + ".tar.gz"));
- cmd = cmd("IMAGE", image);
- cmd = cmd("IS_BUNDLE", (vm->cran_interface->is_bundle ? "yes" : ""));
- cmd = cmd("LOCATION", stringify(_imp->location));
- cmd = cmd("PN", stringify(pn));
- cmd = cmd("PV", stringify(vn));
- cmd = cmd("PALUDIS_CRAN_LIBRARY", stringify(_imp->library));
- cmd = cmd("PALUDIS_EBUILD_DIR", std::string(LIBEXECDIR "/paludis/"));
- cmd = cmd("PALUDIS_EBUILD_LOG_LEVEL", stringify(Log::get_instance()->log_level()));
- cmd = cmd("PALUDIS_BASHRC_FILES", _imp->env->bashrc_files());
- cmd = cmd("ROOT", o.destination->installed_interface ?
- stringify(o.destination->installed_interface->root()) : "/");
- cmd = cmd("WORKDIR", workdir);
+ cmd = Command(LIBEXECDIR "/paludis/cran.bash clean install")
+ .with_sandbox()
+ .with_setenv("CATEGORY", "cran")
+ .with_setenv("DISTDIR", stringify(_imp->distdir))
+ .with_setenv("DISTFILE", std::string(p + "_" + v + ".tar.gz"))
+ .with_setenv("IMAGE", image)
+ .with_setenv("IS_BUNDLE", (vm->cran_interface->is_bundle ? "yes" : ""))
+ .with_setenv("LOCATION", stringify(_imp->location))
+ .with_setenv("PN", stringify(pn))
+ .with_setenv("PV", stringify(vn))
+ .with_setenv("PALUDIS_CRAN_LIBRARY", stringify(_imp->library))
+ .with_setenv("PALUDIS_EBUILD_DIR", std::string(LIBEXECDIR "/paludis/"))
+ .with_setenv("PALUDIS_EBUILD_LOG_LEVEL", stringify(Log::get_instance()->log_level()))
+ .with_setenv("PALUDIS_BASHRC_FILES", _imp->env->bashrc_files())
+ .with_setenv("ROOT", o.destination->installed_interface ?
+ stringify(o.destination->installed_interface->root()) : "/")
+ .with_setenv("WORKDIR", workdir);
if (0 != run_command(cmd))
throw PackageInstallActionError("Couldn't install '" + stringify(q) + "-" + stringify(vn) + "' to '" +
image + "'");
- cmd = MakeEnvCommand(LIBEXECDIR "/paludis/cran.bash merge clean", "");
- cmd = cmd("IMAGE", image);
- cmd = cmd("PN", p);
- cmd = cmd("PV", stringify(vn));
- cmd = cmd("PALUDIS_CRAN_LIBRARY", stringify(_imp->library));
- cmd = cmd("PALUDIS_EBUILD_DIR", std::string(LIBEXECDIR "/paludis/"));
- cmd = cmd("PALUDIS_EBUILD_LOG_LEVEL", stringify(Log::get_instance()->log_level()));
- cmd = cmd("PALUDIS_BASHRC_FILES", _imp->env->bashrc_files());
- cmd = cmd("ROOT", o.destination->installed_interface ?
- stringify(o.destination->installed_interface->root()) : "/");
- cmd = cmd("WORKDIR", workdir);
- cmd = cmd("REPOSITORY", stringify(name()));
+ cmd = Command(LIBEXECDIR "/paludis/cran.bash merge clean")
+ .with_setenv("IMAGE", image)
+ .with_setenv("PN", p)
+ .with_setenv("PV", stringify(vn))
+ .with_setenv("PALUDIS_CRAN_LIBRARY", stringify(_imp->library))
+ .with_setenv("PALUDIS_EBUILD_DIR", std::string(LIBEXECDIR "/paludis/"))
+ .with_setenv("PALUDIS_EBUILD_LOG_LEVEL", stringify(Log::get_instance()->log_level()))
+ .with_setenv("PALUDIS_BASHRC_FILES", _imp->env->bashrc_files())
+ .with_setenv("ROOT", o.destination->installed_interface ?
+ stringify(o.destination->installed_interface->root()) : "/")
+ .with_setenv("WORKDIR", workdir)
+ .with_setenv("REPOSITORY", stringify(name()));
if (0 != run_command(cmd))
throw PackageInstallActionError("Couldn't merge '" + stringify(q) + "-" + stringify(vn) + "' to '" +
@@ -589,17 +584,17 @@ CRANRepository::do_sync() const
std::string cmd("rsync --delete --recursive --progress --exclude \"*.html\" --exclude \"*.INDEX\" '" +
_imp->sync + "/src/contrib/Descriptions/' ./");
- if (0 != run_command_in_directory(cmd, _imp->location))
+ if (0 != run_command(Command(cmd).with_chdir(_imp->location)))
return false;
cmd = "rsync --progress '" + _imp->sync + "/src/contrib/PACKAGES' ./";
- if (0 != run_command_in_directory(cmd, _imp->location))
+ if (0 != run_command(Command(cmd).with_chdir(_imp->location)))
return false;
cmd = "rsync --progress '" + _imp->sync + "/CRAN_mirrors.csv' ./";
- return 0 == run_command_in_directory(cmd, _imp->location);
+ return 0 == run_command(Command(cmd).with_chdir(_imp->location));
}
void
diff --git a/paludis/repositories/gentoo/ebuild.cc b/paludis/repositories/gentoo/ebuild.cc
index b6e2c3a..dc7d23e 100644
--- a/paludis/repositories/gentoo/ebuild.cc
+++ b/paludis/repositories/gentoo/ebuild.cc
@@ -71,7 +71,7 @@ EbuildCommand::failure()
bool
EbuildCommand::operator() ()
{
- std::string ebuild_cmd(getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis") +
+ Command cmd(getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis") +
"/ebuild.bash '" +
stringify(params.ebuild_dir) + "/" +
stringify(params.db_entry->name.package) + "-" +
@@ -79,40 +79,40 @@ EbuildCommand::operator() ()
".ebuild' " + commands());
if (use_sandbox())
- ebuild_cmd = make_sandbox_command(ebuild_cmd);
-
- MakeEnvCommand cmd(extend_command(make_env_command(ebuild_cmd)
- ("P", stringify(params.db_entry->name.package) + "-" +
- stringify(params.db_entry->version.remove_revision()))
- ("PV", stringify(params.db_entry->version.remove_revision()))
- ("PR", stringify(params.db_entry->version.revision_only()))
- ("PN", stringify(params.db_entry->name.package))
- ("PVR", stringify(params.db_entry->version))
- ("PF", stringify(params.db_entry->name.package) + "-" +
- stringify(params.db_entry->version))
- ("CATEGORY", stringify(params.db_entry->name.category))
- ("REPOSITORY", stringify(params.db_entry->repository))
- ("FILESDIR", stringify(params.files_dir))
- ("ECLASSDIR", stringify(*params.eclassdirs->begin()))
- ("ECLASSDIRS", join(params.eclassdirs->begin(),
- params.eclassdirs->end(), " "))
- ("PORTDIR", stringify(params.portdir))
- ("DISTDIR", stringify(params.distdir))
- ("PKGMANAGER", PALUDIS_PACKAGE "-" + stringify(PALUDIS_VERSION_MAJOR) + "." +
- stringify(PALUDIS_VERSION_MINOR) + "." +
- stringify(PALUDIS_VERSION_MICRO) +
- (std::string(PALUDIS_SUBVERSION_REVISION).empty() ?
- std::string("") : "-r" + std::string(PALUDIS_SUBVERSION_REVISION)))
- ("PALUDIS_TMPDIR", stringify(params.buildroot))
- ("PALUDIS_CONFIG_DIR", SYSCONFDIR "/paludis/")
- ("PALUDIS_BASHRC_FILES", params.environment->bashrc_files())
- ("PALUDIS_HOOK_DIRS", params.environment->hook_dirs())
- ("PALUDIS_FETCHERS_DIRS", params.environment->fetchers_dirs())
- ("PALUDIS_SYNCERS_DIRS", params.environment->syncers_dirs())
- ("PALUDIS_COMMAND", params.environment->paludis_command())
- ("KV", kernel_version())
- ("PALUDIS_EBUILD_LOG_LEVEL", stringify(Log::get_instance()->log_level()))
- ("PALUDIS_EBUILD_DIR", getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis"))));
+ cmd.with_sandbox();
+
+ cmd = extend_command(cmd
+ .with_setenv("P", stringify(params.db_entry->name.package) + "-" +
+ stringify(params.db_entry->version.remove_revision()))
+ .with_setenv("PV", stringify(params.db_entry->version.remove_revision()))
+ .with_setenv("PR", stringify(params.db_entry->version.revision_only()))
+ .with_setenv("PN", stringify(params.db_entry->name.package))
+ .with_setenv("PVR", stringify(params.db_entry->version))
+ .with_setenv("PF", stringify(params.db_entry->name.package) + "-" +
+ stringify(params.db_entry->version))
+ .with_setenv("CATEGORY", stringify(params.db_entry->name.category))
+ .with_setenv("REPOSITORY", stringify(params.db_entry->repository))
+ .with_setenv("FILESDIR", stringify(params.files_dir))
+ .with_setenv("ECLASSDIR", stringify(*params.eclassdirs->begin()))
+ .with_setenv("ECLASSDIRS", join(params.eclassdirs->begin(),
+ params.eclassdirs->end(), " "))
+ .with_setenv("PORTDIR", stringify(params.portdir))
+ .with_setenv("DISTDIR", stringify(params.distdir))
+ .with_setenv("PKGMANAGER", PALUDIS_PACKAGE "-" + stringify(PALUDIS_VERSION_MAJOR) + "." +
+ stringify(PALUDIS_VERSION_MINOR) + "." +
+ stringify(PALUDIS_VERSION_MICRO) +
+ (std::string(PALUDIS_SUBVERSION_REVISION).empty() ?
+ std::string("") : "-r" + std::string(PALUDIS_SUBVERSION_REVISION)))
+ .with_setenv("PALUDIS_TMPDIR", stringify(params.buildroot))
+ .with_setenv("PALUDIS_CONFIG_DIR", SYSCONFDIR "/paludis/")
+ .with_setenv("PALUDIS_BASHRC_FILES", params.environment->bashrc_files())
+ .with_setenv("PALUDIS_HOOK_DIRS", params.environment->hook_dirs())
+ .with_setenv("PALUDIS_FETCHERS_DIRS", params.environment->fetchers_dirs())
+ .with_setenv("PALUDIS_SYNCERS_DIRS", params.environment->syncers_dirs())
+ .with_setenv("PALUDIS_COMMAND", params.environment->paludis_command())
+ .with_setenv("KV", kernel_version())
+ .with_setenv("PALUDIS_EBUILD_LOG_LEVEL", stringify(Log::get_instance()->log_level()))
+ .with_setenv("PALUDIS_EBUILD_DIR", getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis")));
if (do_run_command(add_portage_vars(cmd)))
return success();
@@ -120,29 +120,29 @@ EbuildCommand::operator() ()
return failure();
}
-MakeEnvCommand
-EbuildCommand::add_portage_vars(const MakeEnvCommand & cmd) const
+Command
+EbuildCommand::add_portage_vars(const Command & cmd) const
{
- return cmd
- ("PORTAGE_ACTUAL_DISTDIR", stringify(params.distdir))
- ("PORTAGE_BASHRC", "/dev/null")
- ("PORTAGE_BUILDDIR", stringify(params.buildroot) + "/" +
+ return Command(cmd)
+ .with_setenv("PORTAGE_ACTUAL_DISTDIR", stringify(params.distdir))
+ .with_setenv("PORTAGE_BASHRC", "/dev/null")
+ .with_setenv("PORTAGE_BUILDDIR", stringify(params.buildroot) + "/" +
stringify(params.db_entry->name.category) + "/" +
stringify(params.db_entry->name.package) + "-" +
stringify(params.db_entry->version))
- ("PORTAGE_CALLER", params.environment->paludis_command())
- ("PORTAGE_GID", "0")
- ("PORTAGE_INST_GID", "0")
- ("PORTAGE_INST_UID", "0")
- ("PORTAGE_MASTER_PID", stringify(::getpid()))
- ("PORTAGE_NICENCESS", stringify(::getpriority(PRIO_PROCESS, 0)))
- ("PORTAGE_TMPDIR", stringify(params.buildroot))
- ("PORTAGE_TMPFS", "/dev/shm")
- ("PORTAGE_WORKDIR_MODE", "0700");
+ .with_setenv("PORTAGE_CALLER", params.environment->paludis_command())
+ .with_setenv("PORTAGE_GID", "0")
+ .with_setenv("PORTAGE_INST_GID", "0")
+ .with_setenv("PORTAGE_INST_UID", "0")
+ .with_setenv("PORTAGE_MASTER_PID", stringify(::getpid()))
+ .with_setenv("PORTAGE_NICENCESS", stringify(::getpriority(PRIO_PROCESS, 0)))
+ .with_setenv("PORTAGE_TMPDIR", stringify(params.buildroot))
+ .with_setenv("PORTAGE_TMPFS", "/dev/shm")
+ .with_setenv("PORTAGE_WORKDIR_MODE", "0700");
}
bool
-EbuildCommand::do_run_command(const std::string & cmd)
+EbuildCommand::do_run_command(const Command & cmd)
{
return 0 == run_command(cmd);
}
@@ -164,14 +164,14 @@ EbuildMetadataCommand::failure()
return EbuildCommand::failure();
}
-MakeEnvCommand
-EbuildMetadataCommand::extend_command(const MakeEnvCommand & cmd)
+Command
+EbuildMetadataCommand::extend_command(const Command & cmd)
{
return cmd;
}
bool
-EbuildMetadataCommand::do_run_command(const std::string & cmd)
+EbuildMetadataCommand::do_run_command(const Command & cmd)
{
PStream prog(cmd);
KeyValueConfigFile f(&prog);
@@ -237,14 +237,14 @@ EbuildVariableCommand::failure()
return EbuildCommand::failure();
}
-MakeEnvCommand
-EbuildVariableCommand::extend_command(const MakeEnvCommand & cmd)
+Command
+EbuildVariableCommand::extend_command(const Command & cmd)
{
- return cmd("PALUDIS_VARIABLE", _var);
+ return Command(cmd).with_setenv("PALUDIS_VARIABLE", _var);
}
bool
-EbuildVariableCommand::do_run_command(const std::string & cmd)
+EbuildVariableCommand::do_run_command(const Command & cmd)
{
PStream prog(cmd);
_result = strip_trailing_string(
@@ -270,25 +270,25 @@ EbuildFetchCommand::failure()
*params.db_entry) + "'");
}
-MakeEnvCommand
-EbuildFetchCommand::extend_command(const MakeEnvCommand & cmd)
+Command
+EbuildFetchCommand::extend_command(const Command & cmd)
{
- MakeEnvCommand result(cmd
- ("A", fetch_params.a)
- ("AA", fetch_params.aa)
- ("USE", fetch_params.use)
- ("USE_EXPAND", fetch_params.use_expand)
- ("FLAT_SRC_URI", fetch_params.flat_src_uri)
- ("ROOT", fetch_params.root)
- ("PALUDIS_USE_SAFE_RESUME", fetch_params.safe_resume ? "oohyesplease" : "")
- ("PALUDIS_PROFILE_DIR", stringify(*fetch_params.profiles->begin()))
- ("PALUDIS_PROFILE_DIRS", join(fetch_params.profiles->begin(),
- fetch_params.profiles->end(), " ")));
+ Command result(Command(cmd)
+ .with_setenv("A", fetch_params.a)
+ .with_setenv("AA", fetch_params.aa)
+ .with_setenv("USE", fetch_params.use)
+ .with_setenv("USE_EXPAND", fetch_params.use_expand)
+ .with_setenv("FLAT_SRC_URI", fetch_params.flat_src_uri)
+ .with_setenv("ROOT", fetch_params.root)
+ .with_setenv("PALUDIS_USE_SAFE_RESUME", fetch_params.safe_resume ? "oohyesplease" : "")
+ .with_setenv("PALUDIS_PROFILE_DIR", stringify(*fetch_params.profiles->begin()))
+ .with_setenv("PALUDIS_PROFILE_DIRS", join(fetch_params.profiles->begin(),
+ fetch_params.profiles->end(), " ")));
for (AssociativeCollection<std::string, std::string>::Iterator
i(fetch_params.expand_vars->begin()),
j(fetch_params.expand_vars->end()) ; i != j ; ++i)
- result = result(i->first, i->second);
+ result.with_setenv(i->first, i->second);
return result;
}
@@ -331,8 +331,8 @@ EbuildInstallCommand::failure()
*params.db_entry) + "'");
}
-MakeEnvCommand
-EbuildInstallCommand::extend_command(const MakeEnvCommand & cmd)
+Command
+EbuildInstallCommand::extend_command(const Command & cmd)
{
std::string debug_build;
do
@@ -356,27 +356,27 @@ EbuildInstallCommand::extend_command(const MakeEnvCommand & cmd)
}
while (false);
- MakeEnvCommand result(cmd
- ("A", install_params.a)
- ("AA", install_params.aa)
- ("USE", install_params.use)
- ("USE_EXPAND", install_params.use_expand)
- ("ROOT", install_params.root)
- ("PALUDIS_LOADSAVEENV_DIR", stringify(install_params.loadsaveenv_dir))
- ("PALUDIS_CONFIG_PROTECT", install_params.config_protect)
- ("PALUDIS_CONFIG_PROTECT_MASK", install_params.config_protect_mask)
- ("PALUDIS_EBUILD_OVERRIDE_CONFIG_PROTECT_MASK",
+ Command result(Command(cmd)
+ .with_setenv("A", install_params.a)
+ .with_setenv("AA", install_params.aa)
+ .with_setenv("USE", install_params.use)
+ .with_setenv("USE_EXPAND", install_params.use_expand)
+ .with_setenv("ROOT", install_params.root)
+ .with_setenv("PALUDIS_LOADSAVEENV_DIR", stringify(install_params.loadsaveenv_dir))
+ .with_setenv("PALUDIS_CONFIG_PROTECT", install_params.config_protect)
+ .with_setenv("PALUDIS_CONFIG_PROTECT_MASK", install_params.config_protect_mask)
+ .with_setenv("PALUDIS_EBUILD_OVERRIDE_CONFIG_PROTECT_MASK",
install_params.disable_cfgpro ? "/" : "")
- ("PALUDIS_DEBUG_BUILD", debug_build)
- ("PALUDIS_PROFILE_DIR", stringify(*install_params.profiles->begin()))
- ("PALUDIS_PROFILE_DIRS", join(install_params.profiles->begin(),
+ .with_setenv("PALUDIS_DEBUG_BUILD", debug_build)
+ .with_setenv("PALUDIS_PROFILE_DIR", stringify(*install_params.profiles->begin()))
+ .with_setenv("PALUDIS_PROFILE_DIRS", join(install_params.profiles->begin(),
install_params.profiles->end(), " "))
- ("SLOT", stringify(install_params.slot)));
+ .with_setenv("SLOT", stringify(install_params.slot)));
for (AssociativeCollection<std::string, std::string>::Iterator
i(install_params.expand_vars->begin()),
j(install_params.expand_vars->end()) ; i != j ; ++i)
- result = result(i->first, i->second);
+ result.with_setenv(i->first, i->second);
return result;
}
@@ -413,19 +413,19 @@ EbuildUninstallCommand::failure()
*params.db_entry) + "'");
}
-MakeEnvCommand
-EbuildUninstallCommand::extend_command(const MakeEnvCommand & cmd)
+Command
+EbuildUninstallCommand::extend_command(const Command & cmd)
{
- MakeEnvCommand result(cmd
- ("ROOT", uninstall_params.root)
- ("PALUDIS_LOADSAVEENV_DIR", stringify(uninstall_params.loadsaveenv_dir))
- ("PALUDIS_EBUILD_OVERRIDE_CONFIG_PROTECT_MASK",
+ Command result(Command(cmd)
+ .with_setenv("ROOT", uninstall_params.root)
+ .with_setenv("PALUDIS_LOADSAVEENV_DIR", stringify(uninstall_params.loadsaveenv_dir))
+ .with_setenv("PALUDIS_EBUILD_OVERRIDE_CONFIG_PROTECT_MASK",
uninstall_params.disable_cfgpro ? "/" : ""));
if (uninstall_params.load_environment)
- result = result
- ("PALUDIS_LOAD_ENVIRONMENT", stringify(*uninstall_params.load_environment))
- ("PALUDIS_SKIP_INHERIT", "yes");
+ result
+ .with_setenv("PALUDIS_LOAD_ENVIRONMENT", stringify(*uninstall_params.load_environment))
+ .with_setenv("PALUDIS_SKIP_INHERIT", "yes");
return result;
}
@@ -471,16 +471,16 @@ EbuildConfigCommand::failure()
*params.db_entry) + "'");
}
-MakeEnvCommand
-EbuildConfigCommand::extend_command(const MakeEnvCommand & cmd)
+Command
+EbuildConfigCommand::extend_command(const Command & cmd)
{
- MakeEnvCommand result(cmd
- ("ROOT", config_params.root));
+ Command result(Command(cmd)
+ .with_setenv("ROOT", config_params.root));
if (config_params.load_environment)
- result = result
- ("PALUDIS_LOAD_ENVIRONMENT", stringify(*config_params.load_environment))
- ("PALUDIS_SKIP_INHERIT", "yes");
+ result
+ .with_setenv("PALUDIS_LOAD_ENVIRONMENT", stringify(*config_params.load_environment))
+ .with_setenv("PALUDIS_SKIP_INHERIT", "yes");
return result;
}
@@ -505,20 +505,20 @@ WriteVDBEntryCommand::operator() ()
stringify(params.output_directory) + "' '" +
stringify(params.environment_file) + "'");
- MakeEnvCommand cmd(make_env_command(ebuild_cmd)
- ("PKGMANAGER", PALUDIS_PACKAGE "-" + stringify(PALUDIS_VERSION_MAJOR) + "." +
- stringify(PALUDIS_VERSION_MINOR) + "." +
- stringify(PALUDIS_VERSION_MICRO) +
- (std::string(PALUDIS_SUBVERSION_REVISION).empty() ?
- std::string("") : "-r" + std::string(PALUDIS_SUBVERSION_REVISION)))
- ("PALUDIS_CONFIG_DIR", SYSCONFDIR "/paludis/")
- ("PALUDIS_BASHRC_FILES", params.environment->bashrc_files())
- ("PALUDIS_HOOK_DIRS", params.environment->hook_dirs())
- ("PALUDIS_FETCHERS_DIRS", params.environment->fetchers_dirs())
- ("PALUDIS_SYNCERS_DIRS", params.environment->syncers_dirs())
- ("PALUDIS_COMMAND", params.environment->paludis_command())
- ("PALUDIS_EBUILD_LOG_LEVEL", stringify(Log::get_instance()->log_level()))
- ("PALUDIS_EBUILD_DIR", getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis")));
+ Command cmd(Command(ebuild_cmd)
+ .with_setenv("PKGMANAGER", PALUDIS_PACKAGE "-" + stringify(PALUDIS_VERSION_MAJOR) + "." +
+ stringify(PALUDIS_VERSION_MINOR) + "." +
+ stringify(PALUDIS_VERSION_MICRO) +
+ (std::string(PALUDIS_SUBVERSION_REVISION).empty() ?
+ std::string("") : "-r" + std::string(PALUDIS_SUBVERSION_REVISION)))
+ .with_setenv("PALUDIS_CONFIG_DIR", SYSCONFDIR "/paludis/")
+ .with_setenv("PALUDIS_BASHRC_FILES", params.environment->bashrc_files())
+ .with_setenv("PALUDIS_HOOK_DIRS", params.environment->hook_dirs())
+ .with_setenv("PALUDIS_FETCHERS_DIRS", params.environment->fetchers_dirs())
+ .with_setenv("PALUDIS_SYNCERS_DIRS", params.environment->syncers_dirs())
+ .with_setenv("PALUDIS_COMMAND", params.environment->paludis_command())
+ .with_setenv("PALUDIS_EBUILD_LOG_LEVEL", stringify(Log::get_instance()->log_level()))
+ .with_setenv("PALUDIS_EBUILD_DIR", getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis")));
if (0 != (run_command(cmd)))
throw PackageInstallActionError("Write VDB Entry command failed");
diff --git a/paludis/repositories/gentoo/ebuild.hh b/paludis/repositories/gentoo/ebuild.hh
index e355877..eae7764 100644
--- a/paludis/repositories/gentoo/ebuild.hh
+++ b/paludis/repositories/gentoo/ebuild.hh
@@ -56,7 +56,7 @@ namespace paludis
};
class Environment;
- class MakeEnvCommand;
+ class Command;
#include <paludis/repositories/gentoo/ebuild-se.hh>
#include <paludis/repositories/gentoo/ebuild-sr.hh>
@@ -126,17 +126,17 @@ namespace paludis
*
* \return Whether the command succeeded.
*/
- virtual bool do_run_command(const std::string &);
+ virtual bool do_run_command(const Command &);
/**
* Add Portage emulation vars.
*/
- virtual MakeEnvCommand add_portage_vars(const MakeEnvCommand &) const;
+ virtual Command add_portage_vars(const Command &) const;
/**
* Extend the command to be run.
*/
- virtual MakeEnvCommand extend_command(const MakeEnvCommand &) = 0;
+ virtual Command extend_command(const Command &) = 0;
public:
/**
@@ -167,9 +167,9 @@ namespace paludis
virtual bool failure();
- virtual MakeEnvCommand extend_command(const MakeEnvCommand &);
+ virtual Command extend_command(const Command &);
- virtual bool do_run_command(const std::string &);
+ virtual bool do_run_command(const Command &);
public:
/**
@@ -203,9 +203,9 @@ namespace paludis
protected:
virtual std::string commands() const;
- virtual MakeEnvCommand extend_command(const MakeEnvCommand &);
+ virtual Command extend_command(const Command &);
- virtual bool do_run_command(const std::string &);
+ virtual bool do_run_command(const Command &);
virtual bool failure();
@@ -241,7 +241,7 @@ namespace paludis
virtual bool failure() PALUDIS_ATTRIBUTE((noreturn));
- virtual MakeEnvCommand extend_command(const MakeEnvCommand &);
+ virtual Command extend_command(const Command &);
public:
/**
@@ -267,7 +267,7 @@ namespace paludis
virtual bool failure() PALUDIS_ATTRIBUTE((noreturn));
- virtual MakeEnvCommand extend_command(const MakeEnvCommand &);
+ virtual Command extend_command(const Command &);
public:
/**
@@ -292,7 +292,7 @@ namespace paludis
virtual bool failure() PALUDIS_ATTRIBUTE((noreturn));
- virtual MakeEnvCommand extend_command(const MakeEnvCommand &);
+ virtual Command extend_command(const Command &);
public:
/**
@@ -317,7 +317,7 @@ namespace paludis
virtual bool failure() PALUDIS_ATTRIBUTE((noreturn));
- virtual MakeEnvCommand extend_command(const MakeEnvCommand &);
+ virtual Command extend_command(const Command &);
public:
/**
diff --git a/paludis/syncer.cc b/paludis/syncer.cc
index dc6e878..39c2211 100644
--- a/paludis/syncer.cc
+++ b/paludis/syncer.cc
@@ -93,12 +93,12 @@ void
DefaultSyncer::sync(const SyncOptions & opts) const
{
- MakeEnvCommand cmd(make_env_command(stringify(_syncer) + " " + opts.options + " '" + _local + "' '" + _remote + "'")
- ("PALUDIS_ACTION", "sync")
- ("PALUDIS_BASHRC_FILES", _environment->bashrc_files())
- ("PALUDIS_FETCHERS_DIRS", _environment->fetchers_dirs())
- ("PALUDIS_SYNCERS_DIRS", _environment->syncers_dirs())
- ("PALUDIS_EBUILD_DIR", getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis")));
+ Command cmd(Command(stringify(_syncer) + " " + opts.options + " '" + _local + "' '" + _remote + "'")
+ .with_setenv("PALUDIS_ACTION", "sync")
+ .with_setenv("PALUDIS_BASHRC_FILES", _environment->bashrc_files())
+ .with_setenv("PALUDIS_FETCHERS_DIRS", _environment->fetchers_dirs())
+ .with_setenv("PALUDIS_SYNCERS_DIRS", _environment->syncers_dirs())
+ .with_setenv("PALUDIS_EBUILD_DIR", getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis")));
if (run_command(cmd))
throw SyncFailedError(_local, _remote);
diff --git a/paludis/util/Makefile.am.m4 b/paludis/util/Makefile.am.m4
index 6793aca..de0adce 100644
--- a/paludis/util/Makefile.am.m4
+++ b/paludis/util/Makefile.am.m4
@@ -35,7 +35,7 @@ include(`paludis/util/files.m4')
CLEANFILES = *~ gmon.out *.gcov *.gcno *.gcda
MAINTAINERCLEANFILES = Makefile.in Makefile.am paludis.hh \
hashed_containers.hh util.hh attributes.hh
-AM_CXXFLAGS = -I$(top_srcdir) @PALUDIS_CXXFLAGS@ @PALUDIS_CXXFLAGS_VISIBILITY@
+AM_CXXFLAGS = -I$(top_srcdir) @PALUDIS_CXXFLAGS@ @PALUDIS_CXXFLAGS_NO_WOLD_STYLE_CAST@ @PALUDIS_CXXFLAGS_VISIBILITY@
DEFS=\
-DSYSCONFDIR=\"$(sysconfdir)\" \
-DLIBEXECDIR=\"$(libexecdir)\"
diff --git a/paludis/util/pstream.cc b/paludis/util/pstream.cc
index d9495cf..130a1b6 100644
--- a/paludis/util/pstream.cc
+++ b/paludis/util/pstream.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ * Copyright (c) 2006, 2007 Ciaran McCreesh <ciaranm@ciaranm.org>
*
* This file is part of the Paludis package manager. Paludis is free software;
* you can redistribute it and/or modify it under the terms of the GNU General
@@ -62,14 +62,19 @@ PStreamInBuf::underflow()
return *gptr();
}
-PStreamInBuf::PStreamInBuf(const std::string & cmd) :
+PStreamInBuf::PStreamInBuf(const Command & cmd) :
_command(cmd),
child(fork())
{
if (0 == child)
{
- Log::get_instance()->message(ll_debug, lc_no_context, "dup2 " +
- stringify(stdout_pipe.write_fd()) + " 1");
+ if (! cmd.chdir().empty())
+ if (-1 == chdir(cmd.chdir().c_str()))
+ throw RunCommandError("chdir failed: " + stringify(strerror(errno)));
+
+ for (Command::Iterator s(cmd.begin_setenvs()), s_end(cmd.end_setenvs()) ; s != s_end ; ++s)
+ setenv(s->first.c_str(), s->second.c_str(), 1);
+
if (-1 == dup2(stdout_pipe.write_fd(), 1))
throw PStreamError("dup2 failed");
close(stdout_pipe.read_fd());
@@ -86,9 +91,9 @@ PStreamInBuf::PStreamInBuf(const std::string & cmd) :
close(PStream::stderr_close_fd);
}
- Log::get_instance()->message(ll_debug, lc_no_context, "execl /bin/sh -c " + cmd);
- execl("/bin/sh", "sh", "-c", cmd.c_str(), static_cast<char *>(0));
- throw PStreamError("execl /bin/sh -c '" + cmd + "' failed:"
+ Log::get_instance()->message(ll_debug, lc_no_context, "execl /bin/sh -c " + cmd.command());
+ execl("/bin/sh", "sh", "-c", cmd.command().c_str(), static_cast<char *>(0));
+ throw PStreamError("execl /bin/sh -c '" + cmd.command() + "' failed:"
+ stringify(strerror(errno)));
}
else if (-1 == child)
diff --git a/paludis/util/pstream.hh b/paludis/util/pstream.hh
index eb0b861..be42e05 100644
--- a/paludis/util/pstream.hh
+++ b/paludis/util/pstream.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ * Copyright (c) 2006, 2007 Ciaran McCreesh <ciaranm@ciaranm.org>
*
* This file is part of the Paludis package manager. Paludis is free software;
* you can redistribute it and/or modify it under the terms of the GNU General
@@ -26,6 +26,7 @@
#include <paludis/util/exception.hh>
#include <paludis/util/instantiation_policy.hh>
#include <paludis/util/pipe.hh>
+#include <paludis/util/system.hh>
#include <streambuf>
#include <string>
@@ -76,7 +77,7 @@ namespace paludis
private:
Pipe stdout_pipe;
- const std::string _command;
+ Command _command;
int _exit_status;
@@ -117,7 +118,7 @@ namespace paludis
*
* \param command The command to run. See PStream for discussion.
*/
- PStreamInBuf(const std::string & command);
+ PStreamInBuf(const Command & command);
~PStreamInBuf();
@@ -126,7 +127,7 @@ namespace paludis
/**
* What was our command?
*/
- const std::string & command() const
+ const Command & command() const
{
return _command;
}
@@ -160,7 +161,7 @@ namespace paludis
/**
* Constructor.
*/
- PStreamInBufBase(const std::string & command) :
+ PStreamInBufBase(const Command & command) :
buf(command)
{
}
@@ -194,7 +195,7 @@ namespace paludis
* usually no need to specify a full path. Arguments can be passed
* as part of the command.
*/
- PStream(const std::string & command) :
+ PStream(const Command & command) :
PStreamInBufBase(command),
std::istream(&buf)
{
diff --git a/paludis/util/system.cc b/paludis/util/system.cc
index 8c0c814..b506dd5 100644
--- a/paludis/util/system.cc
+++ b/paludis/util/system.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ * Copyright (c) 2006, 2007 Ciaran McCreesh <ciaranm@ciaranm.org>
*
* This file is part of the Paludis package manager. Paludis is free software;
* you can redistribute it and/or modify it under the terms of the GNU General
@@ -28,6 +28,7 @@
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
+#include <map>
#include "config.h"
/** \file
@@ -64,64 +65,6 @@ namespace
static pid_t paludis_pid(get_paludis_pid());
-
- /**
- * Runs a command in a directory if needed, wait for it to terminate
- * and return its exit status.
- *
- * \ingroup grpsystem
- */
- int
- real_run_command(const std::string & cmd, const FSEntry * const fsentry)
- {
- pid_t child(fork());
- if (0 == child)
- {
- if (fsentry)
- if (-1 == chdir(stringify(*fsentry).c_str()))
- throw RunCommandError("chdir failed: " + stringify(strerror(errno)));
-
- if (-1 != stdout_write_fd)
- {
- Log::get_instance()->message(ll_debug, lc_no_context, "dup2 " +
- stringify(stdout_write_fd) + " 2");
-
- if (-1 == dup2(stdout_write_fd, 1))
- throw RunCommandError("dup2 failed");
-
- if (-1 != stdout_close_fd)
- close(stdout_close_fd);
- }
-
- if (-1 != stderr_write_fd)
- {
- Log::get_instance()->message(ll_debug, lc_no_context, "dup2 " +
- stringify(stderr_write_fd) + " 2");
-
- if (-1 == dup2(stderr_write_fd, 2))
- throw RunCommandError("dup2 failed");
-
- if (-1 != stderr_close_fd)
- close(stderr_close_fd);
- }
-
- Log::get_instance()->message(ll_debug, lc_no_context, "execl /bin/sh -c " + cmd);
- execl("/bin/sh", "sh", "-c", cmd.c_str(), static_cast<char *>(0));
- throw RunCommandError("execl /bin/sh -c '" + cmd + "' failed:"
- + stringify(strerror(errno)));
- }
- else if (-1 == child)
- throw RunCommandError("fork failed: " + stringify(strerror(errno)));
- else
- {
- int status(-1);
- if (-1 == wait(&status))
- throw RunCommandError("wait failed: " + stringify(strerror(errno)));
- return ((status & 0xff00) >> 8);
- }
-
- throw InternalError(PALUDIS_HERE, "should never be reached");
- }
}
void
@@ -187,70 +130,157 @@ paludis::kernel_version()
return result;
}
-int
-paludis::run_command(const std::string & cmd)
+namespace paludis
+{
+ template<>
+ struct Implementation<Command>
+ {
+ std::string command;
+ std::map<std::string, std::string> setenv_values;
+ std::string chdir;
+
+ Implementation(const std::string & c,
+ const std::map<std::string, std::string> & s = (std::map<std::string, std::string>()),
+ const std::string & d = "") :
+ command(c),
+ setenv_values(s),
+ chdir(d)
+ {
+ }
+ };
+}
+
+Command::Command(const std::string & s) :
+ PrivateImplementationPattern<Command>(new Implementation<Command>(s))
{
- return real_run_command(cmd, 0);
}
-int
-paludis::run_command_in_directory(const std::string & cmd, const FSEntry & fsentry)
+Command::Command(const char * const s) :
+ PrivateImplementationPattern<Command>(new Implementation<Command>(s))
{
- return real_run_command(cmd, &fsentry);
}
-MakeEnvCommand::MakeEnvCommand(const std::string & c,
- const std::string & a) :
- cmd(c),
- args(a)
+Command::Command(const Command & other) :
+ PrivateImplementationPattern<Command>(new Implementation<Command>(other._imp->command,
+ other._imp->setenv_values, other._imp->chdir))
{
}
-MakeEnvCommand
-MakeEnvCommand::operator() (const std::string & k,
- const std::string & v) const
+const Command &
+Command::operator= (const Command & other)
{
- std::string vv;
- for (std::string::size_type p(0) ; p < v.length() ; ++p)
- if ('\'' == v[p])
- vv.append("'\"'\"'");
- else
- vv.append(v.substr(p, 1));
+ if (this != &other)
+ _imp.reset(new Implementation<Command>(other._imp->command, other._imp->setenv_values,
+ other._imp->chdir));
+
+ return *this;
+}
- return MakeEnvCommand(cmd, args + k + "='" + vv + "' ");
+Command::~Command()
+{
}
-MakeEnvCommand::operator std::string() const
+Command &
+Command::with_chdir(const FSEntry & c)
{
- return "/usr/bin/env " + args + cmd;
+ _imp->chdir = stringify(c);
+ return *this;
}
-const MakeEnvCommand
-paludis::make_env_command(const std::string & cmd)
+Command &
+Command::with_setenv(const std::string & k, const std::string & v)
{
- return MakeEnvCommand(cmd, "");
+ _imp->setenv_values.insert(std::make_pair(k, v));
+ return *this;
}
-const std::string
-paludis::make_sandbox_command(const std::string & cmd)
+Command &
+Command::with_sandbox()
{
#if HAVE_SANDBOX
if (! getenv_with_default("PALUDIS_DO_NOTHING_SANDBOXY", "").empty())
- {
Log::get_instance()->message(ll_debug, lc_no_context,
"PALUDIS_DO_NOTHING_SANDBOXY is set, not using sandbox");
- return cmd;
- }
else if (! getenv_with_default("SANDBOX_ACTIVE", "").empty())
- {
Log::get_instance()->message(ll_warning, lc_no_context,
"Already inside sandbox, not spawning another sandbox instance");
- return cmd;
- }
else
- return "sandbox " + cmd;
-#else
- return cmd;
+ _imp->command = "sandbox " + _imp->command;
#endif
+
+ return *this;
+}
+
+int
+paludis::run_command(const Command & cmd)
+{
+ pid_t child(fork());
+ if (0 == child)
+ {
+ if (! cmd.chdir().empty())
+ if (-1 == chdir(stringify(cmd.chdir()).c_str()))
+ throw RunCommandError("chdir failed: " + stringify(strerror(errno)));
+
+ for (Command::Iterator s(cmd.begin_setenvs()), s_end(cmd.end_setenvs()) ; s != s_end ; ++s)
+ setenv(s->first.c_str(), s->second.c_str(), 1);
+
+ if (-1 != stdout_write_fd)
+ {
+ if (-1 == dup2(stdout_write_fd, 1))
+ throw RunCommandError("dup2 failed");
+
+ if (-1 != stdout_close_fd)
+ close(stdout_close_fd);
+ }
+
+ if (-1 != stderr_write_fd)
+ {
+ if (-1 == dup2(stderr_write_fd, 2))
+ throw RunCommandError("dup2 failed");
+
+ if (-1 != stderr_close_fd)
+ close(stderr_close_fd);
+ }
+
+ Log::get_instance()->message(ll_debug, lc_no_context, "execl /bin/sh -c " + cmd.command());
+ execl("/bin/sh", "sh", "-c", cmd.command().c_str(), static_cast<char *>(0));
+ throw RunCommandError("execl /bin/sh -c '" + cmd.command() + "' failed:"
+ + stringify(strerror(errno)));
+ }
+ else if (-1 == child)
+ throw RunCommandError("fork failed: " + stringify(strerror(errno)));
+ else
+ {
+ int status(-1);
+ if (-1 == wait(&status))
+ throw RunCommandError("wait failed: " + stringify(strerror(errno)));
+ return WEXITSTATUS(status);
+ }
+
+ throw InternalError(PALUDIS_HERE, "should never be reached");
+}
+
+std::string
+Command::command() const
+{
+ return _imp->command;
+}
+
+std::string
+Command::chdir() const
+{
+ return _imp->chdir;
+}
+
+Command::Iterator
+Command::begin_setenvs() const
+{
+ return Iterator(_imp->setenv_values.begin());
+}
+
+Command::Iterator
+Command::end_setenvs() const
+{
+ return Iterator(_imp->setenv_values.end());
}
diff --git a/paludis/util/system.hh b/paludis/util/system.hh
index 63ca2f5..a1483dc 100644
--- a/paludis/util/system.hh
+++ b/paludis/util/system.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ * Copyright (c) 2006, 2007 Ciaran McCreesh <ciaranm@ciaranm.org>
*
* This file is part of the Paludis package manager. Paludis is free software;
* you can redistribute it and/or modify it under the terms of the GNU General
@@ -21,6 +21,7 @@
#define PALUDIS_GUARD_PALUDIS_UTIL_SYSTEM_HH 1
#include <paludis/util/exception.hh>
+#include <paludis/util/private_implementation_pattern.hh>
#include <string>
/** \file
@@ -91,21 +92,39 @@ namespace paludis
std::string kernel_version() PALUDIS_VISIBLE;
/**
- * Run a command, wait for it to terminate and return its exit status.
- *
- * Use PStream instead if you need to capture stdout.
- *
- * \ingroup grpsystem
+ * A command to be run.
*/
- int run_command(const std::string & cmd) PALUDIS_VISIBLE;
+ class Command :
+ private PrivateImplementationPattern<Command>
+ {
+ public:
+ Command(const std::string &);
+ Command(const char * const);
+ Command(const Command &);
+ const Command & operator= (const Command &);
+ ~Command();
+
+ Command & with_chdir(const FSEntry &);
+ Command & with_setenv(const std::string &, const std::string &);
+ Command & with_sandbox();
+
+ std::string command() const;
+ std::string chdir() const;
+
+ typedef libwrapiter::ForwardIterator<Command, const std::pair<const std::string, std::string> > Iterator;
+ Iterator begin_setenvs() const;
+ Iterator end_setenvs() const;
+ };
+
/**
- * Run a command in a directory, wait for it to terminate and return
- * its exit status.
+ * Run a command, wait for it to terminate and return its exit status.
+ *
+ * Use PStream instead if you need to capture stdout.
*
* \ingroup grpsystem
*/
- int run_command_in_directory(const std::string & cmd, const FSEntry & fsentry) PALUDIS_VISIBLE;
+ int run_command(const Command & cmd) PALUDIS_VISIBLE;
/**
* Set the stderr and close for stdout fds used by run_command and
@@ -122,48 +141,6 @@ namespace paludis
* \ingroup grpsystem
*/
void set_run_command_stderr_fds(const int, const int) PALUDIS_VISIBLE;
-
- /**
- * Make a command that's run in a particular environment.
- */
- class PALUDIS_VISIBLE MakeEnvCommand
- {
- private:
- std::string cmd;
- std::string args;
-
- public:
- ///\name Basic operations
- ///\{
-
- explicit MakeEnvCommand(const std::string &, const std::string &);
-
- ///\}
-
- /**
- * Add some environment.
- */
- MakeEnvCommand operator() (const std::string &, const std::string &) const;
-
- /**
- * Turn ourself into a command string.
- */
- operator std::string() const;
- };
-
- /**
- * Make a command, with environment.
- *
- * \ingroup grpsystem
- */
- const MakeEnvCommand make_env_command(const std::string & cmd) PALUDIS_VISIBLE;
-
- /**
- * Make a command that is run inside the sandbox, if sandbox is enabled.
- *
- * \ingroup grpsystem
- */
- const std::string make_sandbox_command(const std::string & cmd) PALUDIS_VISIBLE;
}
#endif
diff --git a/paludis/util/system_TEST.cc b/paludis/util/system_TEST.cc
index 2b24f0c..a5eae4b 100644
--- a/paludis/util/system_TEST.cc
+++ b/paludis/util/system_TEST.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ * Copyright (c) 2006, 2007 Ciaran McCreesh <ciaranm@ciaranm.org>
*
* This file is part of the Paludis package manager. Paludis is free software;
* you can redistribute it and/or modify it under the terms of the GNU General
@@ -117,9 +117,9 @@ namespace test_cases
FSEntry dir("system_TEST_dir");
TEST_CHECK(dir.is_directory());
- run_command_in_directory("touch in_directory", dir);
+ run_command(Command("touch in_directory").with_chdir(dir));
TEST_CHECK(FSEntry(dir / "in_directory").exists());
- run_command_in_directory("rm in_directory", dir);
+ run_command(Command("rm in_directory").with_chdir(dir));
TEST_CHECK(! FSEntry(dir / "in_directory").exists());
}
} test_run_command_in_directory;
@@ -134,24 +134,24 @@ namespace test_cases
void run()
{
- TEST_CHECK(0 != run_command(make_env_command("printenv PALUDUS_TEST_ENV_VAR")));
- TEST_CHECK(0 == run_command(make_env_command("bash -c '[[ -z $PALUDUS_TEST_ENV_VAR ]]'")));
- TEST_CHECK(0 == run_command(make_env_command("bash -c '[[ -z $PALUDUS_TEST_ENV_VAR ]]'")(
- "PALUDUS_TEST_ENV_VAR", "")));
- TEST_CHECK(0 == run_command(make_env_command("bash -c '[[ -n $PALUDUS_TEST_ENV_VAR ]]'")(
- "PALUDUS_TEST_ENV_VAR", "foo")));
- TEST_CHECK(0 != run_command(make_env_command("bash -c '[[ -z $PALUDUS_TEST_ENV_VAR ]]'")(
- "PALUDUS_TEST_ENV_VAR", "foo")));
- TEST_CHECK(0 != run_command(make_env_command("bash -c '[[ -n $PALUDUS_TEST_ENV_VAR ]]'")));
- TEST_CHECK(0 != run_command(make_env_command("bash -c '[[ -n $PALUDUS_TEST_ENV_VAR ]]'")(
- "PALUDUS_TEST_ENV_VAR", "")));
- TEST_CHECK(0 == run_command(make_env_command("bash -c '[[ $PALUDUS_TEST_ENV_VAR == foo ]]'")(
- "PALUDUS_TEST_ENV_VAR", "foo")));
- TEST_CHECK(0 != run_command(make_env_command("bash -c '[[ $PALUDUS_TEST_ENV_VAR == foo ]]'")));
- TEST_CHECK(0 != run_command(make_env_command("bash -c '[[ $PALUDUS_TEST_ENV_VAR == foo ]]'")(
- "PALUDUS_TEST_ENV_VAR", "")));
- TEST_CHECK(0 != run_command(make_env_command("bash -c '[[ $PALUDUS_TEST_ENV_VAR == foo ]]'")(
- "PALUDUS_TEST_ENV_VAR", "bar")));
+ TEST_CHECK(0 != run_command(("printenv PALUDUS_TEST_ENV_VAR")));
+ TEST_CHECK(0 == run_command(("bash -c '[[ -z $PALUDUS_TEST_ENV_VAR ]]'")));
+ TEST_CHECK(0 == run_command(Command("bash -c '[[ -z $PALUDUS_TEST_ENV_VAR ]]'")
+ .with_setenv("PALUDUS_TEST_ENV_VAR", "")));
+ TEST_CHECK(0 == run_command(Command("bash -c '[[ -n $PALUDUS_TEST_ENV_VAR ]]'")
+ .with_setenv("PALUDUS_TEST_ENV_VAR", "foo")));
+ TEST_CHECK(0 != run_command(Command("bash -c '[[ -z $PALUDUS_TEST_ENV_VAR ]]'")
+ .with_setenv("PALUDUS_TEST_ENV_VAR", "foo")));
+ TEST_CHECK(0 != run_command(("bash -c '[[ -n $PALUDUS_TEST_ENV_VAR ]]'")));
+ TEST_CHECK(0 != run_command(Command("bash -c '[[ -n $PALUDUS_TEST_ENV_VAR ]]'")
+ .with_setenv("PALUDUS_TEST_ENV_VAR", "")));
+ TEST_CHECK(0 == run_command(Command("bash -c '[[ $PALUDUS_TEST_ENV_VAR == foo ]]'")
+ .with_setenv("PALUDUS_TEST_ENV_VAR", "foo")));
+ TEST_CHECK(0 != run_command(("bash -c '[[ $PALUDUS_TEST_ENV_VAR == foo ]]'")));
+ TEST_CHECK(0 != run_command(Command("bash -c '[[ $PALUDUS_TEST_ENV_VAR == foo ]]'")
+ .with_setenv("PALUDUS_TEST_ENV_VAR", "")));
+ TEST_CHECK(0 != run_command(Command("bash -c '[[ $PALUDUS_TEST_ENV_VAR == foo ]]'")
+ .with_setenv("PALUDUS_TEST_ENV_VAR", "bar")));
}
} test_make_env_command;
@@ -165,12 +165,13 @@ namespace test_cases
void run()
{
- TEST_CHECK(0 == run_command(make_env_command(
+ TEST_CHECK(0 == run_command(Command(
"bash -c '[[ x$PALUDUS_TEST_ENV_VAR == \"x....\" ]]'")
- ("PALUDUS_TEST_ENV_VAR", "....")));
- TEST_CHECK(0 == run_command(make_env_command(
+ .with_setenv("PALUDUS_TEST_ENV_VAR", "....")));
+ TEST_CHECK(0 == run_command(Command(
"bash -c '[[ x$PALUDUS_TEST_ENV_VAR == \"x..'\"'\"'..\" ]]'")
- ("PALUDUS_TEST_ENV_VAR", "..'..")));
+ .with_setenv("PALUDUS_TEST_ENV_VAR", "..'..")));
}
} test_make_env_command_quotes;
}
+
diff --git a/src/clients/paludis/applets.cc b/src/clients/paludis/applets.cc
index 4aedb78..6a9a524 100644
--- a/src/clients/paludis/applets.cc
+++ b/src/clients/paludis/applets.cc
@@ -225,10 +225,9 @@ int do_list_sync_protocols()
s != s_end ; ++s)
{
std::cout << "* " << colour(cl_key_name, s->first) << std::endl;
- MakeEnvCommand cmd(make_env_command(s->second + " --help")
- ("PALUDIS_FETCHERS_DIRS", env->fetchers_dirs())
- ("PALUDIS_EBUILD_DIR", getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis")));
- run_command(cmd);
+ run_command(Command(s->second + " --help")
+ .with_setenv("PALUDIS_FETCHERS_DIRS", env->fetchers_dirs())
+ .with_setenv("PALUDIS_EBUILD_DIR", getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis")));
}
}