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