$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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)