Skip to content

Process.V2 may block with wrong way use of "process_stdio" #471

Open
@atomictoquark

Description

@atomictoquark
#define WIN32_LEAN_AND_MEAN
#define BOOST_PROCESS_VERSION 2
#include <boost/process.hpp>
#include <iostream>

#if defined(BOOST_PROCESS_V2_WINDOWS)
#pragma comment(lib,"ntdll.lib")

//for MSVC 143
#if defined(_MT) //MultiThread Static
#   if defined(_DEBUG)
#       pragma comment(lib,"libboost_process-vc143-mt-sgd-x64-1_87.lib")
#   endif
#endif
#endif

using namespace boost;
namespace bp = boost::process::v2;
int main()
{
    asio::io_context ctx;
    std::string output;
    output.resize(1000);
    system::error_code ec;

    {
        //bad way
        asio::readable_pipe rp2{ ctx };

        //this io must declare inside proc like bp::process proc(ctx,xx,xxx,bp::process_stdio{{...},{...},{..}}}
        bp::process_stdio io = bp::process_stdio{ nullptr, rp2, nullptr };
        //due to [email protected] hold this pip handle with a unique_ptr,
        //this make the life time as long as the var 'proc' bellow
        //and cannot clean the handle passed to the child,after CreateProcessW
        //thus read_some can't get ERROR_PIPE_BROKEN(because there still have a valid PIPE handle in 'io')

        //use SysinternalsSuite/procexp64 FIND->FIND Handle or DLL to search 'asio' 
        //after child process exit.it should not valid.
        bp::process proc(ctx, R"(C:\Program Files\Git\bin\git.exe)", { "-v" }, io);
        proc.detach();
        while (true)
        {
            //bad:never revice ERROR_PIPE_BROKEN
            auto size = rp2.read_some(asio::buffer(output), ec);
            if (ec)  break;
            std::cout<<output.substr(0, size);
        }
        std::cout<<"badend\n\n";
    }

    {
        //good way
        asio::readable_pipe rp{ ctx };
        bp::process proc(ctx, R"(C:\Program Files\Git\bin\git.exe)", { "-v" }, bp::process_stdio{ nullptr, rp, nullptr });
        proc.detach();
        while (true)
        {
            auto size = rp.read_some(asio::buffer(output), ec);
            if (ec)  break;
            std::cout<<output.substr(0, size);
        }
        std::cout<<"goodend\n\n";
    }

    return 0;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions