added interrupts plugin
[lttv.git] / ltt / branches / poly / lttv / modules / gui / tracecontrol / tracecontrol.c
CommitLineData
e7c8534e 1/* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2005 Mathieu Desnoyers
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
16 * MA 02111-1307, USA.
17 */
18
19#ifdef HAVE_CONFIG_H
20#include <config.h>
21#endif
22
23#include <glib.h>
24#include <string.h>
25#include <gtk/gtk.h>
26#include <gdk/gdk.h>
27#include <gdk/gdkkeysyms.h>
28
29#include <lttv/lttv.h>
30#include <lttv/module.h>
31#include <lttv/hook.h>
e7c8534e 32
33#include <lttvwindow/lttvwindow.h>
34#include <lttvwindow/lttvwindowtraces.h>
35
36#include "hTraceControlInsert.xpm"
381229ee 37#include "TraceControlStart.xpm"
38#include "TraceControlPause.xpm"
39#include "TraceControlStop.xpm"
e7c8534e 40
77ef407f 41#include <sys/types.h>
42#include <unistd.h>
43#include <stdlib.h>
ff430216 44#include <pty.h>
45#include <utmp.h>
46#include <sys/wait.h>
86a65fdb 47#include <sys/poll.h>
6cec4cd2 48#include <errno.h>
77ef407f 49
f6f6abf0 50#define MAX_ARGS_LEN PATH_MAX * 10
e7c8534e 51
52GSList *g_control_list = NULL ;
53
54/*! \file lttv/modules/gui/tracecontrol/tracecontrol.c
55 * \brief Graphic trace start/stop control interface.
56 *
57 * This plugin interacts with lttctl to start/stop tracing. It needs to take the
58 * root password to be able to interact with lttctl.
59 *
60 */
61
62typedef struct _ControlData ControlData;
63
64/*
65 * Prototypes
66 */
67GtkWidget *guicontrol_get_widget(ControlData *tcd);
68ControlData *gui_control(Tab *tab);
69void gui_control_destructor(ControlData *tcd);
70GtkWidget* h_guicontrol(Tab *tab);
71void control_destroy_walk(gpointer data, gpointer user_data);
72
73/*
74 * Callback functions
75 */
76
77ef407f 77static void start_clicked (GtkButton *button, gpointer user_data);
78static void pause_clicked (GtkButton *button, gpointer user_data);
45653836 79static void unpause_clicked (GtkButton *button, gpointer user_data);
77ef407f 80static void stop_clicked (GtkButton *button, gpointer user_data);
e7c8534e 81
ff430216 82
e7c8534e 83/**
84 * @struct _ControlData
85 *
77ef407f 86 * @brief Main structure of gui control
e7c8534e 87 */
88struct _ControlData {
89 Tab *tab; /**< current tab of module */
90
77ef407f 91 GtkWidget *window; /**< window */
e7c8534e 92
77ef407f 93 GtkWidget *main_box; /**< main container */
94 GtkWidget *start_button;
95 GtkWidget *pause_button;
45653836 96 GtkWidget *unpause_button;
77ef407f 97 GtkWidget *stop_button;
98 GtkWidget *username_label;
99 GtkWidget *username_entry;
100 GtkWidget *password_label;
101 GtkWidget *password_entry;
102 GtkWidget *channel_dir_label;
103 GtkWidget *channel_dir_entry;
104 GtkWidget *trace_dir_label;
105 GtkWidget *trace_dir_entry;
106 GtkWidget *trace_name_label;
107 GtkWidget *trace_name_entry;
108 GtkWidget *trace_mode_label;
109 GtkWidget *trace_mode_combo;
110 GtkWidget *start_daemon_label;
111 GtkWidget *start_daemon_check;
45653836 112 GtkWidget *append_label;
113 GtkWidget *append_check;
77ef407f 114 GtkWidget *optional_label;
115 GtkWidget *subbuf_size_label;
116 GtkWidget *subbuf_size_entry;
117 GtkWidget *subbuf_num_label;
118 GtkWidget *subbuf_num_entry;
119 GtkWidget *lttctl_path_label;
120 GtkWidget *lttctl_path_entry;
121 GtkWidget *lttd_path_label;
122 GtkWidget *lttd_path_entry;
123 GtkWidget *fac_path_label;
124 GtkWidget *fac_path_entry;
e7c8534e 125};
126
127/**
128 * @fn GtkWidget* guicontrol_get_widget(ControlData*)
129 *
130 * This function returns the current main widget
131 * used by this module
132 * @param tcd the module struct
133 * @return The main widget
134 */
135GtkWidget*
136guicontrol_get_widget(ControlData *tcd)
137{
77ef407f 138 return tcd->window;
e7c8534e 139}
140
141/**
142 * @fn ControlData* gui_control(Tab*)
143 *
144 * Constructor is used to create ControlData data structure.
145 * @param tab The tab structure used by the widget
146 * @return The Filter viewer data created.
147 */
148ControlData*
149gui_control(Tab *tab)
150{
151 g_debug("filter::gui_control()");
152
153 unsigned i;
154 GtkCellRenderer *renderer;
155 GtkTreeViewColumn *column;
156
157 ControlData* tcd = g_new(ControlData,1);
158
159 tcd->tab = tab;
160
77ef407f 161 tcd->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
162 gtk_window_set_title(GTK_WINDOW(tcd->window), "LTTng Trace Control");
e7c8534e 163 /*
164 * Initiating GtkTable layout
165 * starts with 2 rows and 5 columns and
166 * expands when expressions added
167 */
77ef407f 168 tcd->main_box = gtk_table_new(14,7,FALSE);
169 gtk_table_set_row_spacings(GTK_TABLE(tcd->main_box),5);
170 gtk_table_set_col_spacings(GTK_TABLE(tcd->main_box),5);
e7c8534e 171
77ef407f 172 gtk_container_add(GTK_CONTAINER(tcd->window), GTK_WIDGET(tcd->main_box));
e7c8534e 173
ff430216 174 GList *focus_chain = NULL;
175
381229ee 176 /*
177 * start/pause/stop buttons
178 */
179 GdkPixbuf *pixbuf;
180 GtkWidget *image;
181 pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)TraceControlStart_xpm);
182 image = gtk_image_new_from_pixbuf(pixbuf);
77ef407f 183 tcd->start_button = gtk_button_new_with_label("start");
06e9af2d 184 //2.6 gtk_button_set_image(GTK_BUTTON(tcd->start_button), image);
185 g_object_set(G_OBJECT(tcd->start_button), "image", image, NULL);
77ef407f 186 gtk_button_set_alignment(GTK_BUTTON(tcd->start_button), 0.0, 0.0);
187 gtk_widget_show (tcd->start_button);
188 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->start_button,6,7,0,1,GTK_FILL,GTK_FILL,2,2);
381229ee 189
190 pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)TraceControlPause_xpm);
191 image = gtk_image_new_from_pixbuf(pixbuf);
77ef407f 192 tcd->pause_button = gtk_button_new_with_label("pause");
06e9af2d 193 //2.6 gtk_button_set_image(GTK_BUTTON(tcd->pause_button), image);
194 g_object_set(G_OBJECT(tcd->pause_button), "image", image, NULL);
77ef407f 195 gtk_button_set_alignment(GTK_BUTTON(tcd->pause_button), 0.0, 0.0);
196 gtk_widget_show (tcd->pause_button);
197 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->pause_button,6,7,1,2,GTK_FILL,GTK_FILL,2,2);
381229ee 198
45653836 199 pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)TraceControlPause_xpm);
200 image = gtk_image_new_from_pixbuf(pixbuf);
201 tcd->unpause_button = gtk_button_new_with_label("unpause");
06e9af2d 202 //2.6 gtk_button_set_image(GTK_BUTTON(tcd->unpause_button), image);
203 g_object_set(G_OBJECT(tcd->unpause_button), "image", image, NULL);
45653836 204 gtk_button_set_alignment(GTK_BUTTON(tcd->unpause_button), 0.0, 0.0);
205 gtk_widget_show (tcd->unpause_button);
206 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->unpause_button,6,7,2,3,GTK_FILL,GTK_FILL,2,2);
207
381229ee 208 pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)TraceControlStop_xpm);
209 image = gtk_image_new_from_pixbuf(pixbuf);
77ef407f 210 tcd->stop_button = gtk_button_new_with_label("stop");
06e9af2d 211 //2.6 gtk_button_set_image(GTK_BUTTON(tcd->stop_button), image);
212 g_object_set(G_OBJECT(tcd->stop_button), "image", image, NULL);
77ef407f 213 gtk_button_set_alignment(GTK_BUTTON(tcd->stop_button), 0.0, 0.0);
214 gtk_widget_show (tcd->stop_button);
45653836 215 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->stop_button,6,7,3,4,GTK_FILL,GTK_FILL,2,2);
381229ee 216
e7c8534e 217 /*
218 * First half of the filter window
219 * - textual entry of filter expression
220 * - processing button
221 */
77ef407f 222 tcd->username_label = gtk_label_new("Username:");
223 gtk_widget_show (tcd->username_label);
224 tcd->username_entry = gtk_entry_new();
225 gtk_entry_set_text(GTK_ENTRY(tcd->username_entry),"root");
226 gtk_widget_show (tcd->username_entry);
227 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->username_label,0,2,0,1,GTK_FILL,GTK_FILL,2,2);
228 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->username_entry,2,6,0,1,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
229
230
231
232 tcd->password_label = gtk_label_new("Password:");
233 gtk_widget_show (tcd->password_label);
234 tcd->password_entry = gtk_entry_new();
235 gtk_entry_set_visibility(GTK_ENTRY(tcd->password_entry), FALSE);
236 gtk_widget_show (tcd->password_entry);
237 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->password_label,0,2,1,2,GTK_FILL,GTK_FILL,2,2);
238 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->password_entry,2,6,1,2,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
239
240
241 tcd->channel_dir_label = gtk_label_new("Channel directory:");
242 gtk_widget_show (tcd->channel_dir_label);
243 tcd->channel_dir_entry = gtk_entry_new();
244 gtk_entry_set_text(GTK_ENTRY(tcd->channel_dir_entry),"/mnt/relayfs/ltt");
245 gtk_widget_show (tcd->channel_dir_entry);
246 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->channel_dir_label,0,2,2,3,GTK_FILL,GTK_FILL,2,2);
247 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->channel_dir_entry,2,6,2,3,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
248
249 tcd->trace_dir_label = gtk_label_new("Trace directory:");
250 gtk_widget_show (tcd->trace_dir_label);
251 tcd->trace_dir_entry = gtk_entry_new();
252 gtk_entry_set_text(GTK_ENTRY(tcd->trace_dir_entry),"/tmp/trace1");
253 gtk_widget_show (tcd->trace_dir_entry);
254 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->trace_dir_label,0,2,3,4,GTK_FILL,GTK_FILL,2,2);
255 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->trace_dir_entry,2,6,3,4,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
256
257 tcd->trace_name_label = gtk_label_new("Trace name:");
258 gtk_widget_show (tcd->trace_name_label);
259 tcd->trace_name_entry = gtk_entry_new();
260 gtk_entry_set_text(GTK_ENTRY(tcd->trace_name_entry),"trace");
261 gtk_widget_show (tcd->trace_name_entry);
262 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->trace_name_label,0,2,4,5,GTK_FILL,GTK_FILL,2,2);
263 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->trace_name_entry,2,6,4,5,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
264
265 tcd->trace_mode_label = gtk_label_new("Trace mode ");
266 gtk_widget_show (tcd->trace_mode_label);
267 tcd->trace_mode_combo = gtk_combo_box_new_text();
268 gtk_combo_box_append_text(GTK_COMBO_BOX(tcd->trace_mode_combo),
381229ee 269 "normal");
77ef407f 270 gtk_combo_box_append_text(GTK_COMBO_BOX(tcd->trace_mode_combo),
381229ee 271 "flight recorder");
77ef407f 272 gtk_combo_box_set_active(GTK_COMBO_BOX(tcd->trace_mode_combo), 0);
273 gtk_widget_show (tcd->trace_mode_combo);
274 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->trace_mode_label,0,2,5,6,GTK_FILL,GTK_FILL,2,2);
275 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->trace_mode_combo,2,6,5,6,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
276
277 tcd->start_daemon_label = gtk_label_new("Start daemon ");
278 gtk_widget_show (tcd->start_daemon_label);
279 tcd->start_daemon_check = gtk_check_button_new();
280 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tcd->start_daemon_check), TRUE);
281 gtk_widget_show (tcd->start_daemon_check);
282 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->start_daemon_label,0,2,6,7,GTK_FILL,GTK_FILL,2,2);
283 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->start_daemon_check,2,6,6,7,GTK_FILL,GTK_FILL,0,0);
45653836 284
285 tcd->append_label = gtk_label_new("Append to trace ");
286 gtk_widget_show (tcd->append_label);
287 tcd->append_check = gtk_check_button_new();
288 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tcd->append_check), FALSE);
289 gtk_widget_show (tcd->append_check);
290 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->append_label,0,2,7,8,GTK_FILL,GTK_FILL,2,2);
291 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->append_check,2,6,7,8,GTK_FILL,GTK_FILL,0,0);
292
77ef407f 293
294 tcd->optional_label = gtk_label_new("Optional fields ");
295 gtk_widget_show (tcd->optional_label);
45653836 296 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->optional_label,0,6,8,9,GTK_FILL,GTK_FILL,2,2);
77ef407f 297
298 tcd->subbuf_size_label = gtk_label_new("Subbuffer size:");
299 gtk_widget_show (tcd->subbuf_size_label);
300 tcd->subbuf_size_entry = gtk_entry_new();
301 gtk_widget_show (tcd->subbuf_size_entry);
45653836 302 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->subbuf_size_label,0,2,9,10,GTK_FILL,GTK_FILL,2,2);
303 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->subbuf_size_entry,2,6,9,10,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
77ef407f 304
305 tcd->subbuf_num_label = gtk_label_new("Number of subbuffers:");
306 gtk_widget_show (tcd->subbuf_num_label);
307 tcd->subbuf_num_entry = gtk_entry_new();
308 gtk_widget_show (tcd->subbuf_num_entry);
45653836 309 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->subbuf_num_label,0,2,10,11,GTK_FILL,GTK_FILL,2,2);
310 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->subbuf_num_entry,2,6,10,11,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
77ef407f 311
312 tcd->lttctl_path_label = gtk_label_new("path to lttctl:");
313 gtk_widget_show (tcd->lttctl_path_label);
314 tcd->lttctl_path_entry = gtk_entry_new();
ff430216 315 gtk_entry_set_text(GTK_ENTRY(tcd->lttctl_path_entry),PACKAGE_BIN_DIR "/lttctl");
77ef407f 316 gtk_widget_show (tcd->lttctl_path_entry);
45653836 317 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->lttctl_path_label,0,2,11,12,GTK_FILL,GTK_FILL,2,2);
318 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->lttctl_path_entry,2,6,11,12,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
77ef407f 319
320
321 tcd->lttd_path_label = gtk_label_new("path to lttd:");
322 gtk_widget_show (tcd->lttd_path_label);
323 tcd->lttd_path_entry = gtk_entry_new();
ff430216 324 gtk_entry_set_text(GTK_ENTRY(tcd->lttd_path_entry),PACKAGE_BIN_DIR "/lttd");
77ef407f 325 gtk_widget_show (tcd->lttd_path_entry);
45653836 326 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->lttd_path_label,0,2,12,13,GTK_FILL,GTK_FILL,2,2);
327 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->lttd_path_entry,2,6,12,13,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
381229ee 328
329
77ef407f 330 tcd->fac_path_label = gtk_label_new("path to facilities:");
331 gtk_widget_show (tcd->fac_path_label);
332 tcd->fac_path_entry = gtk_entry_new();
86a65fdb 333 gtk_entry_set_text(GTK_ENTRY(tcd->fac_path_entry),PACKAGE_DATA_DIR "/" PACKAGE "/facilities");
77ef407f 334 gtk_widget_set_size_request(tcd->fac_path_entry, 250, -1);
335 gtk_widget_show (tcd->fac_path_entry);
45653836 336 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->fac_path_label,0,2,13,14,GTK_FILL,GTK_FILL,2,2);
337 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->fac_path_entry,2,6,13,14,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
ff430216 338
339 focus_chain = g_list_append (focus_chain, tcd->username_entry);
340 focus_chain = g_list_append (focus_chain, tcd->password_entry);
341 focus_chain = g_list_append (focus_chain, tcd->start_button);
342 focus_chain = g_list_append (focus_chain, tcd->pause_button);
45653836 343 focus_chain = g_list_append (focus_chain, tcd->unpause_button);
ff430216 344 focus_chain = g_list_append (focus_chain, tcd->stop_button);
345 focus_chain = g_list_append (focus_chain, tcd->channel_dir_entry);
346 focus_chain = g_list_append (focus_chain, tcd->trace_dir_entry);
347 focus_chain = g_list_append (focus_chain, tcd->trace_name_entry);
348 focus_chain = g_list_append (focus_chain, tcd->trace_mode_combo);
349 focus_chain = g_list_append (focus_chain, tcd->start_daemon_check);
45653836 350 focus_chain = g_list_append (focus_chain, tcd->append_check);
ff430216 351 focus_chain = g_list_append (focus_chain, tcd->subbuf_size_entry);
352 focus_chain = g_list_append (focus_chain, tcd->subbuf_num_entry);
353 focus_chain = g_list_append (focus_chain, tcd->lttctl_path_entry);
354 focus_chain = g_list_append (focus_chain, tcd->lttd_path_entry);
355 focus_chain = g_list_append (focus_chain, tcd->fac_path_entry);
356
357 gtk_container_set_focus_chain(GTK_CONTAINER(tcd->main_box), focus_chain);
358
382e4b92 359 g_list_free(focus_chain);
360
77ef407f 361 g_signal_connect(G_OBJECT(tcd->start_button), "clicked",
362 (GCallback)start_clicked, tcd);
363 g_signal_connect(G_OBJECT(tcd->pause_button), "clicked",
364 (GCallback)pause_clicked, tcd);
45653836 365 g_signal_connect(G_OBJECT(tcd->unpause_button), "clicked",
366 (GCallback)unpause_clicked, tcd);
77ef407f 367 g_signal_connect(G_OBJECT(tcd->stop_button), "clicked",
368 (GCallback)stop_clicked, tcd);
e7c8534e 369
370 /*
371 * show main container
372 */
77ef407f 373 gtk_widget_show(tcd->main_box);
374 gtk_widget_show(tcd->window);
e7c8534e 375
376
377 g_object_set_data_full(
77ef407f 378 G_OBJECT(guicontrol_get_widget(tcd)),
379 "control_viewer_data",
e7c8534e 380 tcd,
381 (GDestroyNotify)gui_control_destructor);
382
383 g_control_list = g_slist_append(
384 g_control_list,
385 tcd);
386
387 return tcd;
388}
389
390
391/**
392 * @fn void gui_control_destructor(ControlData*)
393 *
394 * Destructor for the filter gui module
395 * @param tcd The module structure
396 */
397void
398gui_control_destructor(ControlData *tcd)
399{
400 Tab *tab = tcd->tab;
401
402 /* May already been done by GTK window closing */
77ef407f 403 if(GTK_IS_WIDGET(guicontrol_get_widget(tcd))){
e7c8534e 404 g_info("widget still exists");
405 }
406// if(tab != NULL) {
407// lttvwindow_unregister_traceset_notify(tcd->tab,
408// filter_traceset_changed,
409// filter_viewer_data);
410// }
411 lttvwindowtraces_background_notify_remove(tcd);
412
413 g_control_list = g_slist_remove(g_control_list, tcd);
414
415 g_free(tcd);
416}
417
29e34d6c 418static int execute_command(const gchar *command, const gchar *username,
45653836 419 const gchar *password, const gchar *lttd_path, const gchar *fac_path)
77ef407f 420{
ff430216 421 pid_t pid;
422 int fdpty;
423 pid = forkpty(&fdpty, NULL, NULL, NULL);
29e34d6c 424 int retval = 0;
77ef407f 425
426 if(pid > 0) {
427 /* parent */
ff430216 428 gchar buf[256];
429 int status;
430 ssize_t count;
431 /* discuss with su */
432 struct timeval timeout;
433 timeout.tv_sec = 1;
434 timeout.tv_usec = 0;
ff430216 435
86a65fdb 436 struct pollfd pollfd;
437 int num_rdy;
438 int num_hup = 0;
439
440
441 /* Read the output from the child terminal before the prompt. If no data in
442 * 200 ms, we stop reading to give the password */
443 g_info("Reading from child console...");
1f1a8b9c 444 sleep(1); /* make sure the child is ready */
86a65fdb 445 while(1) {
446 pollfd.fd = fdpty;
75e2f396 447 pollfd.events = POLLIN|POLLPRI|POLLERR|POLLHUP|POLLNVAL;
86a65fdb 448
449 num_rdy = poll(&pollfd, 1, 200);
450#if 0
451 if(num_rdy == -1) {
452 perror("Poll error");
453 goto wait_child;
454 }
455#endif //0
456
457 /* Timeout : stop waiting for chars */
458 if(num_rdy == 0) break;
459
460 switch(pollfd.revents) {
461 case POLLERR:
462 g_warning("Error returned in polling fd\n");
463 num_hup++;
464 break;
465 case POLLHUP:
466 g_info("Polling FD : hung up.");
467 num_hup++;
468 break;
469 case POLLNVAL:
470 g_warning("Polling fd tells it is not open");
471 num_hup++;
472 break;
473 case POLLPRI:
474 case POLLIN:
475 count = read (fdpty, buf, 256);
476 if(count > 0) {
477 buf[count] = '\0';
478 printf("%s", buf);
479 } else if(count == -1) {
480 perror("Error in read");
481 goto wait_child;
482 }
483 break;
484 }
485 if(num_hup > 0) {
486 g_warning("Child hung up too fast");
487 goto wait_child;
488 }
489 }
490
491 /* Write the password */
ff430216 492 g_info("Got su prompt, now writing password...");
ff430216 493 int ret;
494 ret = write(fdpty, password, strlen(password));
495 if(ret < 0) perror("Error in write");
496 ret = write(fdpty, "\n", 1);
497 if(ret < 0) perror("Error in write");
498 fsync(fdpty);
499
86a65fdb 500 /* Take the output from the terminal and show it on the real console */
501 g_info("Getting data from child terminal...");
502 while(1) {
503 int num_hup = 0;
504 pollfd.fd = fdpty;
75e2f396 505 pollfd.events = POLLIN|POLLPRI|POLLERR|POLLHUP|POLLNVAL;
86a65fdb 506
507 num_rdy = poll(&pollfd, 1, -1);
508#if 0
509 if(num_rdy == -1) {
510 perror("Poll error");
511 goto wait_child;
512 }
513#endif //0
514 if(num_rdy == 0) break;
515
516 switch(pollfd.revents) {
517 case POLLERR:
518 g_warning("Error returned in polling fd\n");
519 num_hup++;
520 break;
521 case POLLHUP:
522 g_info("Polling FD : hung up.");
523 num_hup++;
524 break;
525 case POLLNVAL:
526 g_warning("Polling fd tells it is not open");
527 num_hup++;
528 break;
529 case POLLPRI:
530 case POLLIN:
531 count = read (fdpty, buf, 256);
532 if(count > 0) {
533 buf[count] = '\0';
534 printf("%s", buf);
535 } else if(count == -1) {
536 perror("Error in read");
537 goto wait_child;
538 }
539 break;
ff430216 540 }
86a65fdb 541 if(num_hup > 0) goto wait_child;
542 }
543wait_child:
544 g_info("Waiting for child exit...");
545
546 ret = waitpid(pid, &status, 0);
6cec4cd2 547
548 if(ret == -1) {
549 g_warning("An error occured in wait : %s",
550 strerror(errno));
551 } else {
552 if(WIFEXITED(status))
553 if(WEXITSTATUS(status) != 0) {
554 retval = WEXITSTATUS(status);
555 g_warning("An error occured in the su command : %s",
556 strerror(retval));
557 }
558 }
77ef407f 559
86a65fdb 560 g_info("Child exited.");
77ef407f 561
562 } else if(pid == 0) {
f6f6abf0 563 /* Setup environment variables */
77ef407f 564 if(strcmp(lttd_path, "") != 0)
565 setenv("LTT_DAEMON", lttd_path, 1);
566 if(strcmp(fac_path, "") != 0)
567 setenv("LTT_FACILITIES", fac_path, 1);
f6f6abf0 568
45653836 569 g_message("Executing (as %s) : %s\n", username, command);
ff430216 570
45653836 571 execlp("su", "su", "-p", "-c", command, username, NULL);
572 exit(-1); /* not supposed to happen! */
573
574 //gint ret = execvp();
575
576 } else {
577 /* error */
578 g_warning("Error happened when forking for su");
579 }
86a65fdb 580
29e34d6c 581 return retval;
45653836 582}
86a65fdb 583
86a65fdb 584
45653836 585/* Callbacks */
f6f6abf0 586
45653836 587void start_clicked (GtkButton *button, gpointer user_data)
588{
589 ControlData *tcd = (ControlData*)user_data;
f6f6abf0 590
45653836 591 const gchar *username = gtk_entry_get_text(GTK_ENTRY(tcd->username_entry));
592 const gchar *password = gtk_entry_get_text(GTK_ENTRY(tcd->password_entry));
593 const gchar *channel_dir =
594 gtk_entry_get_text(GTK_ENTRY(tcd->channel_dir_entry));
595 const gchar *trace_dir = gtk_entry_get_text(GTK_ENTRY(tcd->trace_dir_entry));
596 const gchar *trace_name =
597 gtk_entry_get_text(GTK_ENTRY(tcd->trace_name_entry));
598
382e4b92 599 const gchar *trace_mode_sel;
600 GtkTreeIter iter;
601
602 gtk_combo_box_get_active_iter(GTK_COMBO_BOX(tcd->trace_mode_combo), &iter);
603 gtk_tree_model_get(
604 gtk_combo_box_get_model(GTK_COMBO_BOX(tcd->trace_mode_combo)),
605 &iter, 0, &trace_mode_sel, -1);
606 //const gchar *trace_mode_sel =
607 //2.6+ gtk_combo_box_get_active_text(GTK_COMBO_BOX(tcd->trace_mode_combo));
45653836 608 const gchar *trace_mode;
609 if(strcmp(trace_mode_sel, "normal") == 0)
610 trace_mode = "normal";
611 else
612 trace_mode = "flight";
613
614 gboolean start_daemon =
615 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tcd->start_daemon_check));
f6f6abf0 616
45653836 617 gboolean append =
618 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tcd->append_check));
619
620 const gchar *subbuf_size =
621 gtk_entry_get_text(GTK_ENTRY(tcd->subbuf_size_entry));
622 const gchar *subbuf_num =
623 gtk_entry_get_text(GTK_ENTRY(tcd->subbuf_num_entry));
624 const gchar *lttctl_path =
625 gtk_entry_get_text(GTK_ENTRY(tcd->lttctl_path_entry));
626 const gchar *lttd_path = gtk_entry_get_text(GTK_ENTRY(tcd->lttd_path_entry));
627 const gchar *fac_path = gtk_entry_get_text(GTK_ENTRY(tcd->fac_path_entry));
628
629
630 /* Setup arguments to su */
631 /* child */
632 gchar args[MAX_ARGS_LEN];
633 gint args_left = MAX_ARGS_LEN - 1; /* for \0 */
634
635 args[0] = '\0';
636
637 /* Command */
638 strncat(args, "exec", args_left);
639 args_left = MAX_ARGS_LEN - strlen(args) - 1;
640
641 /* space */
642 strncat(args, " ", args_left);
643 args_left = MAX_ARGS_LEN - strlen(args) - 1;
644
645 if(strcmp(lttctl_path, "") == 0)
646 strncat(args, "lttctl", args_left);
647 else
648 strncat(args, lttctl_path, args_left);
649 args_left = MAX_ARGS_LEN - strlen(args) - 1;
650
651 /* space */
652 strncat(args, " ", args_left);
653 args_left = MAX_ARGS_LEN - strlen(args) - 1;
654
655 /* channel dir */
656 strncat(args, "-l ", args_left);
657 args_left = MAX_ARGS_LEN - strlen(args) - 1;
658 strncat(args, channel_dir, args_left);
659 args_left = MAX_ARGS_LEN - strlen(args) - 1;
660
661 /* space */
662 strncat(args, " ", args_left);
663 args_left = MAX_ARGS_LEN - strlen(args) - 1;
664
665 /* trace dir */
666 strncat(args, "-t ", args_left);
667 args_left = MAX_ARGS_LEN - strlen(args) - 1;
668 strncat(args, trace_dir, args_left);
669 args_left = MAX_ARGS_LEN - strlen(args) - 1;
670
671 /* space */
672 strncat(args, " ", args_left);
673 args_left = MAX_ARGS_LEN - strlen(args) - 1;
674
675 /* name */
676 strncat(args, "-n ", args_left);
677 args_left = MAX_ARGS_LEN - strlen(args) - 1;
678 strncat(args, trace_name, args_left);
679 args_left = MAX_ARGS_LEN - strlen(args) - 1;
680
681 /* space */
682 strncat(args, " ", args_left);
683 args_left = MAX_ARGS_LEN - strlen(args) - 1;
684
685 /* trace mode */
686 strncat(args, "-m ", args_left);
687 args_left = MAX_ARGS_LEN - strlen(args) - 1;
688 strncat(args, trace_mode, args_left);
689 args_left = MAX_ARGS_LEN - strlen(args) - 1;
690
691 /* space */
692 strncat(args, " ", args_left);
693 args_left = MAX_ARGS_LEN - strlen(args) - 1;
694
695 /* Start daemon ? */
696 if(start_daemon) {
697 strncat(args, "-d", args_left);
f6f6abf0 698 args_left = MAX_ARGS_LEN - strlen(args) - 1;
45653836 699 } else {
700 /* Simply create the channel and then start tracing */
701 strncat(args, "-b", args_left);
f6f6abf0 702 args_left = MAX_ARGS_LEN - strlen(args) - 1;
45653836 703 }
704
f6f6abf0 705
45653836 706 /* Append to trace ? */
707 if(append) {
f6f6abf0 708 /* space */
709 strncat(args, " ", args_left);
710 args_left = MAX_ARGS_LEN - strlen(args) - 1;
45653836 711 strncat(args, "-a", args_left);
f6f6abf0 712 args_left = MAX_ARGS_LEN - strlen(args) - 1;
45653836 713 }
714
715 /* optional arguments */
716 /* subbuffer size */
717 if(strcmp(subbuf_size, "") != 0) {
f6f6abf0 718 /* space */
719 strncat(args, " ", args_left);
720 args_left = MAX_ARGS_LEN - strlen(args) - 1;
721
45653836 722 strncat(args, "-z ", args_left);
f6f6abf0 723 args_left = MAX_ARGS_LEN - strlen(args) - 1;
45653836 724 strncat(args, subbuf_size, args_left);
f6f6abf0 725 args_left = MAX_ARGS_LEN - strlen(args) - 1;
45653836 726 }
f6f6abf0 727
45653836 728 /* number of subbuffers */
729 if(strcmp(subbuf_num, "") != 0) {
f6f6abf0 730 /* space */
731 strncat(args, " ", args_left);
732 args_left = MAX_ARGS_LEN - strlen(args) - 1;
733
45653836 734 strncat(args, "-x ", args_left);
735 args_left = MAX_ARGS_LEN - strlen(args) - 1;
736 strncat(args, subbuf_num, args_left);
737 args_left = MAX_ARGS_LEN - strlen(args) - 1;
738 }
ff430216 739
77ef407f 740
29e34d6c 741 int retval = execute_command(args, username, password, lttd_path, fac_path);
742
743 if(retval) {
744 gchar msg[256];
745 guint msg_left = 256;
746
747 strcpy(msg, "A problem occured when executing the su command : ");
748 msg_left = 256 - strlen(msg) - 1;
749 strncat(msg, strerror(retval), msg_left);
750 GtkWidget *dialogue =
751 gtk_message_dialog_new(
752 GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(button))),
753 GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
754 GTK_MESSAGE_ERROR,
755 GTK_BUTTONS_OK,
756 msg);
757 gtk_dialog_run(GTK_DIALOG(dialogue));
758 gtk_widget_destroy(dialogue);
759 }
77ef407f 760
761}
762
763
764void pause_clicked (GtkButton *button, gpointer user_data)
765{
766 ControlData *tcd = (ControlData*)user_data;
767
45653836 768 const gchar *username = gtk_entry_get_text(GTK_ENTRY(tcd->username_entry));
769 const gchar *password = gtk_entry_get_text(GTK_ENTRY(tcd->password_entry));
770 const gchar *trace_name =
771 gtk_entry_get_text(GTK_ENTRY(tcd->trace_name_entry));
772 const gchar *lttd_path = "";
773 const gchar *fac_path = "";
774
775 const gchar *lttctl_path =
776 gtk_entry_get_text(GTK_ENTRY(tcd->lttctl_path_entry));
77ef407f 777
45653836 778 /* Setup arguments to su */
779 /* child */
780 gchar args[MAX_ARGS_LEN];
781 gint args_left = MAX_ARGS_LEN - 1; /* for \0 */
782
783 args[0] = '\0';
784
785 /* Command */
786 strncat(args, "exec", args_left);
787 args_left = MAX_ARGS_LEN - strlen(args) - 1;
788
789 /* space */
790 strncat(args, " ", args_left);
791 args_left = MAX_ARGS_LEN - strlen(args) - 1;
792
793 if(strcmp(lttctl_path, "") == 0)
794 strncat(args, "lttctl", args_left);
795 else
796 strncat(args, lttctl_path, args_left);
797 args_left = MAX_ARGS_LEN - strlen(args) - 1;
798
799 /* space */
800 strncat(args, " ", args_left);
801 args_left = MAX_ARGS_LEN - strlen(args) - 1;
802
803 /* name */
804 strncat(args, "-n ", args_left);
805 args_left = MAX_ARGS_LEN - strlen(args) - 1;
806 strncat(args, trace_name, args_left);
807 args_left = MAX_ARGS_LEN - strlen(args) - 1;
808
809 /* space */
810 strncat(args, " ", args_left);
811 args_left = MAX_ARGS_LEN - strlen(args) - 1;
812
813 /* Simply pause tracing */
814 strncat(args, "-q", args_left);
815 args_left = MAX_ARGS_LEN - strlen(args) - 1;
816
29e34d6c 817 int retval = execute_command(args, username, password, lttd_path, fac_path);
818 if(retval) {
819 gchar msg[256];
820 guint msg_left = 256;
821
822 strcpy(msg, "A problem occured when executing the su command : ");
823 msg_left = 256 - strlen(msg) - 1;
824 strncat(msg, strerror(retval), msg_left);
825 GtkWidget *dialogue =
826 gtk_message_dialog_new(
827 GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(button))),
828 GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
829 GTK_MESSAGE_ERROR,
830 GTK_BUTTONS_OK,
831 msg);
832 gtk_dialog_run(GTK_DIALOG(dialogue));
833 gtk_widget_destroy(dialogue);
834 }
835
45653836 836}
837
838void unpause_clicked (GtkButton *button, gpointer user_data)
839{
840 ControlData *tcd = (ControlData*)user_data;
841
842 const gchar *username = gtk_entry_get_text(GTK_ENTRY(tcd->username_entry));
843 const gchar *password = gtk_entry_get_text(GTK_ENTRY(tcd->password_entry));
844 const gchar *trace_name =
845 gtk_entry_get_text(GTK_ENTRY(tcd->trace_name_entry));
846 const gchar *lttd_path = "";
847 const gchar *fac_path = "";
848
849 const gchar *lttctl_path =
850 gtk_entry_get_text(GTK_ENTRY(tcd->lttctl_path_entry));
851
852 /* Setup arguments to su */
853 /* child */
854 gchar args[MAX_ARGS_LEN];
855 gint args_left = MAX_ARGS_LEN - 1; /* for \0 */
856
857 args[0] = '\0';
858
859 /* Command */
860 strncat(args, "exec", args_left);
861 args_left = MAX_ARGS_LEN - strlen(args) - 1;
862
863 /* space */
864 strncat(args, " ", args_left);
865 args_left = MAX_ARGS_LEN - strlen(args) - 1;
866
867 if(strcmp(lttctl_path, "") == 0)
868 strncat(args, "lttctl", args_left);
869 else
870 strncat(args, lttctl_path, args_left);
871 args_left = MAX_ARGS_LEN - strlen(args) - 1;
872
873 /* space */
874 strncat(args, " ", args_left);
875 args_left = MAX_ARGS_LEN - strlen(args) - 1;
876
877 /* name */
878 strncat(args, "-n ", args_left);
879 args_left = MAX_ARGS_LEN - strlen(args) - 1;
880 strncat(args, trace_name, args_left);
881 args_left = MAX_ARGS_LEN - strlen(args) - 1;
882
883 /* space */
884 strncat(args, " ", args_left);
885 args_left = MAX_ARGS_LEN - strlen(args) - 1;
886
887 /* Simply unpause tracing */
888 strncat(args, "-s", args_left);
889 args_left = MAX_ARGS_LEN - strlen(args) - 1;
890
29e34d6c 891 int retval = execute_command(args, username, password, lttd_path, fac_path);
892 if(retval) {
893 gchar msg[256];
894 guint msg_left = 256;
895
896 strcpy(msg, "A problem occured when executing the su command : ");
897 msg_left = 256 - strlen(msg) - 1;
898 strncat(msg, strerror(retval), msg_left);
899 GtkWidget *dialogue =
900 gtk_message_dialog_new(
901 GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(button))),
902 GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
903 GTK_MESSAGE_ERROR,
904 GTK_BUTTONS_OK,
905 msg);
906 gtk_dialog_run(GTK_DIALOG(dialogue));
907 gtk_widget_destroy(dialogue);
908 }
909
77ef407f 910}
911
912void stop_clicked (GtkButton *button, gpointer user_data)
913{
914 ControlData *tcd = (ControlData*)user_data;
915
45653836 916 const gchar *username = gtk_entry_get_text(GTK_ENTRY(tcd->username_entry));
917 const gchar *password = gtk_entry_get_text(GTK_ENTRY(tcd->password_entry));
918 const gchar *trace_name =
919 gtk_entry_get_text(GTK_ENTRY(tcd->trace_name_entry));
920 const gchar *lttd_path = "";
921 const gchar *fac_path = "";
922
923 const gchar *lttctl_path =
924 gtk_entry_get_text(GTK_ENTRY(tcd->lttctl_path_entry));
8321ae6a 925 const gchar *trace_dir = gtk_entry_get_text(GTK_ENTRY(tcd->trace_dir_entry));
45653836 926
927 /* Setup arguments to su */
928 /* child */
929 gchar args[MAX_ARGS_LEN];
930 gint args_left = MAX_ARGS_LEN - 1; /* for \0 */
931
932 args[0] = '\0';
933
934 /* Command */
935 strncat(args, "exec", args_left);
936 args_left = MAX_ARGS_LEN - strlen(args) - 1;
937
938 /* space */
939 strncat(args, " ", args_left);
940 args_left = MAX_ARGS_LEN - strlen(args) - 1;
941
942 if(strcmp(lttctl_path, "") == 0)
943 strncat(args, "lttctl", args_left);
944 else
945 strncat(args, lttctl_path, args_left);
946 args_left = MAX_ARGS_LEN - strlen(args) - 1;
947
948 /* space */
949 strncat(args, " ", args_left);
950 args_left = MAX_ARGS_LEN - strlen(args) - 1;
951
952 /* name */
953 strncat(args, "-n ", args_left);
954 args_left = MAX_ARGS_LEN - strlen(args) - 1;
955 strncat(args, trace_name, args_left);
956 args_left = MAX_ARGS_LEN - strlen(args) - 1;
957
958 /* space */
959 strncat(args, " ", args_left);
960 args_left = MAX_ARGS_LEN - strlen(args) - 1;
961
962 /* Simply stop tracing and destroy channel */
963 strncat(args, "-R", args_left);
964 args_left = MAX_ARGS_LEN - strlen(args) - 1;
965
29e34d6c 966 int retval = execute_command(args, username, password, lttd_path, fac_path);
967 if(retval) {
968 gchar msg[256];
969 guint msg_left = 256;
970
971 strcpy(msg, "A problem occured when executing the su command : ");
972 msg_left = 256 - strlen(msg) - 1;
973 strncat(msg, strerror(retval), msg_left);
974 GtkWidget *dialogue =
975 gtk_message_dialog_new(
976 GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(button))),
977 GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
978 GTK_MESSAGE_ERROR,
979 GTK_BUTTONS_OK,
980 msg);
981 gtk_dialog_run(GTK_DIALOG(dialogue));
982 gtk_widget_destroy(dialogue);
983 return;
984 }
985
77ef407f 986
8321ae6a 987 /* Ask to the user if he wants to open the trace in a new window */
988 GtkWidget *dialogue;
989 GtkWidget *label;
990 gint id;
991
992 dialogue = gtk_dialog_new_with_buttons("Open trace ?",
993 GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(button))),
994 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
995 GTK_STOCK_YES,GTK_RESPONSE_ACCEPT,
996 GTK_STOCK_NO,GTK_RESPONSE_REJECT,
997 NULL);
998 label = gtk_label_new("Do you want to open the trace in LTTV ?");
999 gtk_widget_show(label);
1000
1001 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialogue)->vbox),
1002 label);
1003
1004 id = gtk_dialog_run(GTK_DIALOG(dialogue));
1005
1006 switch(id){
1007 case GTK_RESPONSE_ACCEPT:
1008 {
1009 create_main_window_with_trace(trace_dir);
1010 }
1011 break;
1012 case GTK_RESPONSE_REJECT:
1013 default:
1014 break;
1015 }
1016 gtk_widget_destroy(dialogue);
1017
77ef407f 1018}
1019
e7c8534e 1020
1021/**
1022 * @fn GtkWidget* h_guicontrol(Tab*)
1023 *
1024 * Control Module's constructor hook
1025 *
1026 * This constructor is given as a parameter to the menuitem and toolbar button
1027 * registration. It creates the list.
1028 * @param tab A pointer to the parent window.
1029 * @return The widget created.
1030 */
1031GtkWidget *
1032h_guicontrol(Tab *tab)
1033{
1034 ControlData* f = gui_control(tab) ;
1035
1036 return NULL;
1037}
1038
1039/**
1040 * @fn static void init()
1041 *
1042 * This function initializes the Filter Viewer functionnality through the
1043 * gtkTraceSet API.
1044 */
1045static void init() {
1046
1047 lttvwindow_register_constructor("guicontrol",
1048 "/",
1049 "Insert Tracing Control Module",
1050 hTraceControlInsert_xpm,
1051 "Insert Tracing Control Module",
1052 h_guicontrol);
1053}
1054
1055/**
1056 * @fn void control_destroy_walk(gpointer,gpointer)
1057 *
1058 * Initiate the destruction of the current gui module
1059 * on the GTK Interface
1060 */
1061void
1062control_destroy_walk(gpointer data, gpointer user_data)
1063{
1064 ControlData *tcd = (ControlData*)data;
1065
1066 g_debug("traceontrol.c : control_destroy_walk, %p", tcd);
1067
1068 /* May already have been done by GTK window closing */
1069 if(GTK_IS_WIDGET(guicontrol_get_widget(tcd)))
1070 gtk_widget_destroy(guicontrol_get_widget(tcd));
1071}
1072
1073/**
1074 * @fn static void destroy()
1075 * @brief plugin's destroy function
1076 *
1077 * This function releases the memory reserved by the module and unregisters
1078 * everything that has been registered in the gtkTraceSet API.
1079 */
1080static void destroy() {
1081
1082 g_slist_foreach(g_control_list, control_destroy_walk, NULL );
1083
1084 lttvwindow_unregister_constructor(h_guicontrol);
1085
1086}
1087
1088
1089LTTV_MODULE("guitracecontrol", "Trace Control Window", \
1090 "Graphical module that let user control kernel tracing", \
1091 init, destroy, "lttvwindow")
1092
This page took 0.075019 seconds and 4 git commands to generate.