/** @file sample for call of an external executable
*
* Last CVS checkin:
* $Date: $
* $Author: scheff $
*/
/**************************************************************************/
// standard C/C++ header:
#include <iostream>
#include <string>
#include <vector>
// Gnome header:
#include <glibmm/miscutils.h>
#include <glibmm/spawn.h>
using namespace std;
/**************************************************************************/
/** provides an output operator for vector<string>.
*
* @param out the output stream
* @param strv the string vector
* @return the output stream
*/
ostream& operator << (ostream &out, const vector<string> &strv)
{
if (!strv.empty()) {
vector<string>::const_iterator it;
for (it = strv.begin();;) {
out << *it; ++it; if (it != strv.end()) out << ' '; else break;
}
}
return out;
}
/** waits for user confirm.
*
* @param action text with next action
*/
static void pause(const char *action)
{
cerr << "spawn: Press [ENTER] to " << action << ": " << flush;
string str; getline(cin, str);
}
/** provides the main function of application.
*
* @param argc number of command line arguments
* @param argv pointer to array of pointers to strings with command line
* arguments
* @return 0 ... application exited regularly\n
* else ... execution of application aborted
*/
int main(int argc, char *argv[])
{
cout << "spawn: start" << endl;
// build file path
#ifdef WIN32
string file;
{ gchar *dir = g_win32_get_package_installation_directory_of_module(0);
file = Glib::build_filename(dir, "test-spawn.exe");
g_free(dir);
}
#else // WIN32
string file
= Glib::build_filename(Glib::get_current_dir(), "test-spawn");
#endif // WIN32
// spawn regular
{ vector<string> args;
args.push_back(file);
// spawn
cout << "spawn: spawn_sync(" << args << "):" << endl;
try {
Glib::spawn_sync(".", args,
Glib::SPAWN_CHILD_INHERITS_STDIN);
} catch (const Glib::SpawnError &error) {
cerr << "spawn: ERROR: " << error.what() << endl;
}
}
pause("continue");
// spawn with missing app.
{ vector<string> args;
// spawn
cout << "spawn: spawn_sync(" << args << "):" << endl;
try {
Glib::spawn_sync(".", args,
Glib::SPAWN_CHILD_INHERITS_STDIN);
} catch (const Glib::SpawnError &error) {
cerr << "spawn: ERROR: " << error.what() << endl;
}
}
pause("continue");
// spawn with error return
{ vector<string> args;
args.push_back(file); args.push_back("-return"); args.push_back("1");
// spawn
cout << "spawn: spawn_sync(" << args << "):" << endl;
try {
int exitCode;
Glib::spawn_sync(".", args,
Glib::SPAWN_CHILD_INHERITS_STDIN,
sigc::slot<void>(), 0, 0, &exitCode);
cout << "spawn: Received exit code: " << exitCode << endl;
} catch (const Glib::SpawnError &error) {
cerr << "spawn: ERROR: " << error.what() << endl;
}
}
pause("continue");
// spawn with exception
{ vector<string> args;
args.push_back(file); args.push_back("-throw");
// spawn
cout << "spawn: spawn_sync(" << args << "):" << endl;
try {
int exitCode;
Glib::spawn_sync(".", args,
Glib::SPAWN_CHILD_INHERITS_STDIN,
sigc::slot<void>(), 0, 0, &exitCode);
cout << "spawn: Received exit code: " << exitCode << endl;
} catch (const Glib::SpawnError &error) {
cerr << "spawn: ERROR: " << error.what() << endl;
}
}
pause("continue");
// spawn with standard channels
{ vector<string> args;
args.push_back(file); args.push_back("-nopause");
// spawn
cout << "spawn: spawn_sync(" << args << "):" << endl;
try {
string output, error; int exitCode;
Glib::spawn_sync(".", args,
Glib::SpawnFlags(0),
sigc::slot<void>(), &output, &error, &exitCode);
cout << "spawn: Received on standard output:" << endl
<< output << endl;
cout << "spawn: Received on standard error:" << endl
<< error << endl;
cout << "spawn: Received exit code: " << exitCode << endl;
} catch (const Glib::SpawnError &error) {
cerr << "spawn: ERROR: " << error.what() << endl;
}
}
#if 0 // This problem isn't solved, satisfying!
pause("continue");
// spawn with merged standard output and error
{ vector<string> args;
args.push_back(file);
try {
string output; int exitCode = 0;
/* This doesn't work:
Glib::spawn_sync(".", args, Glib::SpawnFlags(0),
sigc::slot<void>(), &output, &output, &exitCode);
* Var. output receives only error channel!
* Output channel gets lost.
*/
/* This doesn't work, also:
Glib::spawn_sync(".", args, Glib::SpawnFlags(0),
sigc::slot<void>(), &output, 0, &exitCode);
* Var. output receives only output channel!
* Error channel goes to console.
*/
cout << "spawn: Received on standard output:" << endl
<< output << endl;
cout << "spawn: Received exit code: " << exitCode << endl;
} catch (const Glib::SpawnError &error) {
cerr << "spawn: ERROR: " << error.what() << endl;
}
}
#endif // 0
// done
pause("finish");
return 0;
}
|