aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-08-20 15:50:41 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-08-21 14:58:17 +0100
commit7d902d768782fae65bdc368a9c0d24b81c381e00 (patch)
tree613ef11993e1b6eeb6133503c43b26784dc0496d
parent6c8ec28a8dd13cdb76f2a367bd54ca1302894bec (diff)
downloadpaludis-7d902d768782fae65bdc368a9c0d24b81c381e00.tar.gz
paludis-7d902d768782fae65bdc368a9c0d24b81c381e00.tar.xz
Process::set_stdin_fd
-rw-r--r--paludis/util/process.cc15
-rw-r--r--paludis/util/process.hh1
-rw-r--r--paludis/util/process_TEST.cc31
3 files changed, 47 insertions, 0 deletions
diff --git a/paludis/util/process.cc b/paludis/util/process.cc
index abcef46..c2967db 100644
--- a/paludis/util/process.cc
+++ b/paludis/util/process.cc
@@ -247,6 +247,7 @@ namespace paludis
std::ostream * capture_output_to_fd_stream;
int capture_output_to_fd_fd;
std::string capture_output_to_fd_env_var;
+ int set_stdin_fd;
std::map<std::string, std::string> setenvs;
std::string chdir;
@@ -262,6 +263,7 @@ namespace paludis
capture_stderr(0),
capture_output_to_fd_stream(0),
capture_output_to_fd_fd(-1),
+ set_stdin_fd(-1),
setuid(getuid()),
setgid(getgid()),
echo_command_to(0)
@@ -348,6 +350,12 @@ Process::run()
::setenv(_imp->capture_output_to_fd_env_var.c_str(), stringify(fd).c_str(), 1);
}
+ if (-1 != _imp->set_stdin_fd)
+ {
+ if (-1 == ::dup2(_imp->set_stdin_fd, STDIN_FILENO))
+ throw ProcessError("dup2() failed");
+ }
+
for (auto m(_imp->setenvs.begin()), m_end(_imp->setenvs.end()) ;
m != m_end ; ++m)
::setenv(m->first.c_str(), m->second.c_str(), 1);
@@ -421,6 +429,13 @@ Process::capture_output_to_fd(std::ostream & s, int fd_or_minus_one, const std::
}
Process &
+Process::set_stdin_fd(int f)
+{
+ _imp->set_stdin_fd = f;
+ return *this;
+}
+
+Process &
Process::setenv(const std::string & a, const std::string & b)
{
_imp->setenvs.insert(std::make_pair(a, b)).first->second = b;
diff --git a/paludis/util/process.hh b/paludis/util/process.hh
index 3865911..8a3fe3f 100644
--- a/paludis/util/process.hh
+++ b/paludis/util/process.hh
@@ -78,6 +78,7 @@ namespace paludis
Process & capture_stdout(std::ostream &);
Process & capture_stderr(std::ostream &);
Process & capture_output_to_fd(std::ostream &, int fd_or_minus_one, const std::string & env_var_with_fd);
+ Process & set_stdin_fd(int);
Process & setenv(const std::string &, const std::string &);
Process & chdir(const FSEntry &);
Process & use_ptys();
diff --git a/paludis/util/process_TEST.cc b/paludis/util/process_TEST.cc
index fc57c19..b0abb15 100644
--- a/paludis/util/process_TEST.cc
+++ b/paludis/util/process_TEST.cc
@@ -19,6 +19,8 @@
#include <paludis/util/process.hh>
#include <paludis/util/fs_entry.hh>
+#include <paludis/util/pipe.hh>
+#include <paludis/util/safe_ofstream.hh>
#include <test/test_framework.hh>
#include <test/test_runner.hh>
#include <sstream>
@@ -262,5 +264,34 @@ namespace test_cases
TEST_CHECK_EQUAL(fd_stream.str(), "monkey\n");
}
} test_grab_fd_fixed;
+
+ struct StdinFDTest : TestCase
+ {
+ StdinFDTest() : TestCase("stdin fd") { }
+
+ void run()
+ {
+ std::unique_ptr<Pipe> input_pipe(new Pipe(true));
+
+ std::stringstream stdout_stream;
+ Process cat_process(ProcessCommand({"rev"}));
+ cat_process.capture_stdout(stdout_stream);
+ cat_process.set_stdin_fd(input_pipe->read_fd());
+
+ RunningProcessHandle handle(cat_process.run());
+
+ {
+ {
+ SafeOFStream s(input_pipe->write_fd());
+ s << "backwards" << std::endl;
+ }
+ TEST_CHECK(0 == ::close(input_pipe->write_fd()));
+ input_pipe->clear_write_fd();
+ }
+
+ TEST_CHECK_EQUAL(handle.wait(), 0);
+ TEST_CHECK_EQUAL(stdout_stream.str(), "sdrawkcab\n");
+ }
+ } test_stdin_fd;
}