#include <stdio.h>
+#include <cstring>
#include <string>
#include <streambuf>
+#include <istream>
+#include <ostream>
+#include <vector>
+
+#include <stringfunc.hxx>
+
+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;
+
+ inline std::string format (void) const
+ {
+ return std::string ("(")
+ + "(normal_exit " + (this->normal_exit ? "T" : "F") + ") "
+ "(return_code '" + I2n::to_string ((int)this->return_code) + "') "
+ "(signal " + (this->terminated_by_signal
+ ? strsignal (this->signal)
+ : "<nil>") + "))"
+ ;
+ };
+};
+typedef struct ExecResult ExecResult;
+
+std::string capture_exec(const std::string& command, ExecResult &rescode);
+std::string capture_exec(const char *const *command, ExecResult &rescode,
+ const bool out=true, const bool err=false,
+ const bool path=false, const bool env=false);
+std::string capture_exec(const std::vector<std::string>& command, ExecResult &rescode,
+ const bool out=true, const bool err=false,
+ const bool path=false, const bool env=false);
+
+inline std::string capture_exec (const std::string &command)
+{
+ ExecResult r;
+ return capture_exec(command,r);
+}
+
+inline std::string capture_exec(const char *const *command)
+{
+ ExecResult r;
+ return capture_exec(command,r);
+}
+
+inline std::string capture_exec(const std::vector<std::string>& command)
+{
+ ExecResult r;
+ return capture_exec(command,r);
+}
/** @brief runs command and provides buffered input for it through pipe
*
{
protected:
char buffer;
+
FILE *pipe;
+ pid_t pid;
// "callback" variables for destructor to store exit status
bool *status_set;
int *exit_status;
public:
- inpipebuf(const std::string& command);
+ inpipebuf(const std::string& command,
+ const bool out, const bool err, const bool path, const bool env);
+ inpipebuf(const char *const *command,
+ const bool out, const bool err, const bool path, const bool env);
+ inpipebuf(const std::vector<std::string> &command,
+ const bool out, const bool err, const bool path, const bool env);
~inpipebuf();
protected:
virtual int_type underflow();
+
+private:
+ std::pair <pid_t, FILE *>
+ init_without_shell (const char *const *argv,
+ const bool out, const bool err,
+ const bool path, const bool env) const;
};
/** @brief stream around inpipebuf -- see comment there */
inpipebuf buf;
public:
- inpipestream(const std::string& command)
- : std::istream(&buf), buf(command)
+ inpipestream(const std::string& command,
+ const bool out=true, const bool err=false,
+ const bool path=false, const bool env=false)
+ : std::istream(&buf), buf(command, out, err, path, env)
+ {}
+
+ inpipestream(const char *const command[],
+ const bool out=true, const bool err=false,
+ const bool path=false, const bool env=false)
+ : std::istream(&buf), buf(command, out, err, path, env)
+ {}
+
+ inpipestream(const std::vector<std::string> &command,
+ const bool out=true, const bool err=false,
+ const bool path=false, const bool env=false)
+ : std::istream(&buf), buf(command, out, err, path, env)
{}
void store_exit_status(bool *_status_set, int *_exit_status)
{ 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