summaryrefslogtreecommitdiffstats
path: root/grapher
diff options
context:
space:
mode:
authorDave Brolley <brolley@redhat.com>2009-11-03 16:22:36 -0500
committerDave Brolley <brolley@redhat.com>2009-11-03 16:22:36 -0500
commit899b66209b0146560f0efc33efe58a4be3577df3 (patch)
tree7b64764b917c359a99d0adcf6c68a2d73cd52be7 /grapher
parentd4ad7984018ff769cbb662342be7e501632c0bea (diff)
parent89651893a8ec51ee4d77ddfd57019e350ad7b169 (diff)
downloadsystemtap-steved-899b66209b0146560f0efc33efe58a4be3577df3.tar.gz
systemtap-steved-899b66209b0146560f0efc33efe58a4be3577df3.tar.xz
systemtap-steved-899b66209b0146560f0efc33efe58a4be3577df3.zip
Merge branch 'master' of ssh://sources.redhat.com/git/systemtap
Conflicts: Makefile.in configure doc/Makefile.in doc/SystemTap_Tapset_Reference/Makefile.in grapher/Makefile.in testsuite/configure
Diffstat (limited to 'grapher')
-rw-r--r--grapher/GraphData.hxx13
-rw-r--r--grapher/StapParser.cxx68
-rw-r--r--grapher/StapParser.hxx14
-rw-r--r--grapher/grapher.cxx454
4 files changed, 318 insertions, 231 deletions
diff --git a/grapher/GraphData.hxx b/grapher/GraphData.hxx
index e4c08cfd..0e26fb4d 100644
--- a/grapher/GraphData.hxx
+++ b/grapher/GraphData.hxx
@@ -6,6 +6,8 @@
#include <vector>
#include <tr1/memory>
+#include <boost/circular_buffer.hpp>
+
namespace systemtap
{
struct GraphDataBase
@@ -16,11 +18,12 @@ namespace systemtap
DOT,
EVENT
};
- GraphDataBase() : scale(1.0), style(BAR)
+ typedef boost::circular_buffer<double> TimeList;
+ GraphDataBase(TimeList::capacity_type cap = 50000)
+ : scale(1.0), style(BAR), times(cap)
{
color[0] = 0.0; color[1] = 1.0; color[2] = 0.0;
}
- typedef std::vector<double> TimeList;
// size of grid square at "normal" viewing
double scale;
double color[3];
@@ -36,7 +39,11 @@ namespace systemtap
{
public:
typedef T data_type;
- typedef std::vector<data_type> DataList;
+ typedef boost::circular_buffer<data_type> DataList;
+ GraphData(typename DataList::capacity_type cap = 50000)
+ : GraphDataBase(cap), data(cap)
+ {
+ }
DataList data;
};
struct CSVData
diff --git a/grapher/StapParser.cxx b/grapher/StapParser.cxx
index 9bb9b9c9..9e42dab6 100644
--- a/grapher/StapParser.cxx
+++ b/grapher/StapParser.cxx
@@ -63,17 +63,17 @@ vector<string> commaSplit(const boost::sub_range<Glib::ustring>& range)
using namespace boost;
if (ioCondition & Glib::IO_HUP)
{
- _win.hide();
+ _win->hide();
return true;
}
if ((ioCondition & Glib::IO_IN) == 0)
return true;
char buf[256];
ssize_t bytes_read = 0;
- bytes_read = read(STDIN_FILENO, buf, sizeof(buf) - 1);
+ bytes_read = read(_inFd, buf, sizeof(buf) - 1);
if (bytes_read <= 0)
{
- _win.hide();
+ _win->hide();
return true;
}
buf[bytes_read] = '\0';
@@ -108,7 +108,7 @@ vector<string> commaSplit(const boost::sub_range<Glib::ustring>& range)
dataSet->color[2] = (hexColor & 0xff) / 255.0;
dataSet->scale = scale;
_dataSets.insert(std::make_pair(setName, dataSet));
- _widget.addGraphData(dataSet);
+ _widget->addGraphData(dataSet);
}
else if (style == "discreet")
{
@@ -120,7 +120,7 @@ vector<string> commaSplit(const boost::sub_range<Glib::ustring>& range)
dataSet->color[2] = (hexColor & 0xff) / 255.0;
dataSet->scale = scale;
_dataSets.insert(std::make_pair(setName, dataSet));
- _widget.addGraphData(dataSet);
+ _widget->addGraphData(dataSet);
}
}
else if ((found = find_first(dataString, "%CSV:")))
@@ -156,18 +156,15 @@ vector<string> commaSplit(const boost::sub_range<Glib::ustring>& range)
shared_ptr<GraphDataBase> gdata = itr->second;
string decl;
// Hack: scan from the beginning of dataString again
- if (findTaggedValue(dataString, "%Title:", decl)
- != string::npos)
+ if (findTaggedValue(dataString, "%Title:", decl))
{
gdata->title = decl;
}
- else if (findTaggedValue(dataString, "%XAxisTitle:", decl)
- != string::npos)
+ else if (findTaggedValue(dataString, "%XAxisTitle:", decl))
{
gdata->xAxisText = decl;
}
- else if (findTaggedValue(dataString, "%YAxisTitle:", decl)
- != string::npos)
+ else if (findTaggedValue(dataString, "%YAxisTitle:", decl))
{
gdata->yAxisText = decl;
}
@@ -179,29 +176,32 @@ vector<string> commaSplit(const boost::sub_range<Glib::ustring>& range)
stream >> ymax;
gdata->scale = ymax;
}
-
- if (!_csv.elements.empty())
- {
- vector<string> tokens = commaSplit(dataString);
- int i = 0;
- double time;
- vector<string>::iterator tokIter = tokens.begin();
- std::istringstream timeStream(*tokIter++);
- timeStream >> time;
- for (vector<string>::iterator e = tokens.end();
- tokIter != e;
- ++tokIter, ++i)
- {
- parseData(_csv.elements[i].second, time, *tokIter);
- }
- }
else
- {
- double time;
- string data;
- stream >> time >> data;
- parseData(itr->second, time, data);
- }
+ {
+ if (!_csv.elements.empty())
+ {
+ vector<string> tokens = commaSplit(dataString);
+ int i = 0;
+ double time;
+ vector<string>::iterator tokIter = tokens.begin();
+ std::istringstream timeStream(*tokIter++);
+ timeStream >> time;
+ for (vector<string>::iterator e = tokens.end();
+ tokIter != e;
+ ++tokIter, ++i)
+ {
+ parseData(_csv.elements[i].second, time,
+ *tokIter);
+ }
+ }
+ else
+ {
+ double time;
+ string data;
+ stream >> time >> data;
+ parseData(itr->second, time, data);
+ }
+ }
}
}
_buffer.erase(0, ret + 1);
@@ -219,7 +219,7 @@ vector<string> commaSplit(const boost::sub_range<Glib::ustring>& range)
bytes_read = read(_errFd, buf, sizeof(buf) - 1);
if (bytes_read <= 0)
{
- _win.hide();
+ _win->hide();
return true;
}
if (write(STDOUT_FILENO, buf, bytes_read) < 0)
diff --git a/grapher/StapParser.hxx b/grapher/StapParser.hxx
index f4f6bdef..40add9fd 100644
--- a/grapher/StapParser.hxx
+++ b/grapher/StapParser.hxx
@@ -10,17 +10,23 @@ class StapParser
typedef std::map<std::string, std::tr1::shared_ptr<GraphDataBase> > DataMap;
DataMap _dataSets;
CSVData _csv;
- Gtk::Window& _win;
- GraphWidget& _widget;
+ Gtk::Window* _win;
+ GraphWidget* _widget;
int _errFd;
+ int _inFd;
public:
- StapParser(Gtk::Window& win,
- GraphWidget& widget) : _win(win), _widget(widget), _errFd(-1) {}
+ StapParser(Gtk::Window* win,
+ GraphWidget* widget) : _win(win), _widget(widget), _errFd(-1),
+ _inFd(-1)
+ {
+ }
void parseData(std::tr1::shared_ptr<GraphDataBase> gdata,
double time, const std::string& dataString);
bool ioCallback(Glib::IOCondition ioCondition);
bool errIoCallback(Glib::IOCondition ioCondition);
int getErrFd() { return _errFd; }
void setErrFd(int fd) { _errFd = fd; }
+ int getInFd() { return _inFd; }
+ void setInFd(int fd) { _inFd = fd; }
};
}
diff --git a/grapher/grapher.cxx b/grapher/grapher.cxx
index 429d0537..fe9880b2 100644
--- a/grapher/grapher.cxx
+++ b/grapher/grapher.cxx
@@ -10,10 +10,13 @@
#include <sstream>
#include <string>
#include <map>
+#include <memory>
#include <vector>
#include <signal.h>
+#include <boost/bind.hpp>
+
#include <gtkmm.h>
#include <gtkmm/button.h>
#include <gtkmm/stock.h>
@@ -31,6 +34,20 @@ using namespace std;
using namespace systemtap;
+// magic for noticing that the child stap process has died.
+int signalPipe[2] = {-1, -1};
+
+extern "C"
+{
+ void handleChild(int signum, siginfo_t* info, void* context)
+ {
+ char buf[1];
+ ssize_t err;
+ buf[0] = 1;
+ err = write(signalPipe[1], buf, 1);
+ }
+}
+
// Waits for a gtk I/O signal, indicating that a child has died, then
// performs an action
@@ -46,6 +63,20 @@ public:
ChildDeathReader(int sigfd_) : sigfd(sigfd_) {}
int getSigfd() { return sigfd; }
void setSigfd(int sigfd_) { sigfd = sigfd_; }
+ virtual pid_t reap()
+ {
+ pid_t pid;
+ int status;
+ if ((pid = waitpid(-1, &status, WNOHANG)) == -1)
+ {
+ std::perror("waitpid");
+ return -1;
+ }
+ else
+ {
+ return pid;
+ }
+ }
bool ioCallback(Glib::IOCondition ioCondition)
{
if ((ioCondition & Glib::IO_IN) == 0)
@@ -54,152 +85,26 @@ public:
if (read(sigfd, &buf, 1) <= 0)
return true;
- int status;
- while (wait(&status) != -1)
- ;
+ reap();
return true;
}
private:
int sigfd;
};
-class StapLauncher;
-
-class GraphicalStapLauncher
-{
-public:
- GraphicalStapLauncher(StapLauncher* launcher);
- bool runDialog();
- void onLaunch();
- void onLaunchCancel();
-private:
- Glib::RefPtr<Gnome::Glade::Xml> _launchStapDialog;
- Gtk::Window* _scriptWindow;
- Gtk::FileChooserButton* _chooserButton;
- Gtk::Entry* _stapArgEntry;
- Gtk::Entry* _scriptArgEntry;
- StapLauncher* _launcher;
-};
-
-class GrapherWindow : public Gtk::Window, public ChildDeathReader::Callback
-{
-public:
- GrapherWindow();
- virtual ~GrapherWindow() {}
- Gtk::VBox m_Box;
- Gtk::ScrolledWindow scrolled;
- GraphWidget w;
- void childDied(int pid);
- void setGraphicalLauncher(GraphicalStapLauncher* launcher)
- {
- _graphicalLauncher = launcher;
- }
- GraphicalStapLauncher* getGraphicalLauncher() { return _graphicalLauncher; }
-protected:
- virtual void on_menu_file_quit();
- virtual void on_menu_script_start();
- void addGraph();
- // menu support
- Glib::RefPtr<Gtk::UIManager> m_refUIManager;
- Glib::RefPtr<Gtk::ActionGroup> m_refActionGroup;
- GraphicalStapLauncher* _graphicalLauncher;
-
-};
-
-GrapherWindow::GrapherWindow()
-{
- set_title("systemtap grapher");
- add(m_Box);
-
-
- //Create actions for menus and toolbars:
- m_refActionGroup = Gtk::ActionGroup::create();
- //File menu:
- m_refActionGroup->add(Gtk::Action::create("FileMenu", "File"));
- m_refActionGroup->add(Gtk::Action::create("StartScript", "Start script"),
- sigc::mem_fun(*this,
- &GrapherWindow::on_menu_script_start));
- m_refActionGroup->add(Gtk::Action::create("AddGraph", "Add graph"),
- sigc::mem_fun(*this, &GrapherWindow::addGraph));
- m_refActionGroup->add(Gtk::Action::create("FileQuit", Gtk::Stock::QUIT),
- sigc::mem_fun(*this,
- &GrapherWindow::on_menu_file_quit));
- m_refUIManager = Gtk::UIManager::create();
- m_refUIManager->insert_action_group(m_refActionGroup);
-
- add_accel_group(m_refUIManager->get_accel_group());
- //Layout the actions in a menubar and toolbar:
- Glib::ustring ui_info =
- "<ui>"
- " <menubar name='MenuBar'>"
- " <menu action='FileMenu'>"
- " <menuitem action='StartScript'/>"
- " <menuitem action='AddGraph'/>"
- " <menuitem action='FileQuit'/>"
- " </menu>"
- " </menubar>"
- "</ui>";
- try
- {
- m_refUIManager->add_ui_from_string(ui_info);
- }
- catch(const Glib::Error& ex)
- {
- std::cerr << "building menus failed: " << ex.what();
- }
- Gtk::Widget* pMenubar = m_refUIManager->get_widget("/MenuBar");
- scrolled.add(w);
- if(pMenubar)
- m_Box.pack_start(*pMenubar, Gtk::PACK_SHRINK);
- m_Box.pack_start(scrolled, Gtk::PACK_EXPAND_WIDGET);
- scrolled.show();
-
- show_all_children();
-
-}
-
-void GrapherWindow::on_menu_file_quit()
-{
- hide();
-}
-
-void GrapherWindow::on_menu_script_start()
-{
- _graphicalLauncher->runDialog();
-}
-
-void GrapherWindow::childDied(int pid)
-{
- hide();
-}
-
-// magic for noticing that the child stap process has died.
-int signalPipe[2] = {-1, -1};
-
-extern "C"
-{
- void handleChild(int signum, siginfo_t* info, void* context)
- {
- char buf[1];
- ssize_t err;
- buf[0] = 1;
- err = write(signalPipe[1], buf, 1);
- }
-}
-
// Depending on how args are passed, either launch stap directly or
// use the shell to parse arguments
class StapLauncher : public ChildDeathReader
{
public:
- StapLauncher() : _argv(0), _childPid(-1), _deathCallback(0), _stapParser(0) {}
+ StapLauncher() : _argv(0), _childPid(-1), _deathCallback(0) {}
StapLauncher(char** argv)
- : _argv(argv), _childPid(-1), _deathCallback(0), _stapParser(0)
+ : _argv(argv), _childPid(-1), _deathCallback(0)
{
}
StapLauncher(const string& stapArgs, const string& script,
const string& scriptArgs)
- : _childPid(-1), _deathCallback(0), _stapParser(0)
+ : _childPid(-1), _deathCallback(0), _win(0), _widget(0)
{
setArgs(stapArgs, script, scriptArgs);
}
@@ -239,12 +144,41 @@ public:
{
_deathCallback = callback;
}
- void setStapParser(StapParser *parser)
+ void setWinParams(Gtk::Window* win, GraphWidget* widget)
{
- _stapParser = parser;
+ _win = win;
+ _widget = widget;
}
int launch();
void cleanUp();
+ tr1::shared_ptr<StapParser> makeStapParser()
+ {
+ tr1::shared_ptr<StapParser> result(new StapParser(_win, _widget));
+ _parsers.push_back(ParserInstance(-1, result));
+ return result;
+ }
+ pid_t reap()
+ {
+ pid_t pid = ChildDeathReader::reap();
+ if (pid < 0)
+ return pid;
+ ParserList::iterator itr
+ = find_if(_parsers.begin(), _parsers.end(),
+ boost::bind(&ParserInstance::childPid, _1) == pid);
+ if (itr != _parsers.end())
+ itr->childPid = -1;
+ return pid;
+ }
+ void killAll()
+ {
+ for (ParserList::iterator itr = _parsers.begin(), end = _parsers.end();
+ itr != end;
+ ++itr)
+ {
+ if (itr->childPid >= 0)
+ kill(itr->childPid, SIGTERM);
+ }
+ }
protected:
char** _argv;
string _stapArgs;
@@ -252,17 +186,39 @@ protected:
string _scriptArgs;
int _childPid;
ChildDeathReader::Callback* _deathCallback;
- StapParser* _stapParser;
+ Gtk::Window* _win;
+ GraphWidget* _widget;
+ struct ParserInstance
+ {
+ ParserInstance() : childPid(-1) {}
+ ParserInstance(int childPid_, tr1::shared_ptr<StapParser> stapParser_)
+ : childPid(childPid_), stapParser(stapParser_)
+ {
+ }
+ pid_t childPid;
+ tr1::shared_ptr<StapParser> stapParser;
+ };
+ typedef vector<ParserInstance> ParserList;
+ ParserList _parsers;
};
int StapLauncher::launch()
{
- int stapErrFd = -1;
-
- if (pipe(&signalPipe[0]) < 0)
+ int childPid = -1;
+ if (signalPipe[0] < 0)
{
- std::perror("pipe");
- exit(1);
+ if (pipe(&signalPipe[0]) < 0)
+ {
+ std::perror("pipe");
+ exit(1);
+ }
+ setSigfd(signalPipe[0]);
+ if (signalPipe[0] >= 0)
+ {
+ Glib::signal_io().connect(sigc::mem_fun(*this,
+ &ChildDeathReader::ioCallback),
+ signalPipe[0], Glib::IO_IN);
+ }
}
struct sigaction action;
action.sa_sigaction = handleChild;
@@ -280,15 +236,12 @@ int StapLauncher::launch()
std::perror("pipe");
exit(1);
}
- if ((_childPid = fork()) == -1)
+ if ((childPid = fork()) == -1)
{
exit(1);
}
- else if (_childPid)
+ else if (childPid)
{
- dup2(pipefd[0], STDIN_FILENO);
- stapErrFd = pipefd[2];
- close(pipefd[0]);
close(pipefd[1]);
close(pipefd[3]);
}
@@ -296,8 +249,8 @@ int StapLauncher::launch()
{
dup2(pipefd[1], STDOUT_FILENO);
dup2(pipefd[3], STDERR_FILENO);
- for (int i = 0; i < 4; ++i)
- close(pipefd[i]);
+ for_each(&pipefd[0], &pipefd[4], close);
+ for_each(&signalPipe[0], &signalPipe[2], close);
if (_argv)
{
char argv0[] = "stap";
@@ -318,70 +271,192 @@ int StapLauncher::launch()
}
_exit(1);
}
- if (stapErrFd >= 0)
- {
- _stapParser->setErrFd(stapErrFd);
- Glib::signal_io().connect(sigc::mem_fun(*_stapParser,
- &StapParser::errIoCallback),
- stapErrFd,
- Glib::IO_IN);
- }
- setSigfd(signalPipe[0]);
- if (signalPipe[0] >= 0)
- {
- Glib::signal_io().connect(sigc::mem_fun(*this,
- &ChildDeathReader::ioCallback),
- signalPipe[0], Glib::IO_IN);
- }
- Glib::signal_io().connect(sigc::mem_fun(*_stapParser,
+ tr1::shared_ptr<StapParser> sp(new StapParser(_win, _widget));
+ _parsers.push_back(ParserInstance(childPid, sp));
+ sp->setErrFd(pipefd[2]);
+ sp->setInFd(pipefd[0]);
+ Glib::signal_io().connect(sigc::mem_fun(sp.get(),
+ &StapParser::errIoCallback),
+ pipefd[2],
+ Glib::IO_IN);
+ Glib::signal_io().connect(sigc::mem_fun(sp.get(),
&StapParser::ioCallback),
- STDIN_FILENO,
+ pipefd[0],
Glib::IO_IN | Glib::IO_HUP);
- return _childPid;
+ return childPid;
}
void StapLauncher::cleanUp()
{
- if (_childPid > 0)
- kill(_childPid, SIGTERM);
- int status;
- while (wait(&status) != -1)
- ;
- if (_deathCallback)
+ struct sigaction action;
+ action.sa_handler = SIG_DFL;
+ sigemptyset(&action.sa_mask);
+ action.sa_flags = 0;
+ sigaction(SIGCLD, &action, 0);
+ // Drain any outstanding signals
+ close(signalPipe[1]);
+ char buf;
+ while (read(signalPipe[0], &buf, 1) > 0)
+ reap();
+ for (ParserList::iterator itr = _parsers.begin(), end = _parsers.end();
+ itr != end;
+ ++itr)
{
- _deathCallback->childDied(_childPid);
- _childPid = -1;
+ if (itr->childPid > 0)
+ kill(itr->childPid, SIGTERM);
+ int status;
+ pid_t killedPid = -1;
+ if ((killedPid = wait(&status)) == -1)
+ {
+ std::perror("wait");
+ }
+ else if (killedPid != itr->childPid)
+ {
+ std::cerr << "wait: killed Pid " << killedPid << " != child Pid "
+ << itr->childPid << "\n";
+ }
+ else if (_deathCallback)
+ _deathCallback->childDied(itr->childPid);
}
}
-StapLauncher launcher;
+class GraphicalStapLauncher : public StapLauncher
+{
+public:
+ GraphicalStapLauncher();
+ bool runDialog();
+ void onLaunch();
+ void onLaunchCancel();
+private:
+ Glib::RefPtr<Gnome::Glade::Xml> _launchStapDialog;
+ Gtk::Window* _scriptWindow;
+ Gtk::FileChooserButton* _chooserButton;
+ Gtk::Entry* _stapArgEntry;
+ Gtk::Entry* _scriptArgEntry;
+};
+
+class GrapherWindow : public Gtk::Window, public ChildDeathReader::Callback
+{
+public:
+ GrapherWindow();
+ virtual ~GrapherWindow() {}
+ Gtk::VBox m_Box;
+ Gtk::ScrolledWindow scrolled;
+ GraphWidget w;
+ void childDied(int pid);
+ void setGraphicalLauncher(GraphicalStapLauncher* launcher)
+ {
+ _graphicalLauncher = launcher;
+ }
+ GraphicalStapLauncher* getGraphicalLauncher() { return _graphicalLauncher; }
+protected:
+ virtual void on_menu_file_quit();
+ virtual void on_menu_script_start();
+ void addGraph();
+ // menu support
+ Glib::RefPtr<Gtk::UIManager> m_refUIManager;
+ Glib::RefPtr<Gtk::ActionGroup> m_refActionGroup;
+ GraphicalStapLauncher* _graphicalLauncher;
+
+};
+
+GrapherWindow::GrapherWindow()
+{
+ set_title("systemtap grapher");
+ add(m_Box);
+
+
+ //Create actions for menus and toolbars:
+ m_refActionGroup = Gtk::ActionGroup::create();
+ //File menu:
+ m_refActionGroup->add(Gtk::Action::create("FileMenu", "File"));
+ m_refActionGroup->add(Gtk::Action::create("StartScript", "Start script"),
+ sigc::mem_fun(*this,
+ &GrapherWindow::on_menu_script_start));
+ m_refActionGroup->add(Gtk::Action::create("AddGraph", "Add graph"),
+ sigc::mem_fun(*this, &GrapherWindow::addGraph));
+ m_refActionGroup->add(Gtk::Action::create("FileQuit", Gtk::Stock::QUIT),
+ sigc::mem_fun(*this,
+ &GrapherWindow::on_menu_file_quit));
+ m_refUIManager = Gtk::UIManager::create();
+ m_refUIManager->insert_action_group(m_refActionGroup);
+
+ add_accel_group(m_refUIManager->get_accel_group());
+ //Layout the actions in a menubar and toolbar:
+ Glib::ustring ui_info =
+ "<ui>"
+ " <menubar name='MenuBar'>"
+ " <menu action='FileMenu'>"
+ " <menuitem action='StartScript'/>"
+ " <menuitem action='AddGraph'/>"
+ " <menuitem action='FileQuit'/>"
+ " </menu>"
+ " </menubar>"
+ "</ui>";
+ try
+ {
+ m_refUIManager->add_ui_from_string(ui_info);
+ }
+ catch(const Glib::Error& ex)
+ {
+ std::cerr << "building menus failed: " << ex.what();
+ }
+ Gtk::Widget* pMenubar = m_refUIManager->get_widget("/MenuBar");
+ scrolled.add(w);
+ if(pMenubar)
+ m_Box.pack_start(*pMenubar, Gtk::PACK_SHRINK);
+ m_Box.pack_start(scrolled, Gtk::PACK_EXPAND_WIDGET);
+ scrolled.show();
+
+ show_all_children();
+
+}
+
+void GrapherWindow::on_menu_file_quit()
+{
+ hide();
+}
+
+void GrapherWindow::on_menu_script_start()
+{
+ _graphicalLauncher->runDialog();
+}
+
+void GrapherWindow::childDied(int pid)
+{
+ hide();
+}
+
+
+
int main(int argc, char** argv)
{
Gtk::Main app(argc, argv);
-
+ GraphicalStapLauncher launcher;
GrapherWindow win;
win.set_title("Grapher");
win.set_default_size(600, 200);
+ launcher.setWinParams(&win, &win.w);
- StapParser stapParser(win, win.w);
- launcher.setStapParser(&stapParser);
- GraphicalStapLauncher graphicalLauncher(&launcher);
- win.setGraphicalLauncher(&graphicalLauncher);
- if (argc > 1)
- {
- launcher.setArgv(argv + 1);
- launcher.setDeathCallback(&win);
- launcher.launch();
- }
- else
+ win.setGraphicalLauncher(&launcher);
+
+ if (argc == 2 && !std::strcmp(argv[1], "-"))
{
- Glib::signal_io().connect(sigc::mem_fun(stapParser,
+ tr1::shared_ptr<StapParser> sp = launcher.makeStapParser();
+ sp->setInFd(STDIN_FILENO);
+ Glib::signal_io().connect(sigc::mem_fun(sp.get(),
&StapParser::ioCallback),
STDIN_FILENO,
Glib::IO_IN | Glib::IO_HUP);
}
+ else if (argc > 1)
+ {
+ launcher.setArgv(argv + 1);
+ launcher.setDeathCallback(&win);
+ launcher.launch();
+ }
Gtk::Main::run(win);
launcher.cleanUp();
return 0;
@@ -393,8 +468,7 @@ void GrapherWindow::addGraph()
}
-GraphicalStapLauncher::GraphicalStapLauncher(StapLauncher* launcher)
- : _launcher(launcher)
+GraphicalStapLauncher::GraphicalStapLauncher()
{
try
{
@@ -428,10 +502,10 @@ bool GraphicalStapLauncher::runDialog()
void GraphicalStapLauncher::onLaunch()
{
- _launcher->setArgs(_stapArgEntry->get_text(), _chooserButton->get_filename(),
- _scriptArgEntry->get_text());
+ setArgs(_stapArgEntry->get_text(), _chooserButton->get_filename(),
+ _scriptArgEntry->get_text());
_scriptWindow->hide();
- _launcher->launch();
+ launch();
}
void GraphicalStapLauncher::onLaunchCancel()