aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-12-31 21:47:26 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-12-31 21:47:26 +0000
commit5af96b9e2a15827bc49e24af497571b45959ca6a (patch)
tree5d08aefa82f86fa33a42546b91321460a74ff8a3
parent6d95e48cbd418ee7a49bceeae864c41eba31eeb3 (diff)
downloadpaludis-5af96b9e2a15827bc49e24af497571b45959ca6a.tar.gz
paludis-5af96b9e2a15827bc49e24af497571b45959ca6a.tar.xz
Switch to using pipes to implement has_version etc.
-rw-r--r--paludis/repositories/e/e_repository_TEST.cc80
-rwxr-xr-xpaludis/repositories/e/e_repository_TEST_setup.sh194
-rw-r--r--paludis/repositories/e/eapi-fwd.hh1
-rw-r--r--paludis/repositories/e/eapi.cc5
-rw-r--r--paludis/repositories/e/eapi.sr10
-rw-r--r--paludis/repositories/e/eapis/0.conf3
-rw-r--r--paludis/repositories/e/eapis/1.conf2
-rw-r--r--paludis/repositories/e/eapis/exheres-0.conf3
-rw-r--r--paludis/repositories/e/eapis/paludis-1.conf3
-rw-r--r--paludis/repositories/e/ebuild.cc206
-rw-r--r--paludis/repositories/e/ebuild.hh5
-rwxr-xr-xpaludis/repositories/e/ebuild/ebuild.bash39
-rw-r--r--paludis/repositories/e/ebuild/echo_functions.bash.in39
-rw-r--r--paludis/repositories/e/ebuild/exheres-0/echo_functions.bash.in39
-rwxr-xr-xpaludis/repositories/e/ebuild/exheres-0/portage_stubs.bash9
-rw-r--r--paludis/repositories/e/ebuild/portage_stubs.bash29
-rwxr-xr-xpaludis/repositories/e/ebuild/run_test.bash10
-rw-r--r--paludis/repositories/e/ebuild/utils/Makefile.am5
-rw-r--r--paludis/repositories/e/ebuild/utils/locked_pipe_command.cc107
-rw-r--r--paludis/util/system.cc8
-rwxr-xr-xpaludis/util/system_TEST_setup.sh51
21 files changed, 743 insertions, 105 deletions
diff --git a/paludis/repositories/e/e_repository_TEST.cc b/paludis/repositories/e/e_repository_TEST.cc
index 1ef4956..db07461 100644
--- a/paludis/repositories/e/e_repository_TEST.cc
+++ b/paludis/repositories/e/e_repository_TEST.cc
@@ -23,6 +23,8 @@
#include <paludis/repositories/e/eapi.hh>
#include <paludis/repositories/e/dep_spec_pretty_printer.hh>
#include <paludis/repositories/fake/fake_installed_repository.hh>
+#include <paludis/repositories/fake/fake_package_id.hh>
+#include <paludis/repository_maker.hh>
#include <paludis/environments/test/test_environment.hh>
#include <paludis/util/system.hh>
#include <paludis/util/visitor-impl.hh>
@@ -1039,6 +1041,7 @@ namespace test_cases
void run()
{
TestEnvironment env;
+
tr1::shared_ptr<Map<std::string, std::string> > keys(new Map<std::string, std::string>);
keys->insert("format", "ebuild");
keys->insert("names_cache", "/var/empty");
@@ -1054,8 +1057,16 @@ namespace test_cases
env.package_database()->add_repository(1, repo);
tr1::shared_ptr<FakeInstalledRepository> installed_repo(new FakeInstalledRepository(&env, RepositoryName("installed")));
+ installed_repo->add_version("cat", "pretend-installed", "0")->provide_key()->set_from_string("virtual/virtual-pretend-installed");
+ installed_repo->add_version("cat", "pretend-installed", "1")->provide_key()->set_from_string("virtual/virtual-pretend-installed");
env.package_database()->add_repository(2, installed_repo);
+ tr1::shared_ptr<Map<std::string, std::string> > iv_keys(new Map<std::string, std::string>);
+ iv_keys->insert("root", "/");
+ env.package_database()->add_repository(-2, RepositoryMaker::get_instance()->find_maker("installed_virtuals")(&env, iv_keys));
+ env.package_database()->add_repository(-2, RepositoryMaker::get_instance()->find_maker("virtuals")(&env,
+ tr1::shared_ptr<Map<std::string, std::string> >()));
+
InstallAction action(InstallActionOptions::create()
.debug_build(iado_none)
.checks(iaco_default)
@@ -1064,6 +1075,13 @@ namespace test_cases
);
{
+ const tr1::shared_ptr<const PackageID> id(*env.package_database()->query(query::Matches(
+ PackageDepSpec(parse_user_package_dep_spec("=virtual/virtual-pretend-installed-0",
+ UserPackageDepSpecOptions()))), qo_require_exactly_one)->last());
+ TEST_CHECK(id);
+ }
+
+ {
TestMessageSuffix suffix("in-ebuild die", true);
const tr1::shared_ptr<const PackageID> id(*env.package_database()->query(query::Matches(
PackageDepSpec(parse_user_package_dep_spec("cat/in-ebuild-die",
@@ -1117,6 +1135,33 @@ namespace test_cases
TEST_CHECK_EQUAL(visitor_cast<const MetadataStringKey>(**id->find_metadata("EAPI"))->value(), "0");
TEST_CHECK_THROWS(id->perform_action(action), InstallActionError);
}
+
+ {
+ TestMessageSuffix suffix("best version", true);
+ const tr1::shared_ptr<const PackageID> id(*env.package_database()->query(query::Matches(
+ PackageDepSpec(parse_user_package_dep_spec("=cat/best-version-0",
+ UserPackageDepSpecOptions()))), qo_require_exactly_one)->last());
+ TEST_CHECK(id);
+ id->perform_action(action);
+ }
+
+ {
+ TestMessageSuffix suffix("has version", true);
+ const tr1::shared_ptr<const PackageID> id(*env.package_database()->query(query::Matches(
+ PackageDepSpec(parse_user_package_dep_spec("=cat/has-version-0",
+ UserPackageDepSpecOptions()))), qo_require_exactly_one)->last());
+ TEST_CHECK(id);
+ id->perform_action(action);
+ }
+
+ {
+ TestMessageSuffix suffix("match", true);
+ const tr1::shared_ptr<const PackageID> id(*env.package_database()->query(query::Matches(
+ PackageDepSpec(parse_user_package_dep_spec("=cat/match-0",
+ UserPackageDepSpecOptions()))), qo_require_exactly_one)->last());
+ TEST_CHECK(id);
+ id->perform_action(action);
+ }
}
} test_e_repository_install_eapi_0;
@@ -1195,8 +1240,16 @@ namespace test_cases
env.package_database()->add_repository(1, repo);
tr1::shared_ptr<FakeInstalledRepository> installed_repo(new FakeInstalledRepository(&env, RepositoryName("installed")));
+ installed_repo->add_version("cat", "pretend-installed", "0")->provide_key()->set_from_string("virtual/virtual-pretend-installed");
+ installed_repo->add_version("cat", "pretend-installed", "1")->provide_key()->set_from_string("virtual/virtual-pretend-installed");
env.package_database()->add_repository(2, installed_repo);
+ tr1::shared_ptr<Map<std::string, std::string> > iv_keys(new Map<std::string, std::string>);
+ iv_keys->insert("root", "/");
+ env.package_database()->add_repository(-2, RepositoryMaker::get_instance()->find_maker("installed_virtuals")(&env, iv_keys));
+ env.package_database()->add_repository(-2, RepositoryMaker::get_instance()->find_maker("virtuals")(&env,
+ tr1::shared_ptr<Map<std::string, std::string> >()));
+
InstallAction action(InstallActionOptions::create()
.debug_build(iado_none)
.checks(iaco_default)
@@ -1248,6 +1301,33 @@ namespace test_cases
TEST_CHECK(id);
TEST_CHECK_THROWS(id->perform_action(action), InstallActionError);
}
+
+ {
+ TestMessageSuffix suffix("best version", true);
+ const tr1::shared_ptr<const PackageID> id(*env.package_database()->query(query::Matches(
+ PackageDepSpec(parse_user_package_dep_spec("=cat/best-version-0",
+ UserPackageDepSpecOptions()))), qo_require_exactly_one)->last());
+ TEST_CHECK(id);
+ id->perform_action(action);
+ }
+
+ {
+ TestMessageSuffix suffix("has version", true);
+ const tr1::shared_ptr<const PackageID> id(*env.package_database()->query(query::Matches(
+ PackageDepSpec(parse_user_package_dep_spec("=cat/has-version-0",
+ UserPackageDepSpecOptions()))), qo_require_exactly_one)->last());
+ TEST_CHECK(id);
+ id->perform_action(action);
+ }
+
+ {
+ TestMessageSuffix suffix("match", true);
+ const tr1::shared_ptr<const PackageID> id(*env.package_database()->query(query::Matches(
+ PackageDepSpec(parse_user_package_dep_spec("=cat/match-0",
+ UserPackageDepSpecOptions()))), qo_require_exactly_one)->last());
+ TEST_CHECK(id);
+ TEST_CHECK_THROWS(id->perform_action(action), InstallActionError);
+ }
}
} test_e_repository_install_exheres_0;
}
diff --git a/paludis/repositories/e/e_repository_TEST_setup.sh b/paludis/repositories/e/e_repository_TEST_setup.sh
index 60f5c84..04e86e5 100755
--- a/paludis/repositories/e/e_repository_TEST_setup.sh
+++ b/paludis/repositories/e/e_repository_TEST_setup.sh
@@ -4,6 +4,9 @@
mkdir e_repository_TEST_dir || exit 1
cd e_repository_TEST_dir || exit 1
+mkdir -p vdb
+touch vdb/THISISTHEVDB
+
mkdir -p build
mkdir -p distdir
@@ -477,6 +480,10 @@ mkdir -p repo13/{profiles/profile,metadata,eclass} || exit 1
cd repo13 || exit 1
echo "test-repo-13" >> profiles/repo_name || exit 1
echo "cat" >> profiles/categories || exit 1
+cat <<END > profiles/profile/virtuals
+virtual/virtual-pretend-installed cat/pretend-installed
+virtual/virtual-doesnotexist cat/doesnotexist
+END
cat <<END > profiles/profile/make.defaults
ARCH="test"
USERLAND="GNU"
@@ -556,6 +563,20 @@ src_compile() {
emake monkey
}
END
+mkdir -p "cat/pretend-installed"
+cat <<END > cat/pretend-installed/pretend-installed-2.ebuild || exit 1
+DESCRIPTION="The Description"
+HOMEPAGE="http://example.com/"
+SRC_URI=""
+SLOT="0"
+IUSE="spork"
+LICENSE="GPL-2"
+KEYWORDS="test"
+
+src_compile() {
+ die "not supposed to install this"
+}
+END
mkdir -p "cat/econf-source"
cat <<END > cat/econf-source/econf-source-0.ebuild || exit 1
EAPI="\${PV}"
@@ -582,11 +603,107 @@ src_install() {
}
END
cp cat/econf-source/econf-source-{0,1}.ebuild || exit 1
+mkdir -p "cat/best-version"
+cat <<'END' > cat/best-version/best-version-0.ebuild || exit 1
+DESCRIPTION="The Description"
+HOMEPAGE="http://example.com/"
+SRC_URI=""
+SLOT="0"
+IUSE="spork"
+LICENSE="GPL-2"
+KEYWORDS="test"
+
+pkg_setup() {
+ if ! best_version cat/pretend-installed >/dev/null ; then
+ die "failed cat/pretend-installed"
+ fi
+
+ BV1=$(best_version cat/pretend-installed )
+ [[ "$BV1" == "cat/pretend-installed-1" ]] || die "BV1 is $BV1"
+
+ if best_version cat/doesnotexist >/dev/null ; then
+ die "not failed cat/doesnotexist"
+ fi
+
+ BV2=$(best_version cat/doesnotexist )
+ [[ "$BV2" == "" ]] || die "BV2 is $BV2"
+
+ if ! best_version virtual/virtual-pretend-installed >/dev/null ; then
+ die "failed virtual/virtual-pretend-installed"
+ fi
+
+ BV3=$(best_version virtual/virtual-pretend-installed )
+ [[ "$BV3" == "cat/pretend-installed-1" ]] || die "BV3 is $BV3"
+
+ if best_version virtual/virtual-doesnotexist >/dev/null ; then
+ die "not failed virtual/virtual-doesnotexist"
+ fi
+
+ BV2=$(best_version virtual/virtual-doesnotexist )
+ [[ "$BV4" == "" ]] || die "BV4 is $BV4"
+}
+END
+mkdir -p "cat/has-version"
+cat <<'END' > cat/has-version/has-version-0.ebuild || exit 1
+EAPI="${PV}"
+DESCRIPTION="The Description"
+HOMEPAGE="http://example.com/"
+SRC_URI=""
+SLOT="0"
+IUSE="spork"
+LICENSE="GPL-2"
+KEYWORDS="test"
+
+pkg_setup() {
+ if ! has_version cat/pretend-installed ; then
+ die "failed cat/pretend-installed"
+ fi
+
+ if has_version cat/doesnotexist >/dev/null ; then
+ die "not failed cat/doesnotexist"
+ fi
+}
+END
+mkdir -p "cat/match"
+cat <<'END' > cat/match/match-0.ebuild || exit 1
+EAPI="${PV}"
+DESCRIPTION="The Description"
+HOMEPAGE="http://example.com/"
+SRC_URI=""
+SLOT="0"
+IUSE="spork"
+LICENSE="GPL-2"
+KEYWORDS="test"
+
+pkg_setup() {
+ if ! portageq match "${ROOT}" cat/pretend-installed >/dev/null ; then
+ die "failed cat/pretend-installed"
+ fi
+
+ cat <<'DONE' > ${T}/expected
+cat/pretend-installed-0
+cat/pretend-installed-1
+DONE
+ portageq match "${ROOT}" cat/pretend-installed > ${T}/got
+ cmp ${T}/expected ${T}/got || die "oops"
+
+ if portageq match "${ROOT}" cat/doesnotexist >/dev/null ; then
+ die "not failed cat/doesnotexist"
+ fi
+
+ BV2=$(portageq match "${ROOT}" cat/doesnotexist )
+ [[ "$BV2" == "" ]] || die "BV2 is $BV2"
+}
+END
cd ..
mkdir -p repo14/{profiles/profile,metadata,eclass} || exit 1
cd repo14 || exit 1
echo "test-repo-14" >> profiles/repo_name || exit 1
+cat <<END > profiles/profile/virtuals
+virtual/virtual-pretend-installed cat/pretend-installed
+virtual/virtual-doesnotexist cat/doesnotexist
+END
echo "cat" >> metadata/categories.conf || exit 1
cat <<END > profiles/profile/make.defaults
CHOST="i286-badger-linux-gnu"
@@ -663,6 +780,83 @@ src_compile() {
emake monkey
}
END
+mkdir -p "packages/cat/best-version"
+cat <<'END' > packages/cat/best-version/best-version-0.ebuild || exit 1
+DESCRIPTION="The Description"
+HOMEPAGE="http://example.com/"
+SRC_URI=""
+SLOT="0"
+MYOPTIONS="spork"
+LICENSE="GPL-2"
+PLATFORMS="test"
+
+pkg_setup() {
+ if ! best_version cat/pretend-installed >/dev/null ; then
+ die "failed cat/pretend-installed"
+ fi
+
+ BV1=$(best_version cat/pretend-installed )
+ [[ "$BV1" == "cat/pretend-installed-1:0::installed" ]] || die "BV1 is $BV1"
+
+ if best_version cat/doesnotexist >/dev/null ; then
+ die "not failed cat/doesnotexist"
+ fi
+
+ BV2=$(best_version cat/doesnotexist )
+ [[ "$BV2" == "" ]] || die "BV2 is $BV2"
+
+ if ! best_version virtual/virtual-pretend-installed >/dev/null ; then
+ die "failed virtual/virtual-pretend-installed"
+ fi
+
+ BV3=$(best_version virtual/virtual-pretend-installed )
+ [[ "$BV3" == "virtual/virtual-pretend-installed-1::installed-virtuals (virtual for cat/pretend-installed-1:0::installed)" ]] \
+ || die "BV3 is $BV3"
+
+ if best_version virtual/virtual-doesnotexist >/dev/null ; then
+ die "not failed virtual/virtual-doesnotexist"
+ fi
+
+ BV2=$(best_version virtual/virtual-doesnotexist )
+ [[ "$BV4" == "" ]] || die "BV4 is $BV4"
+}
+END
+mkdir -p "packages/cat/has-version"
+cat <<'END' > packages/cat/has-version/has-version-0.ebuild || exit 1
+DESCRIPTION="The Description"
+HOMEPAGE="http://example.com/"
+SRC_URI=""
+SLOT="0"
+MYOPTIONS="spork"
+LICENSE="GPL-2"
+PLATFORMS="test"
+
+pkg_setup() {
+ if ! has_version cat/pretend-installed ; then
+ die "failed cat/pretend-installed"
+ fi
+
+ if has_version cat/doesnotexist >/dev/null ; then
+ die "not failed cat/doesnotexist"
+ fi
+}
+END
+mkdir -p "packages/cat/match"
+cat <<'END' > packages/cat/match/match-0.ebuild || exit 1
+DESCRIPTION="The Description"
+HOMEPAGE="http://example.com/"
+SRC_URI=""
+SLOT="0"
+MYOPTIONS="spork"
+LICENSE="GPL-2"
+PLATFORM="test"
+
+pkg_setup() {
+ portageq match "${ROOT}" cat/foo | while read a ; do
+ einfo moo
+ done
+}
+END
cd ..
mkdir -p repo15/{eclass,distfiles,profiles/profile/subprofile} || exit 1
diff --git a/paludis/repositories/e/eapi-fwd.hh b/paludis/repositories/e/eapi-fwd.hh
index 416d9ba..0ca85cd 100644
--- a/paludis/repositories/e/eapi-fwd.hh
+++ b/paludis/repositories/e/eapi-fwd.hh
@@ -33,6 +33,7 @@ namespace paludis
class EAPIEbuildEnvironmentVariables;
class EAPIEbuildOptions;
class EAPILabels;
+ class EAPIPipeCommands;
}
}
diff --git a/paludis/repositories/e/eapi.cc b/paludis/repositories/e/eapi.cc
index cff9a56..c0ed107 100644
--- a/paludis/repositories/e/eapi.cc
+++ b/paludis/repositories/e/eapi.cc
@@ -122,6 +122,11 @@ namespace paludis
.restrict_primaryuri(make_shared_ptr(new Set<std::string>))
)))
+ .pipe_commands(make_shared_ptr(new EAPIPipeCommands(
+ EAPIPipeCommands::create()
+ .rewrite_virtuals(destringify<bool>(k.get("pipe_commands_rewrite_virtuals")))
+ .no_slot_or_repo(destringify<bool>(k.get("pipe_commands_no_slot_or_repo"))))))
+
.ebuild_phases(make_shared_ptr(new EAPIEbuildPhases(
EAPIEbuildPhases::create()
.ebuild_install(k.get("ebuild_install"))
diff --git a/paludis/repositories/e/eapi.sr b/paludis/repositories/e/eapi.sr
index 4165ff0..44f3a29 100644
--- a/paludis/repositories/e/eapi.sr
+++ b/paludis/repositories/e/eapi.sr
@@ -148,6 +148,15 @@ make_class_EAPIEbuildOptions()
END
}
+make_class_EAPIPipeCommands()
+{
+ visible
+ allow_named_args cc
+
+ key rewrite_virtuals bool
+ key no_slot_or_repo bool
+}
+
make_class_SupportedEAPI()
{
visible
@@ -166,6 +175,7 @@ make_class_SupportedEAPI()
key ebuild_environment_variables "tr1::shared_ptr<const EAPIEbuildEnvironmentVariables>"
key uri_labels "tr1::shared_ptr<const EAPILabels>"
key dependency_labels "tr1::shared_ptr<const EAPILabels>"
+ key pipe_commands "tr1::shared_ptr<const EAPIPipeCommands>"
doxygen_comment << "END"
/**
diff --git a/paludis/repositories/e/eapis/0.conf b/paludis/repositories/e/eapis/0.conf
index 571f457..c5811c6 100644
--- a/paludis/repositories/e/eapis/0.conf
+++ b/paludis/repositories/e/eapis/0.conf
@@ -154,3 +154,6 @@ restrict_mirror = mirror nomirror
restrict_fetch = fetch nofetch
restrict_primaryuri = primaryuri
+pipe_commands_rewrite_virtuals = true
+pipe_commands_no_slot_or_repo = true
+
diff --git a/paludis/repositories/e/eapis/1.conf b/paludis/repositories/e/eapis/1.conf
index ed6ab9c..4cef6c3 100644
--- a/paludis/repositories/e/eapis/1.conf
+++ b/paludis/repositories/e/eapis/1.conf
@@ -154,4 +154,6 @@ restrict_mirror = mirror nomirror
restrict_fetch = fetch nofetch
restrict_primaryuri = primaryuri
+pipe_commands_rewrite_virtuals = true
+pipe_commands_no_slot_or_repo = true
diff --git a/paludis/repositories/e/eapis/exheres-0.conf b/paludis/repositories/e/eapis/exheres-0.conf
index 32abdf9..5db485a 100644
--- a/paludis/repositories/e/eapis/exheres-0.conf
+++ b/paludis/repositories/e/eapis/exheres-0.conf
@@ -174,3 +174,6 @@ restrict_mirror = mirror
restrict_fetch = fetch
restrict_primaryuri =
+pipe_commands_rewrite_virtuals = false
+pipe_commands_no_slot_or_repo = false
+
diff --git a/paludis/repositories/e/eapis/paludis-1.conf b/paludis/repositories/e/eapis/paludis-1.conf
index 41c741a..1975567 100644
--- a/paludis/repositories/e/eapis/paludis-1.conf
+++ b/paludis/repositories/e/eapis/paludis-1.conf
@@ -169,3 +169,6 @@ restrict_mirror = mirror
restrict_fetch = fetch
restrict_primaryuri =
+pipe_commands_rewrite_virtuals = true
+pipe_commands_no_slot_or_repo = false
+
diff --git a/paludis/repositories/e/ebuild.cc b/paludis/repositories/e/ebuild.cc
index 35284cc..eafea98 100644
--- a/paludis/repositories/e/ebuild.cc
+++ b/paludis/repositories/e/ebuild.cc
@@ -22,6 +22,7 @@
#include <paludis/repositories/e/e_repository.hh>
#include <paludis/repositories/e/eapi.hh>
#include <paludis/repositories/e/dep_parser.hh>
+#include <paludis/repositories/e/package_dep_spec.hh>
#include <paludis/util/system.hh>
#include <paludis/util/strip.hh>
@@ -33,6 +34,13 @@
#include <paludis/util/tokeniser.hh>
#include <paludis/util/wrapped_forward_iterator.hh>
#include <paludis/util/wrapped_output_iterator.hh>
+#include <paludis/util/tr1_functional.hh>
+#include <paludis/util/iterator_funcs.hh>
+#include <paludis/util/destringify.hh>
+#include <paludis/util/indirect_iterator-impl.hh>
+#include <paludis/util/visitor_cast.hh>
+#include <paludis/util/visitor-impl.hh>
+#include <paludis/util/set.hh>
#include <paludis/about.hh>
#include <paludis/environment.hh>
@@ -46,6 +54,7 @@
#include <unistd.h>
#include <list>
+#include <vector>
#include "config.h"
@@ -93,6 +102,8 @@ EbuildCommand::operator() ()
if (params.userpriv)
cmd.with_uid_gid(params.environment->reduced_uid(), params.environment->reduced_gid());
+ using namespace tr1::placeholders;
+ cmd.with_pipe_command_handler(tr1::bind(tr1::mem_fn(&EbuildCommand::pipe_command_handler), this, _1));
tr1::shared_ptr<const FSEntrySequence> syncers_dirs(params.environment->syncers_dirs());
tr1::shared_ptr<const FSEntrySequence> bashrc_files(params.environment->bashrc_files());
@@ -217,6 +228,201 @@ EbuildCommand::do_run_command(const Command & cmd)
return 0 == run_command(cmd);
}
+namespace
+{
+ std::string name_and_version(const PackageID & id)
+ {
+ return stringify(id.name()) + "-" + stringify(id.version());
+ }
+}
+
+std::string
+EbuildCommand::pipe_command_handler(const std::string & s) const
+{
+ Context context("In ebuild pipe command handler for '" + s + "':");
+
+ try
+ {
+ std::vector<std::string> tokens;
+ tokenise_whitespace(s, std::back_inserter(tokens));
+ if (tokens.empty())
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Got empty pipe command";
+ return "Eempty pipe command";
+ }
+
+ if (tokens[0] == "PING")
+ {
+ if (tokens.size() != 3)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Got bad PING command";
+ return "Ebad PING command";
+ }
+ else
+ return "OPONG " + tokens[2];
+ }
+ else if (tokens[0] == "LOG")
+ {
+ if (tokens.size() < 4)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Got too short LOG pipe command";
+ return "Ebad LOG command";
+ }
+ else
+ {
+ Log::get_instance()->message(destringify<LogLevel>(tokens[2]), lc_context) << join(next(next(next(tokens.begin()))),
+ tokens.end(), " ");
+ return "O";
+ }
+ }
+ else if (tokens[0] == "BEST_VERSION")
+ {
+ if (tokens.size() != 3)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Got bad BEST_VERSION pipe command";
+ return "Ebad BEST_VERSION command";
+ }
+ else
+ {
+ tr1::shared_ptr<const EAPI> eapi(EAPIData::get_instance()->eapi_from_string(tokens[1]));
+ if (! eapi->supported)
+ return "EBEST_VERSION EAPI " + tokens[1] + " unsupported";
+
+ PackageDepSpec spec(erepository::parse_e_package_dep_spec(tokens[2], *eapi, params.package_id));
+ tr1::shared_ptr<const PackageIDSequence> entries(params.environment->package_database()->query(
+ query::Matches(spec) & query::InstalledAtRoot(params.environment->root()), qo_order_by_version));
+ if (eapi->supported->pipe_commands->rewrite_virtuals && (! entries->empty()) &&
+ (*entries->last())->virtual_for_key())
+ {
+ Log::get_instance()->message(ll_qa, lc_context) << "best-version of '" << spec <<
+ "' resolves to '" << **entries->last() << "', which is a virtual for '"
+ << *(*entries->last())->virtual_for_key()->value() << "'. This will break with "
+ "new style virtuals.";
+ tr1::shared_ptr<PackageIDSequence> new_entries(new PackageIDSequence);
+ new_entries->push_back((*entries->last())->virtual_for_key()->value());
+ entries = new_entries;
+ }
+
+ if (entries->empty())
+ return "O1;";
+ else
+ {
+ if (eapi->supported->pipe_commands->no_slot_or_repo)
+ return "O0;" + name_and_version(**entries->last());
+ else
+ return "O0;" + stringify(**entries->last());
+ }
+ }
+ }
+ else if (tokens[0] == "HAS_VERSION")
+ {
+ if (tokens.size() != 3)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Got bad HAS_VERSION pipe command";
+ return "Ebad HAS_VERSION command";
+ }
+ else
+ {
+ tr1::shared_ptr<const EAPI> eapi(EAPIData::get_instance()->eapi_from_string(tokens[1]));
+ if (! eapi->supported)
+ return "EHAS_VERSION EAPI " + tokens[1] + " unsupported";
+
+ PackageDepSpec spec(erepository::parse_e_package_dep_spec(tokens[2], *eapi, params.package_id));
+ tr1::shared_ptr<const PackageIDSequence> entries(params.environment->package_database()->query(
+ query::Matches(spec) & query::InstalledAtRoot(params.environment->root()), qo_order_by_version));
+ if (entries->empty())
+ return "O1;";
+ else
+ return "O0;";
+ }
+ }
+ else if (tokens[0] == "MATCH")
+ {
+ if (tokens.size() != 3)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Got bad MATCH pipe command";
+ return "Ebad MATCH command";
+ }
+ else
+ {
+ tr1::shared_ptr<const EAPI> eapi(EAPIData::get_instance()->eapi_from_string(tokens[1]));
+ if (! eapi->supported)
+ return "EMATCH EAPI " + tokens[1] + " unsupported";
+
+ PackageDepSpec spec(erepository::parse_e_package_dep_spec(tokens[2], *eapi, params.package_id));
+ tr1::shared_ptr<const PackageIDSequence> entries(params.environment->package_database()->query(
+ query::Matches(spec) & query::InstalledAtRoot(params.environment->root()), qo_order_by_version));
+ if (eapi->supported->pipe_commands->rewrite_virtuals && (! entries->empty()))
+ {
+ tr1::shared_ptr<PackageIDSequence> new_entries(new PackageIDSequence);
+ for (PackageIDSequence::ConstIterator i(entries->begin()), i_end(entries->end()) ;
+ i != i_end ; ++i)
+ {
+ if ((*i)->virtual_for_key())
+ {
+ Log::get_instance()->message(ll_qa, lc_context) << "match of '" << spec <<
+ "' resolves to '" << **i << "', which is a virtual for '"
+ << *(*i)->virtual_for_key()->value() << "'. This will break with "
+ "new style virtuals.";
+ new_entries->push_back((*i)->virtual_for_key()->value());
+ }
+ else
+ new_entries->push_back(*i);
+ }
+ entries = new_entries;
+ }
+
+ if (entries->empty())
+ return "O1;";
+ else
+ {
+ if (eapi->supported->pipe_commands->no_slot_or_repo)
+ return "O0;" + join(indirect_iterator(entries->begin()), indirect_iterator(entries->end()), "\n", &name_and_version);
+ else
+ return "O0;" + join(indirect_iterator(entries->begin()), indirect_iterator(entries->end()), "\n");
+ }
+ }
+ }
+ else if (tokens[0] == "VDB_PATH")
+ {
+ if (tokens.size() != 2)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Got bad VDB_PATH pipe command";
+ return "Ebad VDB_PATH command";
+ }
+ else
+ {
+ if (! params.environment->package_database()->has_repository_named(RepositoryName("installed")))
+ return "Eno installed repository available";
+ tr1::shared_ptr<const Repository> repo(params.environment->package_database()->fetch_repository(RepositoryName("installed")));
+ Repository::MetadataConstIterator key(repo->find_metadata("location"));
+ if (repo->end_metadata() == key)
+ return "Einstalled repository has no location key";
+ if (! visitor_cast<const MetadataFSEntryKey>(**key))
+ return "Einstalled repository location key is not a MetadataFSEntryKey";
+ return "O0;" + stringify(visitor_cast<const MetadataFSEntryKey>(**key)->value());
+ }
+ }
+ else
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Got unknown ebuild pipe command '" + s + "'";
+ return "Eunknown pipe command";
+ }
+ }
+ catch (const Exception & e)
+ {
+ return "Eexception '" + e.message() + "' (" + e.what() + ")";
+ }
+ catch (const std::exception & e)
+ {
+ return "Eexception " + stringify(e.what());
+ }
+ catch (...)
+ {
+ return "Eexception ???";
+ }
+}
+
EbuildMetadataCommand::EbuildMetadataCommand(const EbuildCommandParams & p) :
EbuildCommand(p)
{
diff --git a/paludis/repositories/e/ebuild.hh b/paludis/repositories/e/ebuild.hh
index 9101c6d..e1c6cb9 100644
--- a/paludis/repositories/e/ebuild.hh
+++ b/paludis/repositories/e/ebuild.hh
@@ -112,6 +112,11 @@ namespace paludis
*/
virtual Command extend_command(const Command &) = 0;
+ /**
+ * Pipe command handler.
+ */
+ virtual std::string pipe_command_handler(const std::string &) const;
+
public:
/**
* Destructor.
diff --git a/paludis/repositories/e/ebuild/ebuild.bash b/paludis/repositories/e/ebuild/ebuild.bash
index 260b503..f2b3763 100755
--- a/paludis/repositories/e/ebuild/ebuild.bash
+++ b/paludis/repositories/e/ebuild/ebuild.bash
@@ -94,6 +94,38 @@ ebuild_load_module()
exit 123
}
+paludis_pipe_command()
+{
+ [[ -n "${PALUDIS_SKIP_PIPE_COMMAND_CHECK}" ]] && return
+
+ [[ -z "${PALUDIS_PIPE_COMMAND_WRITE_FD}" ]] && die "PALUDIS_PIPE_COMMAND_WRITE_FD unset"
+ [[ -z "${PALUDIS_PIPE_COMMAND_READ_FD}" ]] && die "PALUDIS_PIPE_COMMAND_READ_FD unset"
+
+ local r r1 rest
+ r="$(echo "$@" | {
+ if ! locked_pipe_command "${PALUDIS_PIPE_COMMAND_WRITE_FD}" "${PALUDIS_PIPE_COMMAND_READ_FD}" ; then
+ # die might not be available yet
+ die "locked_pipe_command failed"
+
+ echo "!!! locked_pipe_command failed, and no die available yet" 1>&2
+ kill -s SIGUSR1 "${EBUILD_KILL_PID}"
+ exit 249
+ fi
+ })"
+
+ r1="${r:0:1}"
+ rest="${r:1}"
+ if [[ "${r1}" != "O" ]] ; then
+ die "paludis_pipe_command returned error '${r1}' with text '${rest}'"
+
+ echo "!!! paludis_pipe_command returned error '${r1}' with text '${rest}', and no die available yet" 1>&2
+ kill -s SIGUSR1 "${EBUILD_KILL_PID}"
+ exit 249
+ fi
+
+ echo "$rest"
+}
+
ebuild_load_module die_functions
ebuild_load_module echo_functions
ebuild_load_module kernel_functions
@@ -107,6 +139,11 @@ ebuild_load_module eclass_functions
ebuild_load_module exlib_functions
ebuild_load_module source_functions
+if [[ -z "${PALUDIS_SKIP_PIPE_COMMAND_CHECK}" ]] ; then
+ pcr=$(paludis_pipe_command PING DUNNOYET $$ )
+ [[ "$pcr" == "PONG $$" ]] || die "paludis_pipe_command isn't working (got '$pcr')"
+fi
+
export PALUDIS_HOME="$(canonicalise ${PALUDIS_HOME:-${HOME}} )"
ebuild_source_profile()
@@ -203,7 +240,7 @@ ebuild_scrub_environment()
ebuild_safe_source "${1}" PATH PALUDIS_SOURCE_MERGED_VARIABLES || exit 1
unset -f diefunc perform_hook inherit builtin_loadenv builtin_saveenv
- unset -f ebuild_safe_source portageq best_version has_version
+ unset -f ebuild_safe_source portageq best_version has_version paludis_pipe_command
unset -v ROOTPATH T HOME TMPDIR PALUDIS_TMPDIR PALUDIS_EBUILD_LOG_LEVEL
unset -v PORTDIR FILESDIR ECLASSDIR DISTDIR PALUDIS_EBUILD_DIR
diff --git a/paludis/repositories/e/ebuild/echo_functions.bash.in b/paludis/repositories/e/ebuild/echo_functions.bash.in
index a759bd4..1b2ef24 100644
--- a/paludis/repositories/e/ebuild/echo_functions.bash.in
+++ b/paludis/repositories/e/ebuild/echo_functions.bash.in
@@ -189,46 +189,9 @@ use_enable()
fi
}
-ebuild_notice_level()
-{
- case "$1" in
- debug)
- echo "1";
- ;;
-
- qa)
- echo "2";
- ;;
-
- warning)
- echo "3";
- ;;
-
- silent)
- echo "4";
- ;;
-
- *)
- echo "[WARNING.EBUILD] Bad value '$1' for qa level" 1>&2
- echo "2";
- ;;
- esac
-}
-
ebuild_notice()
{
- local level="$1"
- shift
-
- local level_num=$(ebuild_notice_level "${level}" )
- local min_level_num=$(ebuild_notice_level "${PALUDIS_EBUILD_LOG_LEVEL}" )
-
- if [[ "${level_num}" -ge "${min_level_num}" ]] ; then
- local upper_level=$(echo ${level} | ${ebuild_real_tr:-tr} '[:lower:]' '[:upper:]' )
- echo -n "${EBUILD_PROGRAM_NAME:-ebuild.bash}@$(${ebuild_real_date:-date} +%s ): " 1>&2
- echo "[${upper_level}.EBUILD] $* (from ${EBUILD:-?})" 1>&2
- fi
- true
+ paludis_pipe_command LOG "$EAPI" "$@" >/dev/null
}
ebuild_section()
diff --git a/paludis/repositories/e/ebuild/exheres-0/echo_functions.bash.in b/paludis/repositories/e/ebuild/exheres-0/echo_functions.bash.in
index 664cd7b..23645fa 100644
--- a/paludis/repositories/e/ebuild/exheres-0/echo_functions.bash.in
+++ b/paludis/repositories/e/ebuild/exheres-0/echo_functions.bash.in
@@ -199,46 +199,9 @@ option_enable()
fi
}
-ebuild_notice_level()
-{
- case "$1" in
- debug)
- echo "1";
- ;;
-
- qa)
- echo "2";
- ;;
-
- warning)
- echo "3";
- ;;
-
- silent)
- echo "4";
- ;;
-
- *)
- echo "[WARNING.EBUILD] Bad value '$1' for qa level" 1>&2
- echo "2";
- ;;
- esac
-}
-
ebuild_notice()
{
- local level="$1"
- shift
-
- local level_num=$(ebuild_notice_level "${level}" )
- local min_level_num=$(ebuild_notice_level "${PALUDIS_EBUILD_LOG_LEVEL}" )
-
- if [[ "${level_num}" -ge "${min_level_num}" ]] ; then
- local upper_level=$(echo ${level} | ${ebuild_real_tr:-tr} '[:lower:]' '[:upper:]' )
- echo -n "${EBUILD_PROGRAM_NAME:-ebuild.bash}@$(${ebuild_real_date:-date} +%s ): " 1>&2
- echo "[${upper_level}.EBUILD] $* (from ${EBUILD:-?})" 1>&2
- fi
- true
+ paludis_pipe_command LOG "$EAPI" "$@" >/dev/null
}
ebuild_section()
diff --git a/paludis/repositories/e/ebuild/exheres-0/portage_stubs.bash b/paludis/repositories/e/ebuild/exheres-0/portage_stubs.bash
index f8223d3..5df5075 100755
--- a/paludis/repositories/e/ebuild/exheres-0/portage_stubs.bash
+++ b/paludis/repositories/e/ebuild/exheres-0/portage_stubs.bash
@@ -22,7 +22,9 @@
has_version()
{
- ${PALUDIS_COMMAND} --has-version "$@"
+ [[ "${#@}" -ne 1 ]] && die "$0 should take exactly one arg"
+ local r=$(paludis_pipe_command HAS_VERSION "$EAPI" "$1" )
+ return ${r%%;*}
}
portageq()
@@ -32,7 +34,10 @@ portageq()
best_version()
{
- ${PALUDIS_COMMAND} --best-version "$@"
+ [[ "${#@}" -ne 1 ]] && die "$0 should take exactly one arg"
+ local r=$(paludis_pipe_command BEST_VERSION "$EAPI" "$1" )
+ echo ${r#*;}
+ return ${r%%;*}
}
vdb_path()
diff --git a/paludis/repositories/e/ebuild/portage_stubs.bash b/paludis/repositories/e/ebuild/portage_stubs.bash
index 1efc470..0896d6f 100644
--- a/paludis/repositories/e/ebuild/portage_stubs.bash
+++ b/paludis/repositories/e/ebuild/portage_stubs.bash
@@ -20,11 +20,6 @@
# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA
-has_version()
-{
- ${PALUDIS_COMMAND} --has-version "$@"
-}
-
portageq()
{
# \todo Make this suck less...
@@ -52,7 +47,10 @@ portageq()
die "portageq match emulation only works on current ROOT"
else
shift ; shift
- ${PALUDIS_COMMAND} --match "$@"
+ [[ "${#@}" -ne 1 ]] && die "match should take exactly one arg"
+ local r=$(paludis_pipe_command MATCH "$EAPI" "$1" ) m=""
+ echo "${r#*;}"
+ return ${r%%;*}
fi
else
eerror "Error emulating 'portageq $@':"
@@ -62,14 +60,25 @@ portageq()
best_version()
{
- ${PALUDIS_COMMAND} --best-version "$@"
+ [[ "${#@}" -ne 1 ]] && die "$0 should take exactly one arg"
+ local r=$(paludis_pipe_command BEST_VERSION "$EAPI" "$1" )
+ echo ${r#*;}
+ return ${r%%;*}
+}
+
+has_version()
+{
+ [[ "${#@}" -ne 1 ]] && die "$0 should take exactly one arg"
+ local r=$(paludis_pipe_command HAS_VERSION "$EAPI" "$1" )
+ return ${r%%;*}
}
vdb_path()
{
- if ! ${PALUDIS_COMMAND} --configuration-variable installed location ; then
- die "Could not find vdb_path"
- fi
+ [[ "${#@}" -ne 0 ]] && die "vdb_path should take exactly zero args"
+ local r=$(paludis_pipe_command VDB_PATH "$EAPI" "$1" )
+ echo ${r#*;}
+ return ${r%%;*}
}
check_KV()
diff --git a/paludis/repositories/e/ebuild/run_test.bash b/paludis/repositories/e/ebuild/run_test.bash
index fae2479..aea57f4 100755
--- a/paludis/repositories/e/ebuild/run_test.bash
+++ b/paludis/repositories/e/ebuild/run_test.bash
@@ -32,10 +32,20 @@ test_equality()
fi
}
+export PALUDIS_PIPE_COMMAND_WRITE_FD=
+export PALUDIS_PIPE_COMMAND_READ_FD=
+export PALUDIS_SKIP_PIPE_COMMAND_CHECK=yes
+
echo "Test program ${1}:"
source "$(dirname ${1} )/ebuild.bash" || exit 200
source "${1}" || exit 200
+paludis_pipe_command()
+{
+ echo "No paludis_pipe_command here"
+ exit 127
+}
+
for testname in $(set | grep '_TEST *() *$' ) ; do
[[ ${testname/()} != ${testname} ]] && continue
echo -n "* ${testname%_TEST}: "
diff --git a/paludis/repositories/e/ebuild/utils/Makefile.am b/paludis/repositories/e/ebuild/utils/Makefile.am
index 6b3788f..56e2e30 100644
--- a/paludis/repositories/e/ebuild/utils/Makefile.am
+++ b/paludis/repositories/e/ebuild/utils/Makefile.am
@@ -58,9 +58,12 @@ libexecprog_SCRIPTS = \
patch
libexecbindir = $(libexecdir)/paludis/utils
-libexecbin_PROGRAMS = print_exports
+libexecbin_PROGRAMS = \
+ print_exports \
+ locked_pipe_command
print_exports_SOURCES = print_exports.cc
+locked_pipe_command_SOURCES = locked_pipe_command.cc
AM_CXXFLAGS = -I$(top_srcdir) @PALUDIS_CXXFLAGS@
diff --git a/paludis/repositories/e/ebuild/utils/locked_pipe_command.cc b/paludis/repositories/e/ebuild/utils/locked_pipe_command.cc
new file mode 100644
index 0000000..eca3780
--- /dev/null
+++ b/paludis/repositories/e/ebuild/utils/locked_pipe_command.cc
@@ -0,0 +1,107 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh
+ *
+ * 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
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <cstdlib>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <iostream>
+
+int
+main(int argc, char *argv[])
+{
+ if (argc != 3)
+ {
+ std::cerr << "Usage: " << argv[0] << " write_fd read_fd" << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ int write_fd(std::atoi(argv[1])), read_fd(std::atoi(argv[2]));
+ if (0 != ::lockf(write_fd, F_LOCK, 0))
+ {
+ std::cerr << "Error: " << argv[0] << ": lockf failed with " << ::strerror(errno) << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ /* copy stdin to the pipe read buffer */
+ char buf[1024];
+ int c, w;
+ while (((c = read(0, buf, 1024))) > 0)
+ {
+ char * buf_p(buf);
+ while (((w = write(write_fd, buf_p, c))) > 0)
+ {
+ buf_p += w;
+ c -= w;
+ if (c == 0)
+ break;
+ }
+ if (w == -1)
+ {
+ std::cerr << "Error: " << argv[0] << ": write failed with " << ::strerror(errno) << std::endl;
+ return EXIT_FAILURE;
+ }
+ }
+
+ if (c == -1)
+ {
+ std::cerr << "Error: " << argv[0] << ": read failed with " << ::strerror(errno) << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ /* append null to the pipe read buffer */
+ buf[0] = '\0';
+ while (((w = write(write_fd, buf, 1))) == 0)
+ sleep(0);
+ if (w == -1)
+ {
+ std::cerr << "Error: " << argv[0] << ": write failed with " << ::strerror(errno) << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ /* copy write buffer to stdout until we get a null, and discard that null */
+ while (((c = read(read_fd, buf, 1))) > 0)
+ {
+ if (buf[0] == '\0')
+ break;
+
+ while (((w = write(1, buf, c))) == 0)
+ sleep(0);
+ if (w == -1)
+ {
+ std::cerr << "Error: " << argv[0] << ": write failed with " << ::strerror(errno) << std::endl;
+ return EXIT_FAILURE;
+ }
+ }
+
+ if (c == -1)
+ {
+ std::cerr << "Error: " << argv[0] << ": read failed with " << ::strerror(errno) << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ if (0 != ::lockf(write_fd, F_ULOCK, 0))
+ {
+ std::cerr << "Error: " << argv[0] << ": lockf unlock failed with " << ::strerror(errno) << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ return EXIT_SUCCESS;
+}
+
diff --git a/paludis/util/system.cc b/paludis/util/system.cc
index d5cae70..00befb2 100644
--- a/paludis/util/system.cc
+++ b/paludis/util/system.cc
@@ -570,7 +570,7 @@ paludis::run_command(const Command & cmd)
while (! pipe_command_buffer.empty())
{
- std::string::size_type n_p(pipe_command_buffer.find('\n'));
+ std::string::size_type n_p(pipe_command_buffer.find('\0'));
if (std::string::npos == n_p)
break;
@@ -588,7 +588,6 @@ paludis::run_command(const Command & cmd)
Log::get_instance()->message(ll_warning, lc_context) << "Pipe command op '" << op <<
"' was requested but no handler defined. This is probably a bug...";
- response = strip_trailing(response, "\n") + "\n";
ssize_t n(0);
while (! response.empty())
{
@@ -598,6 +597,11 @@ paludis::run_command(const Command & cmd)
else
response.erase(0, n);
}
+
+ char c(0);
+ n = write(pipe_command_response->write_fd(), &c, 1);
+ if (1 != n)
+ throw InternalError(PALUDIS_HERE, "write failed: " + stringify(strerror(errno)));
}
while (! internal_command_buffer.empty())
diff --git a/paludis/util/system_TEST_setup.sh b/paludis/util/system_TEST_setup.sh
index c75cdda..13ba3f6 100755
--- a/paludis/util/system_TEST_setup.sh
+++ b/paludis/util/system_TEST_setup.sh
@@ -7,11 +7,21 @@ cd system_TEST_dir || exit 3
cat <<'END' > pipe_test.bash
#!/bin/bash
-echo $1 1>&$PALUDIS_PIPE_COMMAND_WRITE_FD
-read -u$PALUDIS_PIPE_COMMAND_READ_FD response1
-
-echo $2 1>&$PALUDIS_PIPE_COMMAND_WRITE_FD
-read -u$PALUDIS_PIPE_COMMAND_READ_FD response2
+echo "$1" | tr "\n" "\0" 1>&$PALUDIS_PIPE_COMMAND_WRITE_FD
+response1=
+while true ; do
+ c=$(head -c1 <&$PALUDIS_PIPE_COMMAND_READ_FD )
+ [[ "$c" == $'\0' ]] && break
+ response1="${response1}${c}"
+done
+
+echo "$2" | tr "\n" "\0" 1>&$PALUDIS_PIPE_COMMAND_WRITE_FD
+response2=
+while true ; do
+ c=$(head -c1 <&$PALUDIS_PIPE_COMMAND_READ_FD )
+ [[ "$c" == $'\0' ]] && break
+ response2="${response2}${c}"
+done
exit $response1$response2
END
@@ -19,14 +29,29 @@ END
cat <<'END' > captured_pipe_test.bash
#!/bin/bash
-echo $1 1>&$PALUDIS_PIPE_COMMAND_WRITE_FD
-read -u$PALUDIS_PIPE_COMMAND_READ_FD response1
-
-echo $2 1>&$PALUDIS_PIPE_COMMAND_WRITE_FD
-read -u$PALUDIS_PIPE_COMMAND_READ_FD response2
-
-echo $3 1>&$PALUDIS_PIPE_COMMAND_WRITE_FD
-read -u$PALUDIS_PIPE_COMMAND_READ_FD response3
+echo "$1" | tr "\n" "\0" 1>&$PALUDIS_PIPE_COMMAND_WRITE_FD
+response1=
+while true ; do
+ c=$(head -c1 <&$PALUDIS_PIPE_COMMAND_READ_FD )
+ [[ "$c" == $'\0' ]] && break
+ response1="${response1}${c}"
+done
+
+echo "$2" | tr "\n" "\0" 1>&$PALUDIS_PIPE_COMMAND_WRITE_FD
+response2=
+while true ; do
+ c=$(head -c1 <&$PALUDIS_PIPE_COMMAND_READ_FD )
+ [[ "$c" == $'\0' ]] && break
+ response2="${response2}${c}"
+done
+
+echo "$3" | tr "\n" "\0" 1>&$PALUDIS_PIPE_COMMAND_WRITE_FD
+response3=
+while true ; do
+ c=$(head -c1 <&$PALUDIS_PIPE_COMMAND_READ_FD )
+ [[ "$c" == $'\0' ]] && break
+ response3="${response3}${c}"
+done
echo $response2