***************************************************************************/
#include <stdio.h>
+#include <sys/wait.h>
#include <string>
#include <streambuf>
#include "exception.hxx"
#include "pipestream.hxx"
+/** @brief runs command and returns it's output as string
+ * @param command the full command with all parameters
+ * @param rescode struct containing the return code, if the program exited normally and so on
+ * @returns the output (stdout) of the called program
+ */
+std::string capture_exec(const std::string& command, ExecResult &rescode)
+{
+ std::string output;
+
+ bool exit_set;
+ int exit_status_waitpid;
+
+ // set the results to false until we are sure we have proper values
+ rescode.normal_exit = false;
+ rescode.terminated_by_signal = false;
+
+ try
+ {
+ {
+ inpipestream ips(command);
+
+ ips.store_exit_status(&exit_set, &exit_status_waitpid);
+
+ char buffer[2048];
+ while (ips.good())
+ {
+ ips.read(buffer, sizeof(buffer));
+ output.append(buffer, ips.gcount());
+ }
+ }
+
+ // exit_status_waitpid only valid after destruction of the inpipestream
+
+ if (exit_set)
+ {
+ rescode.normal_exit = WIFEXITED(exit_status_waitpid);
+ if (rescode.normal_exit)
+ rescode.return_code = WEXITSTATUS(exit_status_waitpid);
+
+ rescode.terminated_by_signal = WIFSIGNALED(exit_status_waitpid);
+ if (rescode.terminated_by_signal)
+ rescode.signal = WTERMSIG(exit_status_waitpid);
+ }
+ }
+ catch (pipestream_error &e)
+ {
+ rescode.error_message = e.what();
+ }
+
+ return output;
+}
+
inpipebuf::inpipebuf(const std::string& command)
{
status_set = NULL;
return traits_type::to_int_type(*gptr());
}
-/** @brief runs command and returns it's output as string
- * @param command the full command with all parameters
- * @param exit_status the full exit status, use WEXITSTATUS to get the "regular" return code
- * @returns the output (stderr) of the called program
- */
-std::string pipe_to_string(const std::string& command, std::string *error, int *_exit_status)
-{
- std::string result;
- bool exit_set;
-
- try
- {
- inpipestream ips(command);
-
- ips.store_exit_status(&exit_set, _exit_status);
-
- char buffer[2048];
- while (ips.good())
- {
- ips.read(buffer, sizeof(buffer));
- result.append(buffer, ips.gcount());
- }
- }
- catch (pipestream_error &e)
- {
- if (error)
- *error=e.what();
- return "";
- }
- catch(...)
- {
- throw;
- }
-
- return result;
-}
-
outpipebuf::outpipebuf(const std::string& command)
{
status_set = NULL;
#include <string>
#include <streambuf>
+struct ExecResult
+{
+ /** if the program exited normally and returned a return code */
+ bool normal_exit;
+
+ /** the real return code of the program, only set when normal_exit true */
+ char return_code;
+
+ /** if the program was terminated by a signal */
+ bool terminated_by_signal;
+
+ /** number of the signal that terminated the program, only valid when terminated_by_signal true */
+ int signal;
+
+ /** errormessage if we have one */
+ std::string error_message;
+};
+typedef struct ExecResult ExecResult;
+
+std::string capture_exec(const std::string& command, ExecResult &rescode);
+
+std::string capture_exec(const std::string& command)
+{
+ ExecResult r;
+ return capture_exec(command,r);
+}
+
/** @brief runs command and provides buffered input for it through pipe
*
* opens pipe to command using popen; exit status available after destruction
{ buf.store_exit_status(_status_set, _exit_status); }
};
-std::string pipe_to_string(const std::string& command, std::string *error=NULL, int *_exit_status=NULL);
-
/** @brief runs command and provides buffered ouptput from it through pipe
*
* opens pipe to command using popen; exit status available after destruction
BOOST_AUTO_TEST_CASE(FreeDiskSpace1)
{
- string dfstr=pipe_to_string("df -B 1 --output=avail /tmp | tail -n 1");
+ string dfstr=capture_exec("df -B 1 --output=avail /tmp | tail -n 1");
long long dfout=-1;
string_to<long long>(dfstr,dfout);
BOOST_CHECK_EQUAL(true, I2n::mkdir(sub_dir));
BOOST_CHECK_EQUAL(true, write_file(some_file, "foobar and some more data, even more that Tom would like to see in one line without linebreak but I still want to have it all here"));
- string dustr=pipe_to_string(string("du --block-size=1 --sum ")+unique_dir+" | cut -f 1");
+ string dustr=capture_exec(string("du --block-size=1 --sum ")+unique_dir+" | cut -f 1");
long long duout=-1;
string_to<long long>(dustr,duout);