1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2005 Mathieu Desnoyers
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;
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.
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,
27 #include <gdk/gdkkeysyms.h>
29 #include <lttv/lttv.h>
30 #include <lttv/module.h>
31 #include <lttv/hook.h>
33 #include <lttvwindow/lttvwindow.h>
34 #include <lttvwindow/lttvwindowtraces.h>
36 #include "hTraceControlInsert.xpm"
37 #include "TraceControlStart.xpm"
38 #include "TraceControlPause.xpm"
39 #include "TraceControlStop.xpm"
41 #include <sys/types.h>
50 #define MAX_ARGS_LEN PATH_MAX * 10
52 GSList
*g_control_list
= NULL
;
54 /*! \file lttv/modules/gui/tracecontrol/tracecontrol.c
55 * \brief Graphic trace start/stop control interface.
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.
62 typedef struct _ControlData ControlData
;
67 GtkWidget
*guicontrol_get_widget(ControlData
*tcd
);
68 ControlData
*gui_control(Tab
*tab
);
69 void gui_control_destructor(ControlData
*tcd
);
70 GtkWidget
* h_guicontrol(Tab
*tab
);
71 void control_destroy_walk(gpointer data
, gpointer user_data
);
77 static void start_clicked (GtkButton
*button
, gpointer user_data
);
78 static void pause_clicked (GtkButton
*button
, gpointer user_data
);
79 static void unpause_clicked (GtkButton
*button
, gpointer user_data
);
80 static void stop_clicked (GtkButton
*button
, gpointer user_data
);
84 * @struct _ControlData
86 * @brief Main structure of gui control
89 Tab
*tab
; /**< current tab of module */
91 GtkWidget
*window
; /**< window */
93 GtkWidget
*main_box
; /**< main container */
94 GtkWidget
*start_button
;
95 GtkWidget
*pause_button
;
96 GtkWidget
*unpause_button
;
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
;
112 GtkWidget
*append_label
;
113 GtkWidget
*append_check
;
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
;
128 * @fn GtkWidget* guicontrol_get_widget(ControlData*)
130 * This function returns the current main widget
131 * used by this module
132 * @param tcd the module struct
133 * @return The main widget
136 guicontrol_get_widget(ControlData
*tcd
)
142 * @fn ControlData* gui_control(Tab*)
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.
149 gui_control(Tab
*tab
)
151 g_debug("filter::gui_control()");
154 GtkCellRenderer
*renderer
;
155 GtkTreeViewColumn
*column
;
157 ControlData
* tcd
= g_new(ControlData
,1);
161 tcd
->window
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
162 gtk_window_set_title(GTK_WINDOW(tcd
->window
), "LTTng Trace Control");
164 * Initiating GtkTable layout
165 * starts with 2 rows and 5 columns and
166 * expands when expressions added
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);
172 gtk_container_add(GTK_CONTAINER(tcd
->window
), GTK_WIDGET(tcd
->main_box
));
174 GList
*focus_chain
= NULL
;
177 * start/pause/stop buttons
181 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char **)TraceControlStart_xpm
);
182 image
= gtk_image_new_from_pixbuf(pixbuf
);
183 tcd
->start_button
= gtk_button_new_with_label("start");
184 gtk_button_set_image(GTK_BUTTON(tcd
->start_button
), image
);
185 gtk_button_set_alignment(GTK_BUTTON(tcd
->start_button
), 0.0, 0.0);
186 gtk_widget_show (tcd
->start_button
);
187 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->start_button
,6,7,0,1,GTK_FILL
,GTK_FILL
,2,2);
189 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char **)TraceControlPause_xpm
);
190 image
= gtk_image_new_from_pixbuf(pixbuf
);
191 tcd
->pause_button
= gtk_button_new_with_label("pause");
192 gtk_button_set_image(GTK_BUTTON(tcd
->pause_button
), image
);
193 gtk_button_set_alignment(GTK_BUTTON(tcd
->pause_button
), 0.0, 0.0);
194 gtk_widget_show (tcd
->pause_button
);
195 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->pause_button
,6,7,1,2,GTK_FILL
,GTK_FILL
,2,2);
197 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char **)TraceControlPause_xpm
);
198 image
= gtk_image_new_from_pixbuf(pixbuf
);
199 tcd
->unpause_button
= gtk_button_new_with_label("unpause");
200 gtk_button_set_image(GTK_BUTTON(tcd
->unpause_button
), image
);
201 gtk_button_set_alignment(GTK_BUTTON(tcd
->unpause_button
), 0.0, 0.0);
202 gtk_widget_show (tcd
->unpause_button
);
203 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->unpause_button
,6,7,2,3,GTK_FILL
,GTK_FILL
,2,2);
205 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char **)TraceControlStop_xpm
);
206 image
= gtk_image_new_from_pixbuf(pixbuf
);
207 tcd
->stop_button
= gtk_button_new_with_label("stop");
208 gtk_button_set_image(GTK_BUTTON(tcd
->stop_button
), image
);
209 gtk_button_set_alignment(GTK_BUTTON(tcd
->stop_button
), 0.0, 0.0);
210 gtk_widget_show (tcd
->stop_button
);
211 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->stop_button
,6,7,3,4,GTK_FILL
,GTK_FILL
,2,2);
214 * First half of the filter window
215 * - textual entry of filter expression
216 * - processing button
218 tcd
->username_label
= gtk_label_new("Username:");
219 gtk_widget_show (tcd
->username_label
);
220 tcd
->username_entry
= gtk_entry_new();
221 gtk_entry_set_text(GTK_ENTRY(tcd
->username_entry
),"root");
222 gtk_widget_show (tcd
->username_entry
);
223 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->username_label
,0,2,0,1,GTK_FILL
,GTK_FILL
,2,2);
224 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);
228 tcd
->password_label
= gtk_label_new("Password:");
229 gtk_widget_show (tcd
->password_label
);
230 tcd
->password_entry
= gtk_entry_new();
231 gtk_entry_set_visibility(GTK_ENTRY(tcd
->password_entry
), FALSE
);
232 gtk_widget_show (tcd
->password_entry
);
233 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->password_label
,0,2,1,2,GTK_FILL
,GTK_FILL
,2,2);
234 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);
237 tcd
->channel_dir_label
= gtk_label_new("Channel directory:");
238 gtk_widget_show (tcd
->channel_dir_label
);
239 tcd
->channel_dir_entry
= gtk_entry_new();
240 gtk_entry_set_text(GTK_ENTRY(tcd
->channel_dir_entry
),"/mnt/relayfs/ltt");
241 gtk_widget_show (tcd
->channel_dir_entry
);
242 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->channel_dir_label
,0,2,2,3,GTK_FILL
,GTK_FILL
,2,2);
243 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);
245 tcd
->trace_dir_label
= gtk_label_new("Trace directory:");
246 gtk_widget_show (tcd
->trace_dir_label
);
247 tcd
->trace_dir_entry
= gtk_entry_new();
248 gtk_entry_set_text(GTK_ENTRY(tcd
->trace_dir_entry
),"/tmp/trace1");
249 gtk_widget_show (tcd
->trace_dir_entry
);
250 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->trace_dir_label
,0,2,3,4,GTK_FILL
,GTK_FILL
,2,2);
251 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);
253 tcd
->trace_name_label
= gtk_label_new("Trace name:");
254 gtk_widget_show (tcd
->trace_name_label
);
255 tcd
->trace_name_entry
= gtk_entry_new();
256 gtk_entry_set_text(GTK_ENTRY(tcd
->trace_name_entry
),"trace");
257 gtk_widget_show (tcd
->trace_name_entry
);
258 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->trace_name_label
,0,2,4,5,GTK_FILL
,GTK_FILL
,2,2);
259 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);
261 tcd
->trace_mode_label
= gtk_label_new("Trace mode ");
262 gtk_widget_show (tcd
->trace_mode_label
);
263 tcd
->trace_mode_combo
= gtk_combo_box_new_text();
264 gtk_combo_box_append_text(GTK_COMBO_BOX(tcd
->trace_mode_combo
),
266 gtk_combo_box_append_text(GTK_COMBO_BOX(tcd
->trace_mode_combo
),
268 gtk_combo_box_set_active(GTK_COMBO_BOX(tcd
->trace_mode_combo
), 0);
269 gtk_widget_show (tcd
->trace_mode_combo
);
270 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->trace_mode_label
,0,2,5,6,GTK_FILL
,GTK_FILL
,2,2);
271 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);
273 tcd
->start_daemon_label
= gtk_label_new("Start daemon ");
274 gtk_widget_show (tcd
->start_daemon_label
);
275 tcd
->start_daemon_check
= gtk_check_button_new();
276 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tcd
->start_daemon_check
), TRUE
);
277 gtk_widget_show (tcd
->start_daemon_check
);
278 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->start_daemon_label
,0,2,6,7,GTK_FILL
,GTK_FILL
,2,2);
279 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->start_daemon_check
,2,6,6,7,GTK_FILL
,GTK_FILL
,0,0);
281 tcd
->append_label
= gtk_label_new("Append to trace ");
282 gtk_widget_show (tcd
->append_label
);
283 tcd
->append_check
= gtk_check_button_new();
284 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tcd
->append_check
), FALSE
);
285 gtk_widget_show (tcd
->append_check
);
286 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->append_label
,0,2,7,8,GTK_FILL
,GTK_FILL
,2,2);
287 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->append_check
,2,6,7,8,GTK_FILL
,GTK_FILL
,0,0);
290 tcd
->optional_label
= gtk_label_new("Optional fields ");
291 gtk_widget_show (tcd
->optional_label
);
292 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->optional_label
,0,6,8,9,GTK_FILL
,GTK_FILL
,2,2);
294 tcd
->subbuf_size_label
= gtk_label_new("Subbuffer size:");
295 gtk_widget_show (tcd
->subbuf_size_label
);
296 tcd
->subbuf_size_entry
= gtk_entry_new();
297 gtk_widget_show (tcd
->subbuf_size_entry
);
298 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->subbuf_size_label
,0,2,9,10,GTK_FILL
,GTK_FILL
,2,2);
299 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);
301 tcd
->subbuf_num_label
= gtk_label_new("Number of subbuffers:");
302 gtk_widget_show (tcd
->subbuf_num_label
);
303 tcd
->subbuf_num_entry
= gtk_entry_new();
304 gtk_widget_show (tcd
->subbuf_num_entry
);
305 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->subbuf_num_label
,0,2,10,11,GTK_FILL
,GTK_FILL
,2,2);
306 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);
308 tcd
->lttctl_path_label
= gtk_label_new("path to lttctl:");
309 gtk_widget_show (tcd
->lttctl_path_label
);
310 tcd
->lttctl_path_entry
= gtk_entry_new();
311 gtk_entry_set_text(GTK_ENTRY(tcd
->lttctl_path_entry
),PACKAGE_BIN_DIR
"/lttctl");
312 gtk_widget_show (tcd
->lttctl_path_entry
);
313 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->lttctl_path_label
,0,2,11,12,GTK_FILL
,GTK_FILL
,2,2);
314 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);
317 tcd
->lttd_path_label
= gtk_label_new("path to lttd:");
318 gtk_widget_show (tcd
->lttd_path_label
);
319 tcd
->lttd_path_entry
= gtk_entry_new();
320 gtk_entry_set_text(GTK_ENTRY(tcd
->lttd_path_entry
),PACKAGE_BIN_DIR
"/lttd");
321 gtk_widget_show (tcd
->lttd_path_entry
);
322 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->lttd_path_label
,0,2,12,13,GTK_FILL
,GTK_FILL
,2,2);
323 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);
326 tcd
->fac_path_label
= gtk_label_new("path to facilities:");
327 gtk_widget_show (tcd
->fac_path_label
);
328 tcd
->fac_path_entry
= gtk_entry_new();
329 gtk_entry_set_text(GTK_ENTRY(tcd
->fac_path_entry
),PACKAGE_DATA_DIR
"/" PACKAGE
"/facilities");
330 gtk_widget_set_size_request(tcd
->fac_path_entry
, 250, -1);
331 gtk_widget_show (tcd
->fac_path_entry
);
332 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->fac_path_label
,0,2,13,14,GTK_FILL
,GTK_FILL
,2,2);
333 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);
335 focus_chain
= g_list_append (focus_chain
, tcd
->username_entry
);
336 focus_chain
= g_list_append (focus_chain
, tcd
->password_entry
);
337 focus_chain
= g_list_append (focus_chain
, tcd
->start_button
);
338 focus_chain
= g_list_append (focus_chain
, tcd
->pause_button
);
339 focus_chain
= g_list_append (focus_chain
, tcd
->unpause_button
);
340 focus_chain
= g_list_append (focus_chain
, tcd
->stop_button
);
341 focus_chain
= g_list_append (focus_chain
, tcd
->channel_dir_entry
);
342 focus_chain
= g_list_append (focus_chain
, tcd
->trace_dir_entry
);
343 focus_chain
= g_list_append (focus_chain
, tcd
->trace_name_entry
);
344 focus_chain
= g_list_append (focus_chain
, tcd
->trace_mode_combo
);
345 focus_chain
= g_list_append (focus_chain
, tcd
->start_daemon_check
);
346 focus_chain
= g_list_append (focus_chain
, tcd
->append_check
);
347 focus_chain
= g_list_append (focus_chain
, tcd
->subbuf_size_entry
);
348 focus_chain
= g_list_append (focus_chain
, tcd
->subbuf_num_entry
);
349 focus_chain
= g_list_append (focus_chain
, tcd
->lttctl_path_entry
);
350 focus_chain
= g_list_append (focus_chain
, tcd
->lttd_path_entry
);
351 focus_chain
= g_list_append (focus_chain
, tcd
->fac_path_entry
);
353 gtk_container_set_focus_chain(GTK_CONTAINER(tcd
->main_box
), focus_chain
);
355 g_signal_connect(G_OBJECT(tcd
->start_button
), "clicked",
356 (GCallback
)start_clicked
, tcd
);
357 g_signal_connect(G_OBJECT(tcd
->pause_button
), "clicked",
358 (GCallback
)pause_clicked
, tcd
);
359 g_signal_connect(G_OBJECT(tcd
->unpause_button
), "clicked",
360 (GCallback
)unpause_clicked
, tcd
);
361 g_signal_connect(G_OBJECT(tcd
->stop_button
), "clicked",
362 (GCallback
)stop_clicked
, tcd
);
365 * show main container
367 gtk_widget_show(tcd
->main_box
);
368 gtk_widget_show(tcd
->window
);
371 g_object_set_data_full(
372 G_OBJECT(guicontrol_get_widget(tcd
)),
373 "control_viewer_data",
375 (GDestroyNotify
)gui_control_destructor
);
377 g_control_list
= g_slist_append(
386 * @fn void gui_control_destructor(ControlData*)
388 * Destructor for the filter gui module
389 * @param tcd The module structure
392 gui_control_destructor(ControlData
*tcd
)
396 /* May already been done by GTK window closing */
397 if(GTK_IS_WIDGET(guicontrol_get_widget(tcd
))){
398 g_info("widget still exists");
401 // lttvwindow_unregister_traceset_notify(tcd->tab,
402 // filter_traceset_changed,
403 // filter_viewer_data);
405 lttvwindowtraces_background_notify_remove(tcd
);
407 g_control_list
= g_slist_remove(g_control_list
, tcd
);
412 static int execute_command(const gchar
*command
, const gchar
*username
,
413 const gchar
*password
, const gchar
*lttd_path
, const gchar
*fac_path
)
417 pid
= forkpty(&fdpty
, NULL
, NULL
, NULL
);
425 /* discuss with su */
426 struct timeval timeout
;
430 struct pollfd pollfd
;
435 /* Read the output from the child terminal before the prompt. If no data in
436 * 200 ms, we stop reading to give the password */
437 g_info("Reading from child console...");
438 sleep(1); /* make sure the child is ready */
441 pollfd
.events
= POLLIN
|POLLPRI
|POLLERR
|POLLHUP
|POLLNVAL
;
443 num_rdy
= poll(&pollfd
, 1, 200);
446 perror("Poll error");
451 /* Timeout : stop waiting for chars */
452 if(num_rdy
== 0) break;
454 switch(pollfd
.revents
) {
456 g_warning("Error returned in polling fd\n");
460 g_info("Polling FD : hung up.");
464 g_warning("Polling fd tells it is not open");
469 count
= read (fdpty
, buf
, 256);
473 } else if(count
== -1) {
474 perror("Error in read");
480 g_warning("Child hung up too fast");
485 /* Write the password */
486 g_info("Got su prompt, now writing password...");
488 ret
= write(fdpty
, password
, strlen(password
));
489 if(ret
< 0) perror("Error in write");
490 ret
= write(fdpty
, "\n", 1);
491 if(ret
< 0) perror("Error in write");
494 /* Take the output from the terminal and show it on the real console */
495 g_info("Getting data from child terminal...");
499 pollfd
.events
= POLLIN
|POLLPRI
|POLLERR
|POLLHUP
|POLLNVAL
;
501 num_rdy
= poll(&pollfd
, 1, -1);
504 perror("Poll error");
508 if(num_rdy
== 0) break;
510 switch(pollfd
.revents
) {
512 g_warning("Error returned in polling fd\n");
516 g_info("Polling FD : hung up.");
520 g_warning("Polling fd tells it is not open");
525 count
= read (fdpty
, buf
, 256);
529 } else if(count
== -1) {
530 perror("Error in read");
535 if(num_hup
> 0) goto wait_child
;
538 g_info("Waiting for child exit...");
540 ret
= waitpid(pid
, &status
, 0);
543 g_warning("An error occured in wait : %s",
546 if(WIFEXITED(status
))
547 if(WEXITSTATUS(status
) != 0) {
548 retval
= WEXITSTATUS(status
);
549 g_warning("An error occured in the su command : %s",
554 g_info("Child exited.");
556 } else if(pid
== 0) {
557 /* Setup environment variables */
558 if(strcmp(lttd_path
, "") != 0)
559 setenv("LTT_DAEMON", lttd_path
, 1);
560 if(strcmp(fac_path
, "") != 0)
561 setenv("LTT_FACILITIES", fac_path
, 1);
563 g_message("Executing (as %s) : %s\n", username
, command
);
565 execlp("su", "su", "-p", "-c", command
, username
, NULL
);
566 exit(-1); /* not supposed to happen! */
568 //gint ret = execvp();
572 g_warning("Error happened when forking for su");
581 void start_clicked (GtkButton
*button
, gpointer user_data
)
583 ControlData
*tcd
= (ControlData
*)user_data
;
585 const gchar
*username
= gtk_entry_get_text(GTK_ENTRY(tcd
->username_entry
));
586 const gchar
*password
= gtk_entry_get_text(GTK_ENTRY(tcd
->password_entry
));
587 const gchar
*channel_dir
=
588 gtk_entry_get_text(GTK_ENTRY(tcd
->channel_dir_entry
));
589 const gchar
*trace_dir
= gtk_entry_get_text(GTK_ENTRY(tcd
->trace_dir_entry
));
590 const gchar
*trace_name
=
591 gtk_entry_get_text(GTK_ENTRY(tcd
->trace_name_entry
));
593 const gchar
*trace_mode_sel
=
594 gtk_combo_box_get_active_text(GTK_COMBO_BOX(tcd
->trace_mode_combo
));
595 const gchar
*trace_mode
;
596 if(strcmp(trace_mode_sel
, "normal") == 0)
597 trace_mode
= "normal";
599 trace_mode
= "flight";
601 gboolean start_daemon
=
602 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tcd
->start_daemon_check
));
605 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tcd
->append_check
));
607 const gchar
*subbuf_size
=
608 gtk_entry_get_text(GTK_ENTRY(tcd
->subbuf_size_entry
));
609 const gchar
*subbuf_num
=
610 gtk_entry_get_text(GTK_ENTRY(tcd
->subbuf_num_entry
));
611 const gchar
*lttctl_path
=
612 gtk_entry_get_text(GTK_ENTRY(tcd
->lttctl_path_entry
));
613 const gchar
*lttd_path
= gtk_entry_get_text(GTK_ENTRY(tcd
->lttd_path_entry
));
614 const gchar
*fac_path
= gtk_entry_get_text(GTK_ENTRY(tcd
->fac_path_entry
));
617 /* Setup arguments to su */
619 gchar args
[MAX_ARGS_LEN
];
620 gint args_left
= MAX_ARGS_LEN
- 1; /* for \0 */
625 strncat(args
, "exec", args_left
);
626 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
629 strncat(args
, " ", args_left
);
630 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
632 if(strcmp(lttctl_path
, "") == 0)
633 strncat(args
, "lttctl", args_left
);
635 strncat(args
, lttctl_path
, args_left
);
636 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
639 strncat(args
, " ", args_left
);
640 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
643 strncat(args
, "-l ", args_left
);
644 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
645 strncat(args
, channel_dir
, args_left
);
646 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
649 strncat(args
, " ", args_left
);
650 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
653 strncat(args
, "-t ", args_left
);
654 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
655 strncat(args
, trace_dir
, args_left
);
656 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
659 strncat(args
, " ", args_left
);
660 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
663 strncat(args
, "-n ", args_left
);
664 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
665 strncat(args
, trace_name
, args_left
);
666 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
669 strncat(args
, " ", args_left
);
670 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
673 strncat(args
, "-m ", args_left
);
674 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
675 strncat(args
, trace_mode
, args_left
);
676 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
679 strncat(args
, " ", args_left
);
680 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
684 strncat(args
, "-d", args_left
);
685 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
687 /* Simply create the channel and then start tracing */
688 strncat(args
, "-b", args_left
);
689 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
693 /* Append to trace ? */
696 strncat(args
, " ", args_left
);
697 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
698 strncat(args
, "-a", args_left
);
699 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
702 /* optional arguments */
704 if(strcmp(subbuf_size
, "") != 0) {
706 strncat(args
, " ", args_left
);
707 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
709 strncat(args
, "-z ", args_left
);
710 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
711 strncat(args
, subbuf_size
, args_left
);
712 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
715 /* number of subbuffers */
716 if(strcmp(subbuf_num
, "") != 0) {
718 strncat(args
, " ", args_left
);
719 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
721 strncat(args
, "-x ", args_left
);
722 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
723 strncat(args
, subbuf_num
, args_left
);
724 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
728 int retval
= execute_command(args
, username
, password
, lttd_path
, fac_path
);
732 guint msg_left
= 256;
734 strcpy(msg
, "A problem occured when executing the su command : ");
735 msg_left
= 256 - strlen(msg
) - 1;
736 strncat(msg
, strerror(retval
), msg_left
);
737 GtkWidget
*dialogue
=
738 gtk_message_dialog_new(
739 GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(button
))),
740 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
744 gtk_dialog_run(GTK_DIALOG(dialogue
));
745 gtk_widget_destroy(dialogue
);
751 void pause_clicked (GtkButton
*button
, gpointer user_data
)
753 ControlData
*tcd
= (ControlData
*)user_data
;
755 const gchar
*username
= gtk_entry_get_text(GTK_ENTRY(tcd
->username_entry
));
756 const gchar
*password
= gtk_entry_get_text(GTK_ENTRY(tcd
->password_entry
));
757 const gchar
*trace_name
=
758 gtk_entry_get_text(GTK_ENTRY(tcd
->trace_name_entry
));
759 const gchar
*lttd_path
= "";
760 const gchar
*fac_path
= "";
762 const gchar
*lttctl_path
=
763 gtk_entry_get_text(GTK_ENTRY(tcd
->lttctl_path_entry
));
765 /* Setup arguments to su */
767 gchar args
[MAX_ARGS_LEN
];
768 gint args_left
= MAX_ARGS_LEN
- 1; /* for \0 */
773 strncat(args
, "exec", args_left
);
774 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
777 strncat(args
, " ", args_left
);
778 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
780 if(strcmp(lttctl_path
, "") == 0)
781 strncat(args
, "lttctl", args_left
);
783 strncat(args
, lttctl_path
, args_left
);
784 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
787 strncat(args
, " ", args_left
);
788 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
791 strncat(args
, "-n ", args_left
);
792 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
793 strncat(args
, trace_name
, args_left
);
794 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
797 strncat(args
, " ", args_left
);
798 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
800 /* Simply pause tracing */
801 strncat(args
, "-q", args_left
);
802 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
804 int retval
= execute_command(args
, username
, password
, lttd_path
, fac_path
);
807 guint msg_left
= 256;
809 strcpy(msg
, "A problem occured when executing the su command : ");
810 msg_left
= 256 - strlen(msg
) - 1;
811 strncat(msg
, strerror(retval
), msg_left
);
812 GtkWidget
*dialogue
=
813 gtk_message_dialog_new(
814 GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(button
))),
815 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
819 gtk_dialog_run(GTK_DIALOG(dialogue
));
820 gtk_widget_destroy(dialogue
);
825 void unpause_clicked (GtkButton
*button
, gpointer user_data
)
827 ControlData
*tcd
= (ControlData
*)user_data
;
829 const gchar
*username
= gtk_entry_get_text(GTK_ENTRY(tcd
->username_entry
));
830 const gchar
*password
= gtk_entry_get_text(GTK_ENTRY(tcd
->password_entry
));
831 const gchar
*trace_name
=
832 gtk_entry_get_text(GTK_ENTRY(tcd
->trace_name_entry
));
833 const gchar
*lttd_path
= "";
834 const gchar
*fac_path
= "";
836 const gchar
*lttctl_path
=
837 gtk_entry_get_text(GTK_ENTRY(tcd
->lttctl_path_entry
));
839 /* Setup arguments to su */
841 gchar args
[MAX_ARGS_LEN
];
842 gint args_left
= MAX_ARGS_LEN
- 1; /* for \0 */
847 strncat(args
, "exec", args_left
);
848 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
851 strncat(args
, " ", args_left
);
852 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
854 if(strcmp(lttctl_path
, "") == 0)
855 strncat(args
, "lttctl", args_left
);
857 strncat(args
, lttctl_path
, args_left
);
858 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
861 strncat(args
, " ", args_left
);
862 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
865 strncat(args
, "-n ", args_left
);
866 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
867 strncat(args
, trace_name
, args_left
);
868 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
871 strncat(args
, " ", args_left
);
872 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
874 /* Simply unpause tracing */
875 strncat(args
, "-s", args_left
);
876 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
878 int retval
= execute_command(args
, username
, password
, lttd_path
, fac_path
);
881 guint msg_left
= 256;
883 strcpy(msg
, "A problem occured when executing the su command : ");
884 msg_left
= 256 - strlen(msg
) - 1;
885 strncat(msg
, strerror(retval
), msg_left
);
886 GtkWidget
*dialogue
=
887 gtk_message_dialog_new(
888 GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(button
))),
889 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
893 gtk_dialog_run(GTK_DIALOG(dialogue
));
894 gtk_widget_destroy(dialogue
);
899 void stop_clicked (GtkButton
*button
, gpointer user_data
)
901 ControlData
*tcd
= (ControlData
*)user_data
;
903 const gchar
*username
= gtk_entry_get_text(GTK_ENTRY(tcd
->username_entry
));
904 const gchar
*password
= gtk_entry_get_text(GTK_ENTRY(tcd
->password_entry
));
905 const gchar
*trace_name
=
906 gtk_entry_get_text(GTK_ENTRY(tcd
->trace_name_entry
));
907 const gchar
*lttd_path
= "";
908 const gchar
*fac_path
= "";
910 const gchar
*lttctl_path
=
911 gtk_entry_get_text(GTK_ENTRY(tcd
->lttctl_path_entry
));
912 const gchar
*trace_dir
= gtk_entry_get_text(GTK_ENTRY(tcd
->trace_dir_entry
));
914 /* Setup arguments to su */
916 gchar args
[MAX_ARGS_LEN
];
917 gint args_left
= MAX_ARGS_LEN
- 1; /* for \0 */
922 strncat(args
, "exec", args_left
);
923 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
926 strncat(args
, " ", args_left
);
927 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
929 if(strcmp(lttctl_path
, "") == 0)
930 strncat(args
, "lttctl", args_left
);
932 strncat(args
, lttctl_path
, args_left
);
933 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
936 strncat(args
, " ", args_left
);
937 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
940 strncat(args
, "-n ", args_left
);
941 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
942 strncat(args
, trace_name
, args_left
);
943 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
946 strncat(args
, " ", args_left
);
947 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
949 /* Simply stop tracing and destroy channel */
950 strncat(args
, "-R", args_left
);
951 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
953 int retval
= execute_command(args
, username
, password
, lttd_path
, fac_path
);
956 guint msg_left
= 256;
958 strcpy(msg
, "A problem occured when executing the su command : ");
959 msg_left
= 256 - strlen(msg
) - 1;
960 strncat(msg
, strerror(retval
), msg_left
);
961 GtkWidget
*dialogue
=
962 gtk_message_dialog_new(
963 GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(button
))),
964 GTK_DIALOG_MODAL
|GTK_DIALOG_DESTROY_WITH_PARENT
,
968 gtk_dialog_run(GTK_DIALOG(dialogue
));
969 gtk_widget_destroy(dialogue
);
974 /* Ask to the user if he wants to open the trace in a new window */
979 dialogue
= gtk_dialog_new_with_buttons("Open trace ?",
980 GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(button
))),
981 GTK_DIALOG_MODAL
| GTK_DIALOG_DESTROY_WITH_PARENT
,
982 GTK_STOCK_YES
,GTK_RESPONSE_ACCEPT
,
983 GTK_STOCK_NO
,GTK_RESPONSE_REJECT
,
985 label
= gtk_label_new("Do you want to open the trace in LTTV ?");
986 gtk_widget_show(label
);
988 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialogue
)->vbox
),
991 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
994 case GTK_RESPONSE_ACCEPT
:
996 create_main_window_with_trace(trace_dir
);
999 case GTK_RESPONSE_REJECT
:
1003 gtk_widget_destroy(dialogue
);
1009 * @fn GtkWidget* h_guicontrol(Tab*)
1011 * Control Module's constructor hook
1013 * This constructor is given as a parameter to the menuitem and toolbar button
1014 * registration. It creates the list.
1015 * @param tab A pointer to the parent window.
1016 * @return The widget created.
1019 h_guicontrol(Tab
*tab
)
1021 ControlData
* f
= gui_control(tab
) ;
1027 * @fn static void init()
1029 * This function initializes the Filter Viewer functionnality through the
1032 static void init() {
1034 lttvwindow_register_constructor("guicontrol",
1036 "Insert Tracing Control Module",
1037 hTraceControlInsert_xpm
,
1038 "Insert Tracing Control Module",
1043 * @fn void control_destroy_walk(gpointer,gpointer)
1045 * Initiate the destruction of the current gui module
1046 * on the GTK Interface
1049 control_destroy_walk(gpointer data
, gpointer user_data
)
1051 ControlData
*tcd
= (ControlData
*)data
;
1053 g_debug("traceontrol.c : control_destroy_walk, %p", tcd
);
1055 /* May already have been done by GTK window closing */
1056 if(GTK_IS_WIDGET(guicontrol_get_widget(tcd
)))
1057 gtk_widget_destroy(guicontrol_get_widget(tcd
));
1061 * @fn static void destroy()
1062 * @brief plugin's destroy function
1064 * This function releases the memory reserved by the module and unregisters
1065 * everything that has been registered in the gtkTraceSet API.
1067 static void destroy() {
1069 g_slist_foreach(g_control_list
, control_destroy_walk
, NULL
);
1071 lttvwindow_unregister_constructor(h_guicontrol
);
1076 LTTV_MODULE("guitracecontrol", "Trace Control Window", \
1077 "Graphical module that let user control kernel tracing", \
1078 init
, destroy
, "lttvwindow")