C++ library that allows you to run an external program and have its input,
output and error available as standard C++ streams.
Categories
SystemLicense
BSD LicenseFollow libexecstream
Other Useful Business Software
AI-generated apps that pass security review
Retool lets you generate dashboards, admin panels, and workflows directly on your data. Type something like “Build me a revenue dashboard on my Stripe data” and get a working app with security, permissions, and compliance built in from day one. Whether on our cloud or self-hosted, create the internal software your team needs without compromising enterprise standards or control.
Rate This Project
Login To Rate This Project
User Reviews
-
Better than Boost.Process, and very easy to learn.
-
libexecstream has worked well in a couple projects, but we did run into a problem when there were multiple threads started simultaneously and there was likely thread/process contention. Calls in exec-stream-impl.cpp and exec-stream-helpers.cpp to select(...) would occasionally be interrupted by an EINTR error. As far as we can tell, this does not represent an error condition. The select call is just waiting until the status descriptor has something to read, at which point it will return +1. Restarting the status descriptor with the same time delay will extend the possible timeout (or, possibly, on some systems, continue with the remaining time as previously requested). This solution seems to work for our applications. Specifically, around each call to select(), we replaced the if() with a while() loop to restart the select() call in the event of errno==EINTR. I've placed diffs of our files in the wiki, but sourceforge won't let me put a link to it here.
-
OK so this lib works as it's been used for years in a couple of our modules. But it's got a flaw. If you call the kill method the child process will be left as a defunct process (aka zombie) in the system. I sent an email to the author a few days ago, but got no reply. So I am just going to stick my fix here: void exec_stream_t::kill() { if( m_impl->m_child_pid!=-1 ) { if( ::kill( m_impl->m_child_pid, SIGKILL )==-1 ) { throw os_error_t( "exec_stream_t::kill: kill failed" ); } // The correct way to handle killing a child process is to wait for the OS // to release the child process resources before assigning -1 to m_child_pid. // Assigning -1 to m_child_pid without waiting will result in a "defunct" process // (aka zombie process) remaining in the process table. pid_t code=waitpid( m_impl->m_child_pid, &m_impl->m_exit_code, 0 ); if( code == m_impl->m_child_pid ) { m_impl->m_child_pid=-1; m_impl->m_exit_code=0; } else if( code == -1 ) { throw os_error_t( "exec_stream_t::kill: waitpid failed" ); } } }