2004-08-28 16:21:25 +00:00
|
|
|
/** @file
|
|
|
|
|
|
|
|
$Id$
|
|
|
|
|
|
|
|
$Date$
|
|
|
|
$Author$
|
|
|
|
|
|
|
|
@copy © Marc Wäckerlin
|
|
|
|
@license LGPL, see file <a href="license.html">COPYING</a>
|
|
|
|
|
|
|
|
$Log$
|
2005-04-20 18:12:55 +00:00
|
|
|
Revision 1.7 2005/04/20 18:12:55 marc
|
|
|
|
added kill() for PartialExec
|
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
Revision 1.6 2005/04/19 18:48:00 marc
|
|
|
|
new feature PartialExec
|
|
|
|
|
2004-12-14 20:30:10 +00:00
|
|
|
Revision 1.5 2004/12/14 20:30:09 marc
|
|
|
|
added possibility to pass string to stdin of child process
|
|
|
|
|
2004-10-07 09:27:01 +00:00
|
|
|
Revision 1.4 2004/10/07 09:27:01 marc
|
|
|
|
errors in documentation
|
|
|
|
|
2004-08-28 16:21:25 +00:00
|
|
|
Revision 1.3 2004/08/28 16:21:25 marc
|
|
|
|
mrw-c++-0.92 (mrw)
|
|
|
|
- new file: version.cpp
|
|
|
|
- new file header for all sources
|
|
|
|
- work around warning in mrw::auto<T>
|
|
|
|
- possibility to compile without log4cxx
|
|
|
|
- work around bugs in demangle.h and libiberty.h
|
|
|
|
- corrections in documentation
|
|
|
|
- added simple tracing mechanism
|
|
|
|
- more warnings
|
|
|
|
- small corrections in Auto<>::Free and a new test for it
|
|
|
|
- possibility to compile without stack trace
|
|
|
|
|
|
|
|
*/
|
2004-04-21 06:39:20 +00:00
|
|
|
#ifndef __MRW_EXEC_HPP__
|
|
|
|
#define __MRW_EXEC_HPP__
|
|
|
|
|
|
|
|
#include <string>
|
|
|
|
#include <list>
|
|
|
|
#include <mrw/exception.hpp>
|
2005-04-19 18:48:00 +00:00
|
|
|
#include <mrw/unistd.hpp>
|
2004-04-21 06:39:20 +00:00
|
|
|
|
|
|
|
namespace mrw {
|
|
|
|
|
|
|
|
/** @defgroup CmdExec Execute UNIX Commands
|
|
|
|
|
|
|
|
There is no easy way to safely execute UNIX commands and to
|
|
|
|
return the output of the callee to the caller. @c system ist
|
|
|
|
first of all known to be unsafe, because it opens a shell, and
|
|
|
|
second there is no way to transfer the output back to the
|
|
|
|
caller. On the other hand, starting a new process with @c fork
|
|
|
|
and @c exec and passing the output of the callee to the caller
|
|
|
|
using pipes is quite complex and needs much more than one simple
|
|
|
|
line of code. This is the gap that is filled with this command
|
|
|
|
execution classes. There's a class for the command to be
|
|
|
|
executed and a class for the execution of the command.
|
|
|
|
|
|
|
|
Forking a subprocess and evaluating the result becomes so easy:
|
|
|
|
|
|
|
|
@code
|
|
|
|
try {
|
|
|
|
// execute the command: /bin/ls -l /tmp
|
|
|
|
mrw::Exec ls =
|
|
|
|
(mrw::Cmd("/bin/ls"), "-l", "/tmp").execute(false);
|
|
|
|
// evaluate the result
|
|
|
|
if (ls.success())
|
|
|
|
std::cout<<"Execution successful, result was:"<<std::endl;
|
|
|
|
else
|
|
|
|
std::cerr<<"Error in execution, error was:"<<std::endl;
|
|
|
|
std::cout<<ls.result()<<std::endl;
|
|
|
|
std::cerr<<ls.error()<<std::endl;
|
|
|
|
} catch (ExecutionFailedExc& x) {
|
|
|
|
// a fatal execution error occurred
|
|
|
|
// you can trace x.what() and x.stacktrace()
|
|
|
|
}
|
|
|
|
@endcode
|
2004-12-14 20:30:10 +00:00
|
|
|
|
|
|
|
It is also possible to pass an @c stdin input argument to the
|
|
|
|
subprocess called:
|
|
|
|
|
|
|
|
@code
|
|
|
|
try {
|
|
|
|
mrw::Exec cat = mrw::Cmd("/bin/cat")
|
|
|
|
.execute("this is passed to stdin");
|
|
|
|
// "cat" passes all from stdin to stdout, therefore:
|
|
|
|
assert(cat.result()=="this is passed to stdin");
|
|
|
|
} catch (...) {} // ignore
|
2005-04-19 18:48:00 +00:00
|
|
|
@endcode */
|
2004-04-21 06:39:20 +00:00
|
|
|
//@{
|
|
|
|
|
|
|
|
class Cmd;
|
2005-04-19 18:48:00 +00:00
|
|
|
|
|
|
|
//============================================================================
|
2004-04-21 06:39:20 +00:00
|
|
|
/** @brief Exception: Execution of command failed.
|
2004-04-23 16:03:29 +00:00
|
|
|
@pre #include <mrw/exec.hpp>
|
2004-04-21 06:39:20 +00:00
|
|
|
|
|
|
|
This exception is thrown, if the exection of a command in
|
|
|
|
mrw::Exec is failed. That means, it was not possible to fork or
|
|
|
|
to create the necessary pipes, or the command executing process
|
|
|
|
terminated with an error. In the last case, you can access the
|
|
|
|
error stream from @c stderr respectively @c cerr with method
|
2005-04-19 18:48:00 +00:00
|
|
|
mrw::Exec::error(). */
|
2004-04-21 06:39:20 +00:00
|
|
|
class ExecutionFailedExc: public mrw::exception {
|
2005-04-19 18:48:00 +00:00
|
|
|
public:
|
|
|
|
ExecutionFailedExc(const std::string&, const std::string&)
|
|
|
|
throw(std::bad_exception);
|
|
|
|
virtual ~ExecutionFailedExc() throw() {}
|
|
|
|
virtual const char* what() const throw() {return _what.c_str();}
|
|
|
|
private:
|
|
|
|
std::string _what;
|
2004-04-21 06:39:20 +00:00
|
|
|
};
|
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
//============================================================================
|
2004-04-21 06:39:20 +00:00
|
|
|
/** @brief Execute a command in a new process.
|
2004-04-23 16:03:29 +00:00
|
|
|
@pre #include <mrw/exec.hpp>
|
2004-04-21 06:39:20 +00:00
|
|
|
|
|
|
|
This class handles the execution of a command in a new process
|
2004-04-23 16:03:29 +00:00
|
|
|
and returns the two streams @c cout and @c cerr, also known as @c
|
|
|
|
stderr and @c stdout.
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2004-12-14 20:30:10 +00:00
|
|
|
Method @c execute can optionally also take a string parameter
|
|
|
|
that is passed to @c stdin of the child process.
|
|
|
|
|
2004-04-21 06:39:20 +00:00
|
|
|
There are different ways of usage for this class. A simple way,
|
|
|
|
one line of code, to get only the resulting stream (no error)
|
|
|
|
is:
|
|
|
|
|
|
|
|
@code
|
|
|
|
string stdout =
|
|
|
|
(mrw::Cmd("/bin/ls"), "-l", "/tmp").execute(false).result();
|
|
|
|
@endcode
|
|
|
|
|
|
|
|
If you need not only the resulting @c stdout stream, but also
|
|
|
|
the error stream @c stderr, then you need to store the result:
|
|
|
|
|
|
|
|
@code
|
|
|
|
mrw::Exec ls =
|
|
|
|
(mrw::Cmd("/bin/ls"), "-l", "/tmp").execute(false);
|
|
|
|
if (!ls) ...; // command termianted with error
|
|
|
|
// ls.result() contains stdout
|
|
|
|
// ls.error() contains stderr
|
|
|
|
@endcode
|
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
@note Please note that the command execution may throw an exception. */
|
2004-04-21 06:39:20 +00:00
|
|
|
class Exec {
|
2005-04-19 18:48:00 +00:00
|
|
|
|
|
|
|
//................................................................ methods
|
|
|
|
public:
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
/** @brief Create an executor given a command.
|
|
|
|
Construction without passing a command is not possible. */
|
|
|
|
Exec(const mrw::Cmd&) throw(std::bad_exception);
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
Exec(const mrw::Exec&) throw(std::bad_exception);
|
|
|
|
~Exec() throw();
|
|
|
|
Exec& operator=(const mrw::Exec&) throw(std::bad_exception);
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
/** @brief Execute the command.
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
@param exc
|
|
|
|
- @c true throw an exception if return status is not zero
|
|
|
|
- @c false throw only an exception in case of a fatal error
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
@throw ExecutionFailedExc is thrown if
|
|
|
|
- fork fails
|
|
|
|
- creation or setup of pipes failed
|
|
|
|
- if given parameter is @c true (the default) also if the
|
|
|
|
executed program terminates with an error */
|
|
|
|
Exec& execute(bool exc=true) throw(std::exception);
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
/** @brief Execute the command, pass @c stdin.
|
2004-12-14 20:30:10 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
@param input Input that is passed to @c stdin of the child process.
|
2004-12-14 20:30:10 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
@param exc
|
|
|
|
- @c true throw an exception if return status is not zero
|
|
|
|
- @c false throw only an exception in case of a fatal error
|
2004-12-14 20:30:10 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
@throw ExecutionFailedExc is thrown if
|
|
|
|
- fork fails
|
|
|
|
- creation or setup of pipes failed
|
|
|
|
- if given parameter is @c true (the default) also if the
|
|
|
|
executed program terminates with an error */
|
|
|
|
Exec& execute(const std::string& input, bool exc=true)
|
|
|
|
throw(std::exception);
|
2004-12-14 20:30:10 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
/** @brief Execute the command, pass @c stdin.
|
2004-12-14 20:30:10 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
@param input Input that is passed to @c stdin of the child process.
|
2004-12-14 20:30:10 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
@param exc
|
|
|
|
- @c true throw an exception if return status is not zero
|
|
|
|
- @c false throw only an exception in case of a fatal error
|
2004-12-14 20:30:10 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
@throw ExecutionFailedExc is thrown if
|
|
|
|
- fork fails
|
|
|
|
- creation or setup of pipes failed
|
|
|
|
- if given parameter is @c true (the default) also if the
|
|
|
|
executed program terminates with an error */
|
|
|
|
Exec& execute(char const*const input, bool exc=true)
|
|
|
|
throw(std::exception) {
|
|
|
|
return execute(std::string(input), exc);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** @brief Executes the command if not done, streams @c stdout
|
|
|
|
into a string
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
If the command has not yet been executed successfully, it is
|
|
|
|
first executed, then the @c stdout output of the called
|
|
|
|
program is appended to the string.
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
@throw ExecutionFailedExc in case of any failure or if the
|
|
|
|
executed program does not return a zero exit status. */
|
|
|
|
Exec& operator>>(std::string&) throw(std::exception);
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
/** @brief Executes the command if not done, returns @c stdout as string
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
If the command has not yet been executed successfully, it is
|
|
|
|
first executed, then the @c stdout output of the called
|
|
|
|
program is returned.
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
@return @c stdout of the called program
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
@throw ExecutionFailedExc in case of any failure or if the
|
|
|
|
executed program does not return a zero exit status. */
|
|
|
|
operator std::string&() throw(std::exception);
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
/** @return
|
|
|
|
- @c true if the last execution was successful
|
|
|
|
- @c false if the last execution failed or the command was
|
|
|
|
never executed */
|
|
|
|
operator bool() throw(std::bad_exception);
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
/** @brief Executes the command if not done, returns @c stdout as string
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
If the command has not yet been executed successfully, it is
|
|
|
|
first executed, then the @c stdout output of the called
|
|
|
|
program is returned.
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
@return @c stdout of the called program
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
@throw ExecutionFailedExc in case of any failure or if the
|
|
|
|
executed program does not return a zero exit status. */
|
|
|
|
std::string& result() throw(std::exception);
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
/** @brief Executes the command if not done, returns @c stderr as string
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
If the command has not yet been executed successfully, it is
|
|
|
|
first executed, then the @c stderr error output of the called
|
|
|
|
program is returned.
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
@return @c stderr of the called program
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
@throw ExecutionFailedExc in case of any failure or if the
|
|
|
|
executed program does not return a zero exit status. */
|
|
|
|
std::string& error() throw(std::exception);
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
/** @return
|
|
|
|
- @c true if the last execution was successful
|
|
|
|
- @c false if the last execution failed or the command was
|
|
|
|
never executed */
|
|
|
|
bool success() throw(std::bad_exception);
|
|
|
|
|
|
|
|
//................................................................ methods
|
|
|
|
private:
|
|
|
|
|
|
|
|
Exec(); // no default constructor
|
|
|
|
|
|
|
|
//.............................................................. variables
|
|
|
|
private:
|
|
|
|
|
|
|
|
friend class PartialExec; // don't want the variables protected
|
|
|
|
mrw::Cmd* _cmd;
|
|
|
|
std::string _res, _err;
|
|
|
|
bool _success;
|
2004-04-21 06:39:20 +00:00
|
|
|
};
|
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
//============================================================================
|
|
|
|
/** @brief Execute a UNIX program in non blocking parts.
|
|
|
|
@pre #include <mrw/exec.hpp>
|
|
|
|
|
|
|
|
A given UNIX command is executed, but the class does not wait
|
|
|
|
until it is finished, instead it gives back the control to the
|
|
|
|
caller. This behaviour is achieved using non blocking
|
|
|
|
communication. But the caller is responsible to retrieve all
|
|
|
|
information from the client, and if necessary to close the input
|
|
|
|
pipe of the client executable program. Therefore you have to
|
|
|
|
give back control from time to time, normally this is doen in a
|
|
|
|
@c while loop, where you can execute also different thing,
|
|
|
|
e.g. update a display of the result or similar.
|
|
|
|
|
|
|
|
With this class, you can communicate with a child process, and
|
|
|
|
do other things at the same time, without the need for multi
|
|
|
|
threading.
|
|
|
|
|
|
|
|
Execution of a program works the following way:
|
|
|
|
- do not use execute() (otherwise the behaviours is identical
|
|
|
|
to class mrw::Exec, you gain nothing, but also loose nothing)
|
|
|
|
- use start() to start the external program
|
|
|
|
- use start() or @c start(false) if you don't want to pass
|
|
|
|
input to the child process
|
|
|
|
- use @c start(true) if you want to pass input to the
|
|
|
|
child process
|
|
|
|
- if you called @c start(true), call finish() if you have no more
|
|
|
|
input to send to the child process (it's like an end-of-file)
|
|
|
|
- the execution is not terminated, before finished() returns
|
|
|
|
@c true
|
|
|
|
- while finished() is false, subsequently call read() to read
|
|
|
|
the output of the child process
|
|
|
|
|
|
|
|
@warning After calling finish(), or if you did not call
|
|
|
|
start() with parameter @c true, it is forbidden to
|
|
|
|
pass anything but an empty string as first parameter to
|
|
|
|
read()! Anything else is a programming error and
|
|
|
|
results in an assertion failure and a core dump!
|
|
|
|
|
|
|
|
@note If your program seems to hang, check if you call finish()
|
|
|
|
correctly!
|
|
|
|
|
|
|
|
Here an example:
|
|
|
|
@code
|
|
|
|
mrw::PartialExec exec = mrw::Cmd("/bin/cat").start(true);
|
|
|
|
std::string res = exec.read("This is a test\n").first;
|
|
|
|
res += exec.read("This is another test\n").first;
|
|
|
|
exec.finish(); // close the input pipe of @c cat
|
|
|
|
while (!exec.finished()) res+=exec.read().first;
|
|
|
|
@endcode */
|
|
|
|
class PartialExec: public Exec {
|
|
|
|
|
|
|
|
//................................................................ methods
|
|
|
|
public:
|
|
|
|
|
|
|
|
/** @brief Create an executor given a command.
|
|
|
|
Construction without passing a command is not possible. */
|
|
|
|
PartialExec(const mrw::Cmd&) throw(std::bad_exception);
|
|
|
|
|
|
|
|
/** @brief Copy construction invalidates the original object.
|
|
|
|
|
|
|
|
All opened pipes (opened with start()) are lost in the
|
|
|
|
original object and are then owned by the new object. */
|
|
|
|
PartialExec(mrw::PartialExec&) throw(std::bad_exception);
|
|
|
|
|
|
|
|
/** @brief Copy construction invalidates the original object.
|
|
|
|
|
|
|
|
@copydoc PartialExec(mrw::PartialExec&)
|
|
|
|
|
|
|
|
@warning @c const for the argument is a fake! It is casted away!
|
|
|
|
|
|
|
|
@param e @b Warning: const is casted away! */
|
|
|
|
PartialExec(const mrw::PartialExec& e) throw(std::bad_exception);
|
|
|
|
|
|
|
|
/** @brief Assignment invalidates the original object.
|
|
|
|
|
|
|
|
@copydoc PartialExec(mrw::PartialExec&) */
|
|
|
|
PartialExec& operator=(mrw::PartialExec&) throw(std::bad_exception);
|
|
|
|
|
|
|
|
/** @brief Close the input pipe of the child process.
|
|
|
|
|
|
|
|
If start() is called with argument @c false, then you
|
|
|
|
can pass input to @c stdin of the child process, but you @b
|
|
|
|
must call this method, after passing the last input
|
|
|
|
string. Otherwise, the child's input pipe won't be closed,
|
|
|
|
the child process does not stop waiting for more input! If
|
|
|
|
your program seems to hang, check if you call finish()
|
|
|
|
correctly! */
|
|
|
|
PartialExec& finish() throw();
|
|
|
|
|
|
|
|
/** @brief Check if there's more data left to read().
|
|
|
|
@return @c true if the child process has finished and all
|
|
|
|
data is read. */
|
|
|
|
bool finished() throw();
|
|
|
|
|
|
|
|
/** @brief Start a new child process.
|
|
|
|
|
|
|
|
At most one child process can run at the same time.
|
|
|
|
|
|
|
|
@throw mrw::runtime_error if a previous child has not finished() yet
|
|
|
|
@throw mrw::ExecutionFailedExc if the child process cannot be started
|
|
|
|
@param useInput
|
|
|
|
- @c true if input will be sent to the child's @c stdin
|
|
|
|
- pass all input in the first parameter of read()
|
|
|
|
- finish() must be called when all input is sent
|
|
|
|
- @c false if no input is sent to the child's @c stdin
|
|
|
|
- the first parameter of read must allways be passed an
|
|
|
|
empty string */
|
|
|
|
PartialExec& start(bool useInput=false) throw(std::exception);
|
|
|
|
|
|
|
|
/** @brief Read from the subprocess, optionally pass an @c input to
|
|
|
|
@c stdin of the subprocess.
|
|
|
|
|
|
|
|
@param input a string to pass to the child processes @c stdin
|
|
|
|
|
|
|
|
@param exc
|
|
|
|
- @c true throw an exception if return status is not zero
|
|
|
|
- @c false throw only an exception in case of a fatal error
|
|
|
|
|
|
|
|
@return a pair containing the last read @c stdout and @c stderr
|
|
|
|
of the child
|
|
|
|
|
|
|
|
@throw ExecutionFailedExc is thrown if
|
|
|
|
- fork fails
|
|
|
|
- creation or setup of pipes failed
|
|
|
|
- if given parameter is @c true (the default) also if the
|
|
|
|
executed program terminates with an error
|
|
|
|
|
|
|
|
@note If start() was not called with parameter @c true, then
|
|
|
|
@c input must always be an empty string!
|
|
|
|
|
|
|
|
@pre start() was called */
|
|
|
|
std::pair<std::string, std::string> read(const std::string& input="",
|
|
|
|
bool exc=true)
|
|
|
|
throw(std::exception);
|
|
|
|
|
|
|
|
/// Terminates a running job by sending @c SIGTERM to the child process.
|
|
|
|
PartialExec& terminate() throw();
|
|
|
|
|
2005-04-20 18:12:55 +00:00
|
|
|
/// Kills a running job by sending @c SIGKILL to the child process.
|
|
|
|
PartialExec& kill() throw();
|
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
//................................................................ methods
|
|
|
|
private:
|
|
|
|
|
|
|
|
PartialExec(); // no default constructor
|
|
|
|
|
|
|
|
//.............................................................. variables
|
|
|
|
private:
|
|
|
|
|
|
|
|
bool _finished;
|
|
|
|
bool _finish;
|
|
|
|
std::auto_ptr<mrw::Pipe> _stdIn, _stdOut, _stdErr;
|
|
|
|
std::string _input;
|
|
|
|
int _num0, _num1, _num2, _lastPid, _pid;
|
|
|
|
};
|
|
|
|
|
|
|
|
//============================================================================
|
2004-04-21 06:39:20 +00:00
|
|
|
/** @brief A system command to be executed
|
2004-04-23 16:03:29 +00:00
|
|
|
@pre #include <mrw/exec.hpp>
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2004-12-14 20:30:10 +00:00
|
|
|
This class is used in conjunction with mrw::Exec. It must be
|
2004-04-21 06:39:20 +00:00
|
|
|
initialized with the command name, then the command parameters
|
|
|
|
are appended either with commas, or by streaming them into the
|
|
|
|
command, whatever you like.
|
|
|
|
|
|
|
|
You can stream the data into the class:
|
|
|
|
|
|
|
|
@code
|
|
|
|
mrw::Cmd ls("/bin/ls"); // the command to execute is: /bin/ls
|
|
|
|
ls<<"-l"<<"/tmp"; // the command is now: /bin/ls -l /tmp
|
|
|
|
@endcode
|
|
|
|
|
|
|
|
Or you can setup your command with commas:
|
|
|
|
|
|
|
|
@code
|
|
|
|
mrw::Cmd ls = (mrw::Cmd(/bin/ls), "-l", "/tmp");
|
|
|
|
@endcode
|
|
|
|
*/
|
|
|
|
class Cmd {
|
2005-04-19 18:48:00 +00:00
|
|
|
public:
|
|
|
|
/** @brief Create a command given the name of the executable
|
|
|
|
@param command the name of the program to execute (no parameter)
|
|
|
|
@note There is no default constructor. */
|
|
|
|
Cmd(const std::string& command) throw(std::bad_exception);
|
|
|
|
|
|
|
|
/** @brief Append a parameter to a command
|
|
|
|
@param param a parameter / commandline argument
|
|
|
|
to append to the command */
|
|
|
|
Cmd& operator,(const std::string& param) throw(std::bad_exception);
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
/** @brief Append a parameter to a command
|
|
|
|
@param param a parameter / commandline argument
|
|
|
|
to append to the command */
|
|
|
|
Cmd& operator<<(const std::string& param) throw(std::bad_exception);
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
/** @return the command including parameter */
|
|
|
|
operator std::string() const throw(std::bad_exception);
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
/** @return a mrw::Exec that's constructed with this class */
|
|
|
|
operator mrw::Exec() const throw(std::bad_exception);
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
/** @return a mrw::PartialExec that's constructed with this class */
|
|
|
|
operator mrw::PartialExec() const throw(std::bad_exception);
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
/** @brief Create a mrw::Exec and execute a child process.
|
|
|
|
@see Exec::execute(bool) */
|
|
|
|
Exec execute(bool exc=true) const throw(std::exception);
|
2004-04-21 06:39:20 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
/** @brief Create a mrw::Exec and execute a child process.
|
|
|
|
@see Exec::execute(const std::string&, bool) */
|
|
|
|
Exec execute(const std::string& input, bool exc=true) const
|
|
|
|
throw(std::exception);
|
2004-12-14 20:30:10 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
/** @brief Create a mrw::Exec and execute a child process.
|
|
|
|
@see Exec::execute(char const*const, bool) */
|
|
|
|
Exec execute(char const*const input, bool exc=true) const
|
|
|
|
throw(std::exception) {
|
|
|
|
return execute(std::string(input), exc);
|
|
|
|
}
|
2004-12-14 20:30:10 +00:00
|
|
|
|
2005-04-19 18:48:00 +00:00
|
|
|
/** @brief Create a new mrw::PartialExec and start a new child process.
|
|
|
|
@see PartialExec::start(bool) */
|
|
|
|
PartialExec start(bool useInput=false) const throw(std::exception);
|
2004-12-14 20:30:10 +00:00
|
|
|
|
2004-04-21 06:39:20 +00:00
|
|
|
private:
|
2005-04-19 18:48:00 +00:00
|
|
|
// Exec and PartialExec are allowed to call @c path() and @c args().
|
2004-08-28 16:21:25 +00:00
|
|
|
friend class Exec;
|
2005-04-19 18:48:00 +00:00
|
|
|
friend class PartialExec;
|
|
|
|
Cmd(); // No default constructor.
|
2004-04-21 06:39:20 +00:00
|
|
|
const char* path() const throw(std::bad_exception);
|
|
|
|
char** args() const throw(std::bad_exception);
|
|
|
|
typedef std::list<std::string> ArgList;
|
|
|
|
ArgList _cmd;
|
|
|
|
};
|
2005-04-19 18:48:00 +00:00
|
|
|
|
2004-04-21 06:39:20 +00:00
|
|
|
//@}
|
|
|
|
}
|
|
|
|
#endif
|