Reputation: 345
I have a thread starting a boost::process application, with the code the thread runs like this:
void Service::Run()
{
printf("Starting thread for service ID %i\n", this->sid);
// Set up a stream sink for stdout, stderr and stdin
bprocess::pipe pstdIn = create_pipe();
bprocess::pipe pstdOut = create_pipe();
file_descriptor_sink fdSink(pstdIn.sink, close_handle);
file_descriptor_source fdSrc(pstdOut.sink, close_handle);
// Set up the read write streams
this->stdIn = new fdistream(fdSink);
this->stdOut = new fdostream(fdSrc);
// Execute the service
try
{
child proc = execute(
set_args(this->args),
inherit_env(),
bind_stdin(fdSrc),
throw_on_error()
);
printf("PID: %i\n", proc.pid);
// Wait for the application to end then call a cleanup function
int exit_code = wait_for_exit(proc);
printf("Service died, error code: %i\n", exit_code);
}
catch(boost::system::system_error err)
{
printf("Something went wrong: %s\n", err.what());
}
this->manager->ServiceDie(this->sid);
return;
}
As this function is a blocking one, it essentially waits for the service to be killed (Externally or as I need; input via stdin to gracefully stop the application).
I have no idea how to write to the stdin of the child process. I have tried this:
*(this->stdIn) << "stop\n";
inside a public function in the class of Service
that's being called in another thread (Manager
class). However this yeilds no results.
How can I write to the stdin of the child proc
?
Upvotes: 5
Views: 2734
Reputation: 393497
Here's a demo adapted from sample here:
You can see it Live on Coliru Sadly that's pushing the limits of Coliru. May be later:
#include <boost/process.hpp>
#include <boost/assign/list_of.hpp>
#include <string>
#include <vector>
#include <iostream>
using namespace boost::process;
int main()
{
std::string exec = find_executable_in_path("rev");
std::vector<std::string> args = boost::assign::list_of("rev");
context ctx;
ctx.environment = self::get_environment();
ctx.stdin_behavior = capture_stream();
ctx.stdout_behavior = capture_stream();
child c = launch(exec, args, ctx);
postream &os = c.get_stdin();
pistream &is = c.get_stdout();
os << "some\ncookies\nfor\ntasting";
os.close();
std::cout << is.rdbuf();
}
Output:
emos
seikooc
rof
gnitsat
Now, if you need it truly asynchronous, there's another sample using Boost Asio further down that page
Upvotes: 2