diff options
author | 2010-08-20 15:50:41 +0100 | |
---|---|---|
committer | 2010-08-21 14:58:17 +0100 | |
commit | 7d902d768782fae65bdc368a9c0d24b81c381e00 (patch) | |
tree | 613ef11993e1b6eeb6133503c43b26784dc0496d | |
parent | 6c8ec28a8dd13cdb76f2a367bd54ca1302894bec (diff) | |
download | paludis-7d902d768782fae65bdc368a9c0d24b81c381e00.tar.gz paludis-7d902d768782fae65bdc368a9c0d24b81c381e00.tar.xz |
Process::set_stdin_fd
-rw-r--r-- | paludis/util/process.cc | 15 | ||||
-rw-r--r-- | paludis/util/process.hh | 1 | ||||
-rw-r--r-- | paludis/util/process_TEST.cc | 31 |
3 files changed, 47 insertions, 0 deletions
diff --git a/paludis/util/process.cc b/paludis/util/process.cc index abcef4690..c2967dbb5 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 3865911a5..8a3fe3f3d 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 fc57c197a..b0abb159b 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; } |