#include <sstream>
#include <string>
#include <map>
+#include <memory>
#include <vector>
#include <signal.h>
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
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);
}
{
_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));
+ _stapParsers.push_back(result);
+ return result;
+ }
protected:
char** _argv;
string _stapArgs;
string _scriptArgs;
int _childPid;
ChildDeathReader::Callback* _deathCallback;
- StapParser* _stapParser;
+ Gtk::Window* _win;
+ GraphWidget* _widget;
+ vector<tr1::shared_ptr<StapParser> > _stapParsers;
};
int StapLauncher::launch()
}
_exit(1);
}
- _stapParser->setErrFd(pipefd[2]);
- _stapParser->setInFd(pipefd[0]);
- Glib::signal_io().connect(sigc::mem_fun(*_stapParser,
+ tr1::shared_ptr<StapParser> sp(new StapParser(_win, _widget));
+ _stapParsers.push_back(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);
&ChildDeathReader::ioCallback),
signalPipe[0], Glib::IO_IN);
}
- Glib::signal_io().connect(sigc::mem_fun(*_stapParser,
+ Glib::signal_io().connect(sigc::mem_fun(sp.get(),
&StapParser::ioCallback),
pipefd[0],
Glib::IO_IN | Glib::IO_HUP);
}
}
-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;
+ 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();
+}
+
+
+
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;
}
-GraphicalStapLauncher::GraphicalStapLauncher(StapLauncher* launcher)
- : _launcher(launcher)
+GraphicalStapLauncher::GraphicalStapLauncher()
{
try
{
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()