Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r64941 - in sandbox/SOC/2010/process: boost/process libs/process/test
From: boris_at_[hidden]
Date: 2010-08-21 16:46:28


Author: bschaeling
Date: 2010-08-21 16:46:27 EDT (Sat, 21 Aug 2010)
New Revision: 64941
URL: http://svn.boost.org/trac/boost/changeset/64941

Log:
Added test case test_posix_daemon and fixed create_child() to pass the test case
Text files modified:
   sandbox/SOC/2010/process/boost/process/operations.hpp | 39 ++++++++++++++++++++-
   sandbox/SOC/2010/process/libs/process/test/child.cpp | 74 ++++++++++++++++++++++++++++++++++++++++
   2 files changed, 111 insertions(+), 2 deletions(-)

Modified: sandbox/SOC/2010/process/boost/process/operations.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/operations.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/operations.hpp 2010-08-21 16:46:27 EDT (Sat, 21 Aug 2010)
@@ -28,6 +28,7 @@
 # include <cstddef>
 # include <stdlib.h>
 # include <unistd.h>
+# include <fcntl.h>
 # if defined(__CYGWIN__)
 # include <boost/scoped_array.hpp>
 # include <sys/cygwin.h>
@@ -227,8 +228,33 @@
         }
 
         handle hstdin = ctx.stdin_behavior->get_child_end();
+ handle hstdout = ctx.stdout_behavior->get_child_end();
+ handle hstderr = ctx.stderr_behavior->get_child_end();
+
         if (hstdin.valid())
         {
+ if (hstdout.native() == STDIN_FILENO)
+ {
+ int fd = fcntl(hstdout.native(), F_DUPFD, 3);
+ if (fd == -1)
+ {
+ write(STDERR_FILENO, "fcntl() failed\n", 15);
+ _exit(127);
+ }
+ hstdout = fd;
+ }
+
+ if (hstderr.native() == STDIN_FILENO)
+ {
+ int fd = fcntl(hstderr.native(), F_DUPFD, 3);
+ if (fd == -1)
+ {
+ write(STDERR_FILENO, "fcntl() failed\n", 15);
+ _exit(127);
+ }
+ hstderr = fd;
+ }
+
             if (dup2(hstdin.native(), STDIN_FILENO) == -1)
             {
                 write(STDERR_FILENO, "dup2() failed\n", 14);
@@ -237,9 +263,19 @@
             closeflags[STDIN_FILENO] = false;
         }
 
- handle hstdout = ctx.stdout_behavior->get_child_end();
         if (hstdout.valid())
         {
+ if (hstderr.native() == STDOUT_FILENO)
+ {
+ int fd = fcntl(hstderr.native(), F_DUPFD, 3);
+ if (fd == -1)
+ {
+ write(STDERR_FILENO, "fcntl() failed\n", 15);
+ _exit(127);
+ }
+ hstderr = fd;
+ }
+
             if (dup2(hstdout.native(), STDOUT_FILENO) == -1)
             {
                 write(STDERR_FILENO, "dup2() failed\n", 14);
@@ -248,7 +284,6 @@
             closeflags[STDOUT_FILENO] = false;
         }
 
- handle hstderr = ctx.stderr_behavior->get_child_end();
         if (hstderr.valid())
         {
             if (dup2(hstderr.native(), STDERR_FILENO) == -1)

Modified: sandbox/SOC/2010/process/libs/process/test/child.cpp
==============================================================================
--- sandbox/SOC/2010/process/libs/process/test/child.cpp (original)
+++ sandbox/SOC/2010/process/libs/process/test/child.cpp 2010-08-21 16:46:27 EDT (Sat, 21 Aug 2010)
@@ -660,6 +660,80 @@
     BOOST_REQUIRE(WIFEXITED(s));
     BOOST_CHECK_EQUAL(WEXITSTATUS(s), EXIT_SUCCESS);
 }
+
+class raii_dup2
+{
+public:
+ raii_dup2(int fd1, int fd2)
+ : reverted_(false),
+ fd1_(fd1),
+ fd2_(fd2)
+ {
+ BOOST_REQUIRE(dup2(fd1_, fd2_) != -1);
+ }
+
+ ~raii_dup2()
+ {
+ if (!reverted_)
+ revert();
+ }
+
+ void revert()
+ {
+ reverted_ = true;
+ BOOST_REQUIRE(dup2(fd2_, fd1_) != -1);
+ }
+
+private:
+ bool reverted_;
+ int fd1_;
+ int fd2_;
+};
+
+BOOST_AUTO_TEST_CASE(test_posix_daemon)
+{
+ check_helpers();
+
+ std::vector<std::string> args;
+ args.push_back("echo-stdout-stderr");
+ args.push_back("message-to-two-streams");
+
+ context ctx;
+
+ // File descriptors must be closed after context is instantiated as the
+ // context constructor uses the behavior inherit which tries to dup()
+ // stdin, stdout and stderr.
+ raii_dup2 raii_stdin(STDIN_FILENO, 100);
+ close(STDIN_FILENO);
+ raii_dup2 raii_stdout(STDOUT_FILENO, 101);
+ close(STDOUT_FILENO);
+ raii_dup2 raii_stderr(STDERR_FILENO, 102);
+ close(STDERR_FILENO);
+
+ ctx.stderr_behavior = bpb::pipe::create(bpb::pipe::output_stream);
+ ctx.stdout_behavior = bpb::pipe::create(bpb::pipe::output_stream);
+
+ bp::child c = bp::create_child(get_helpers_path(), args, ctx);
+
+ std::string words[4];
+ bp::pistream &isout = c.get_stdout();
+ isout >> words[0] >> words[1];
+ bp::pistream &iserr = c.get_stderr();
+ iserr >> words[2] >> words[3];
+
+ raii_stdin.revert();
+ raii_stdout.revert();
+ raii_stderr.revert();
+
+ int s = c.wait();
+ BOOST_REQUIRE(WIFEXITED(s));
+ BOOST_CHECK_EQUAL(WEXITSTATUS(s), EXIT_SUCCESS);
+
+ BOOST_CHECK_EQUAL(words[0], "stdout");
+ BOOST_CHECK_EQUAL(words[1], "message-to-two-streams");
+ BOOST_CHECK_EQUAL(words[2], "stderr");
+ BOOST_CHECK_EQUAL(words[3], "message-to-two-streams");
+}
 #endif
 
 #if defined(BOOST_WINDOWS_API)


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk