make lttctl and lttd interaction more standard : real daemon
[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);
78static void stop_clicked (GtkButton *button, gpointer user_data);
e7c8534e 79
ff430216 80
e7c8534e 81/**
82 * @struct _ControlData
83 *
77ef407f 84 * @brief Main structure of gui control
e7c8534e 85 */
86struct _ControlData {
87 Tab *tab; /**< current tab of module */
88
77ef407f 89 GtkWidget *window; /**< window */
e7c8534e 90
77ef407f 91 GtkWidget *main_box; /**< main container */
92 GtkWidget *start_button;
93 GtkWidget *pause_button;
94 GtkWidget *stop_button;
95 GtkWidget *username_label;
96 GtkWidget *username_entry;
97 GtkWidget *password_label;
98 GtkWidget *password_entry;
99 GtkWidget *channel_dir_label;
100 GtkWidget *channel_dir_entry;
101 GtkWidget *trace_dir_label;
102 GtkWidget *trace_dir_entry;
103 GtkWidget *trace_name_label;
104 GtkWidget *trace_name_entry;
105 GtkWidget *trace_mode_label;
106 GtkWidget *trace_mode_combo;
107 GtkWidget *start_daemon_label;
108 GtkWidget *start_daemon_check;
109 GtkWidget *optional_label;
110 GtkWidget *subbuf_size_label;
111 GtkWidget *subbuf_size_entry;
112 GtkWidget *subbuf_num_label;
113 GtkWidget *subbuf_num_entry;
114 GtkWidget *lttctl_path_label;
115 GtkWidget *lttctl_path_entry;
116 GtkWidget *lttd_path_label;
117 GtkWidget *lttd_path_entry;
118 GtkWidget *fac_path_label;
119 GtkWidget *fac_path_entry;
e7c8534e 120};
121
122/**
123 * @fn GtkWidget* guicontrol_get_widget(ControlData*)
124 *
125 * This function returns the current main widget
126 * used by this module
127 * @param tcd the module struct
128 * @return The main widget
129 */
130GtkWidget*
131guicontrol_get_widget(ControlData *tcd)
132{
77ef407f 133 return tcd->window;
e7c8534e 134}
135
136/**
137 * @fn ControlData* gui_control(Tab*)
138 *
139 * Constructor is used to create ControlData data structure.
140 * @param tab The tab structure used by the widget
141 * @return The Filter viewer data created.
142 */
143ControlData*
144gui_control(Tab *tab)
145{
146 g_debug("filter::gui_control()");
147
148 unsigned i;
149 GtkCellRenderer *renderer;
150 GtkTreeViewColumn *column;
151
152 ControlData* tcd = g_new(ControlData,1);
153
154 tcd->tab = tab;
155
77ef407f 156 tcd->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
157 gtk_window_set_title(GTK_WINDOW(tcd->window), "LTTng Trace Control");
e7c8534e 158 /*
159 * Initiating GtkTable layout
160 * starts with 2 rows and 5 columns and
161 * expands when expressions added
162 */
77ef407f 163 tcd->main_box = gtk_table_new(14,7,FALSE);
164 gtk_table_set_row_spacings(GTK_TABLE(tcd->main_box),5);
165 gtk_table_set_col_spacings(GTK_TABLE(tcd->main_box),5);
e7c8534e 166
77ef407f 167 gtk_container_add(GTK_CONTAINER(tcd->window), GTK_WIDGET(tcd->main_box));
e7c8534e 168
ff430216 169 GList *focus_chain = NULL;
170
381229ee 171 /*
172 * start/pause/stop buttons
173 */
174 GdkPixbuf *pixbuf;
175 GtkWidget *image;
176 pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)TraceControlStart_xpm);
177 image = gtk_image_new_from_pixbuf(pixbuf);
77ef407f 178 tcd->start_button = gtk_button_new_with_label("start");
179 gtk_button_set_image(GTK_BUTTON(tcd->start_button), image);
180 gtk_button_set_alignment(GTK_BUTTON(tcd->start_button), 0.0, 0.0);
181 gtk_widget_show (tcd->start_button);
182 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->start_button,6,7,0,1,GTK_FILL,GTK_FILL,2,2);
381229ee 183
184 pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)TraceControlPause_xpm);
185 image = gtk_image_new_from_pixbuf(pixbuf);
77ef407f 186 tcd->pause_button = gtk_button_new_with_label("pause");
187 gtk_button_set_image(GTK_BUTTON(tcd->pause_button), image);
188 gtk_button_set_alignment(GTK_BUTTON(tcd->pause_button), 0.0, 0.0);
189 gtk_widget_show (tcd->pause_button);
190 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->pause_button,6,7,1,2,GTK_FILL,GTK_FILL,2,2);
381229ee 191
192 pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)TraceControlStop_xpm);
193 image = gtk_image_new_from_pixbuf(pixbuf);
77ef407f 194 tcd->stop_button = gtk_button_new_with_label("stop");
195 gtk_button_set_image(GTK_BUTTON(tcd->stop_button), image);
196 gtk_button_set_alignment(GTK_BUTTON(tcd->stop_button), 0.0, 0.0);
197 gtk_widget_show (tcd->stop_button);
198 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->stop_button,6,7,2,3,GTK_FILL,GTK_FILL,2,2);
381229ee 199
e7c8534e 200 /*
201 * First half of the filter window
202 * - textual entry of filter expression
203 * - processing button
204 */
77ef407f 205 tcd->username_label = gtk_label_new("Username:");
206 gtk_widget_show (tcd->username_label);
207 tcd->username_entry = gtk_entry_new();
208 gtk_entry_set_text(GTK_ENTRY(tcd->username_entry),"root");
209 gtk_widget_show (tcd->username_entry);
210 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->username_label,0,2,0,1,GTK_FILL,GTK_FILL,2,2);
211 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);
212
213
214
215 tcd->password_label = gtk_label_new("Password:");
216 gtk_widget_show (tcd->password_label);
217 tcd->password_entry = gtk_entry_new();
218 gtk_entry_set_visibility(GTK_ENTRY(tcd->password_entry), FALSE);
219 gtk_widget_show (tcd->password_entry);
220 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->password_label,0,2,1,2,GTK_FILL,GTK_FILL,2,2);
221 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);
222
223
224 tcd->channel_dir_label = gtk_label_new("Channel directory:");
225 gtk_widget_show (tcd->channel_dir_label);
226 tcd->channel_dir_entry = gtk_entry_new();
227 gtk_entry_set_text(GTK_ENTRY(tcd->channel_dir_entry),"/mnt/relayfs/ltt");
228 gtk_widget_show (tcd->channel_dir_entry);
229 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->channel_dir_label,0,2,2,3,GTK_FILL,GTK_FILL,2,2);
230 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);
231
232 tcd->trace_dir_label = gtk_label_new("Trace directory:");
233 gtk_widget_show (tcd->trace_dir_label);
234 tcd->trace_dir_entry = gtk_entry_new();
235 gtk_entry_set_text(GTK_ENTRY(tcd->trace_dir_entry),"/tmp/trace1");
236 gtk_widget_show (tcd->trace_dir_entry);
237 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->trace_dir_label,0,2,3,4,GTK_FILL,GTK_FILL,2,2);
238 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);
239
240 tcd->trace_name_label = gtk_label_new("Trace name:");
241 gtk_widget_show (tcd->trace_name_label);
242 tcd->trace_name_entry = gtk_entry_new();
243 gtk_entry_set_text(GTK_ENTRY(tcd->trace_name_entry),"trace");
244 gtk_widget_show (tcd->trace_name_entry);
245 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->trace_name_label,0,2,4,5,GTK_FILL,GTK_FILL,2,2);
246 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);
247
248 tcd->trace_mode_label = gtk_label_new("Trace mode ");
249 gtk_widget_show (tcd->trace_mode_label);
250 tcd->trace_mode_combo = gtk_combo_box_new_text();
251 gtk_combo_box_append_text(GTK_COMBO_BOX(tcd->trace_mode_combo),
381229ee 252 "normal");
77ef407f 253 gtk_combo_box_append_text(GTK_COMBO_BOX(tcd->trace_mode_combo),
381229ee 254 "flight recorder");
77ef407f 255 gtk_combo_box_set_active(GTK_COMBO_BOX(tcd->trace_mode_combo), 0);
256 gtk_widget_show (tcd->trace_mode_combo);
257 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->trace_mode_label,0,2,5,6,GTK_FILL,GTK_FILL,2,2);
258 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);
259
260 tcd->start_daemon_label = gtk_label_new("Start daemon ");
261 gtk_widget_show (tcd->start_daemon_label);
262 tcd->start_daemon_check = gtk_check_button_new();
263 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tcd->start_daemon_check), TRUE);
264 gtk_widget_show (tcd->start_daemon_check);
265 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->start_daemon_label,0,2,6,7,GTK_FILL,GTK_FILL,2,2);
266 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->start_daemon_check,2,6,6,7,GTK_FILL,GTK_FILL,0,0);
267
268 tcd->optional_label = gtk_label_new("Optional fields ");
269 gtk_widget_show (tcd->optional_label);
270 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->optional_label,0,6,7,8,GTK_FILL,GTK_FILL,2,2);
271
272 tcd->subbuf_size_label = gtk_label_new("Subbuffer size:");
273 gtk_widget_show (tcd->subbuf_size_label);
274 tcd->subbuf_size_entry = gtk_entry_new();
275 gtk_widget_show (tcd->subbuf_size_entry);
276 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->subbuf_size_label,0,2,8,9,GTK_FILL,GTK_FILL,2,2);
277 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->subbuf_size_entry,2,6,8,9,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
278
279 tcd->subbuf_num_label = gtk_label_new("Number of subbuffers:");
280 gtk_widget_show (tcd->subbuf_num_label);
281 tcd->subbuf_num_entry = gtk_entry_new();
282 gtk_widget_show (tcd->subbuf_num_entry);
283 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->subbuf_num_label,0,2,9,10,GTK_FILL,GTK_FILL,2,2);
284 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->subbuf_num_entry,2,6,9,10,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
285
286 tcd->lttctl_path_label = gtk_label_new("path to lttctl:");
287 gtk_widget_show (tcd->lttctl_path_label);
288 tcd->lttctl_path_entry = gtk_entry_new();
ff430216 289 gtk_entry_set_text(GTK_ENTRY(tcd->lttctl_path_entry),PACKAGE_BIN_DIR "/lttctl");
77ef407f 290 gtk_widget_show (tcd->lttctl_path_entry);
291 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->lttctl_path_label,0,2,10,11,GTK_FILL,GTK_FILL,2,2);
292 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->lttctl_path_entry,2,6,10,11,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
293
294
295 tcd->lttd_path_label = gtk_label_new("path to lttd:");
296 gtk_widget_show (tcd->lttd_path_label);
297 tcd->lttd_path_entry = gtk_entry_new();
ff430216 298 gtk_entry_set_text(GTK_ENTRY(tcd->lttd_path_entry),PACKAGE_BIN_DIR "/lttd");
77ef407f 299 gtk_widget_show (tcd->lttd_path_entry);
300 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->lttd_path_label,0,2,11,12,GTK_FILL,GTK_FILL,2,2);
301 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->lttd_path_entry,2,6,11,12,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
381229ee 302
303
77ef407f 304 tcd->fac_path_label = gtk_label_new("path to facilities:");
305 gtk_widget_show (tcd->fac_path_label);
306 tcd->fac_path_entry = gtk_entry_new();
86a65fdb 307 gtk_entry_set_text(GTK_ENTRY(tcd->fac_path_entry),PACKAGE_DATA_DIR "/" PACKAGE "/facilities");
77ef407f 308 gtk_widget_set_size_request(tcd->fac_path_entry, 250, -1);
309 gtk_widget_show (tcd->fac_path_entry);
310 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->fac_path_label,0,2,12,13,GTK_FILL,GTK_FILL,2,2);
311 gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->fac_path_entry,2,6,12,13,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
312
ff430216 313
314 GtkWidget *start_button;
315 GtkWidget *pause_button;
316 GtkWidget *stop_button;
317
318 GtkWidget *username_entry;
319 GtkWidget *password_entry;
320 GtkWidget *channel_dir_entry;
321 GtkWidget *trace_dir_entry;
322 GtkWidget *trace_name_entry;
323 GtkWidget *trace_mode_combo;
324 GtkWidget *start_daemon_check;
325 GtkWidget *subbuf_size_entry;
326 GtkWidget *subbuf_num_entry;
327 GtkWidget *lttctl_path_entry;
328 GtkWidget *lttd_path_entry;
329 GtkWidget *fac_path_entry;
330
331 focus_chain = g_list_append (focus_chain, tcd->username_entry);
332 focus_chain = g_list_append (focus_chain, tcd->password_entry);
333 focus_chain = g_list_append (focus_chain, tcd->start_button);
334 focus_chain = g_list_append (focus_chain, tcd->pause_button);
335 focus_chain = g_list_append (focus_chain, tcd->stop_button);
336 focus_chain = g_list_append (focus_chain, tcd->channel_dir_entry);
337 focus_chain = g_list_append (focus_chain, tcd->trace_dir_entry);
338 focus_chain = g_list_append (focus_chain, tcd->trace_name_entry);
339 focus_chain = g_list_append (focus_chain, tcd->trace_mode_combo);
340 focus_chain = g_list_append (focus_chain, tcd->start_daemon_check);
341 focus_chain = g_list_append (focus_chain, tcd->subbuf_size_entry);
342 focus_chain = g_list_append (focus_chain, tcd->subbuf_num_entry);
343 focus_chain = g_list_append (focus_chain, tcd->lttctl_path_entry);
344 focus_chain = g_list_append (focus_chain, tcd->lttd_path_entry);
345 focus_chain = g_list_append (focus_chain, tcd->fac_path_entry);
346
347 gtk_container_set_focus_chain(GTK_CONTAINER(tcd->main_box), focus_chain);
348
77ef407f 349 g_signal_connect(G_OBJECT(tcd->start_button), "clicked",
350 (GCallback)start_clicked, tcd);
351 g_signal_connect(G_OBJECT(tcd->pause_button), "clicked",
352 (GCallback)pause_clicked, tcd);
353 g_signal_connect(G_OBJECT(tcd->stop_button), "clicked",
354 (GCallback)stop_clicked, tcd);
e7c8534e 355
356 /*
357 * show main container
358 */
77ef407f 359 gtk_widget_show(tcd->main_box);
360 gtk_widget_show(tcd->window);
e7c8534e 361
362
363 g_object_set_data_full(
77ef407f 364 G_OBJECT(guicontrol_get_widget(tcd)),
365 "control_viewer_data",
e7c8534e 366 tcd,
367 (GDestroyNotify)gui_control_destructor);
368
369 g_control_list = g_slist_append(
370 g_control_list,
371 tcd);
372
373 return tcd;
374}
375
376
377/**
378 * @fn void gui_control_destructor(ControlData*)
379 *
380 * Destructor for the filter gui module
381 * @param tcd The module structure
382 */
383void
384gui_control_destructor(ControlData *tcd)
385{
386 Tab *tab = tcd->tab;
387
388 /* May already been done by GTK window closing */
77ef407f 389 if(GTK_IS_WIDGET(guicontrol_get_widget(tcd))){
e7c8534e 390 g_info("widget still exists");
391 }
392// if(tab != NULL) {
393// lttvwindow_unregister_traceset_notify(tcd->tab,
394// filter_traceset_changed,
395// filter_viewer_data);
396// }
397 lttvwindowtraces_background_notify_remove(tcd);
398
399 g_control_list = g_slist_remove(g_control_list, tcd);
400
401 g_free(tcd);
402}
403
77ef407f 404/* Callbacks */
405
406void start_clicked (GtkButton *button, gpointer user_data)
407{
408 ControlData *tcd = (ControlData*)user_data;
409
410 const gchar *username = gtk_entry_get_text(GTK_ENTRY(tcd->username_entry));
411 const gchar *password = gtk_entry_get_text(GTK_ENTRY(tcd->password_entry));
412 const gchar *channel_dir =
413 gtk_entry_get_text(GTK_ENTRY(tcd->channel_dir_entry));
414 const gchar *trace_dir = gtk_entry_get_text(GTK_ENTRY(tcd->trace_dir_entry));
415 const gchar *trace_name =
416 gtk_entry_get_text(GTK_ENTRY(tcd->trace_name_entry));
417
418 const gchar *trace_mode_sel =
419 gtk_combo_box_get_active_text(GTK_COMBO_BOX(tcd->trace_mode_combo));
420 const gchar *trace_mode;
421 if(strcmp(trace_mode_sel, "normal") == 0)
422 trace_mode = "normal";
423 else
424 trace_mode = "flight";
425
426 gboolean start_daemon =
f6f6abf0 427 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tcd->start_daemon_check));
77ef407f 428
429 const gchar *subbuf_size =
430 gtk_entry_get_text(GTK_ENTRY(tcd->subbuf_size_entry));
431 const gchar *subbuf_num =
432 gtk_entry_get_text(GTK_ENTRY(tcd->subbuf_num_entry));
433 const gchar *lttctl_path =
434 gtk_entry_get_text(GTK_ENTRY(tcd->lttctl_path_entry));
435 const gchar *lttd_path = gtk_entry_get_text(GTK_ENTRY(tcd->lttd_path_entry));
436 const gchar *fac_path = gtk_entry_get_text(GTK_ENTRY(tcd->fac_path_entry));
437
ff430216 438 //pid_t pid = fork();
439 pid_t pid;
440 int fdpty;
441 pid = forkpty(&fdpty, NULL, NULL, NULL);
77ef407f 442
443 if(pid > 0) {
444 /* parent */
ff430216 445 gchar buf[256];
446 int status;
447 ssize_t count;
448 /* discuss with su */
449 struct timeval timeout;
450 timeout.tv_sec = 1;
451 timeout.tv_usec = 0;
ff430216 452
86a65fdb 453 struct pollfd pollfd;
454 int num_rdy;
455 int num_hup = 0;
456
457
458 /* Read the output from the child terminal before the prompt. If no data in
459 * 200 ms, we stop reading to give the password */
460 g_info("Reading from child console...");
461 while(1) {
462 pollfd.fd = fdpty;
463 pollfd.events = POLLIN|POLLPRI;
464
465 num_rdy = poll(&pollfd, 1, 200);
466#if 0
467 if(num_rdy == -1) {
468 perror("Poll error");
469 goto wait_child;
470 }
471#endif //0
472
473 /* Timeout : stop waiting for chars */
474 if(num_rdy == 0) break;
475
476 switch(pollfd.revents) {
477 case POLLERR:
478 g_warning("Error returned in polling fd\n");
479 num_hup++;
480 break;
481 case POLLHUP:
482 g_info("Polling FD : hung up.");
483 num_hup++;
484 break;
485 case POLLNVAL:
486 g_warning("Polling fd tells it is not open");
487 num_hup++;
488 break;
489 case POLLPRI:
490 case POLLIN:
491 count = read (fdpty, buf, 256);
492 if(count > 0) {
493 buf[count] = '\0';
494 printf("%s", buf);
495 } else if(count == -1) {
496 perror("Error in read");
497 goto wait_child;
498 }
499 break;
500 }
501 if(num_hup > 0) {
502 g_warning("Child hung up too fast");
503 goto wait_child;
504 }
505 }
506
507 /* Write the password */
ff430216 508 g_info("Got su prompt, now writing password...");
ff430216 509 int ret;
510 ret = write(fdpty, password, strlen(password));
511 if(ret < 0) perror("Error in write");
512 ret = write(fdpty, "\n", 1);
513 if(ret < 0) perror("Error in write");
514 fsync(fdpty);
515
86a65fdb 516 /* Take the output from the terminal and show it on the real console */
517 g_info("Getting data from child terminal...");
518 while(1) {
519 int num_hup = 0;
520 pollfd.fd = fdpty;
521 pollfd.events = POLLIN|POLLPRI;
522
523 num_rdy = poll(&pollfd, 1, -1);
524#if 0
525 if(num_rdy == -1) {
526 perror("Poll error");
527 goto wait_child;
528 }
529#endif //0
530 if(num_rdy == 0) break;
531
532 switch(pollfd.revents) {
533 case POLLERR:
534 g_warning("Error returned in polling fd\n");
535 num_hup++;
536 break;
537 case POLLHUP:
538 g_info("Polling FD : hung up.");
539 num_hup++;
540 break;
541 case POLLNVAL:
542 g_warning("Polling fd tells it is not open");
543 num_hup++;
544 break;
545 case POLLPRI:
546 case POLLIN:
547 count = read (fdpty, buf, 256);
548 if(count > 0) {
549 buf[count] = '\0';
550 printf("%s", buf);
551 } else if(count == -1) {
552 perror("Error in read");
553 goto wait_child;
554 }
555 break;
ff430216 556 }
86a65fdb 557 if(num_hup > 0) goto wait_child;
558 }
559wait_child:
560 g_info("Waiting for child exit...");
561
562 ret = waitpid(pid, &status, 0);
ff430216 563
86a65fdb 564 if(WIFEXITED(ret))
565 if(WEXITSTATUS(ret) != 0)
566 g_warning("An error occured in the su command : %s",
567 strerror(WEXITSTATUS(ret)));
77ef407f 568
86a65fdb 569 g_info("Child exited.");
77ef407f 570
571 } else if(pid == 0) {
572 /* child */
f6f6abf0 573 gchar args[MAX_ARGS_LEN];
574 gint args_left = MAX_ARGS_LEN - 1; /* for \0 */
575
576 /* Setup environment variables */
77ef407f 577 if(strcmp(lttd_path, "") != 0)
578 setenv("LTT_DAEMON", lttd_path, 1);
579 if(strcmp(fac_path, "") != 0)
580 setenv("LTT_FACILITIES", fac_path, 1);
f6f6abf0 581
582 /* Setup arguments to su */
86a65fdb 583 //strncpy(args, "\'", args_left);
584 //args_left = MAX_ARGS_LEN - strlen(args) - 1;
ff430216 585
86a65fdb 586 /* Command */
587 strncat(args, "exec", args_left);
588 args_left = MAX_ARGS_LEN - strlen(args) - 1;
589
590 /* space */
591 strncat(args, " ", args_left);
592 args_left = MAX_ARGS_LEN - strlen(args) - 1;
593
ff430216 594 if(strcmp(lttctl_path, "") == 0)
86a65fdb 595 strncat(args, "lttctl", args_left);
596 else
597 strncat(args, lttctl_path, args_left);
598 args_left = MAX_ARGS_LEN - strlen(args) - 1;
599
600 /* space */
601 strncat(args, " ", args_left);
602 args_left = MAX_ARGS_LEN - strlen(args) - 1;
f6f6abf0 603
604 /* channel dir */
605 strncat(args, "-l ", args_left);
606 args_left = MAX_ARGS_LEN - strlen(args) - 1;
607 strncat(args, channel_dir, args_left);
608 args_left = MAX_ARGS_LEN - strlen(args) - 1;
609
610 /* space */
611 strncat(args, " ", args_left);
612 args_left = MAX_ARGS_LEN - strlen(args) - 1;
613
614 /* trace dir */
615 strncat(args, "-t ", args_left);
616 args_left = MAX_ARGS_LEN - strlen(args) - 1;
617 strncat(args, trace_dir, args_left);
618 args_left = MAX_ARGS_LEN - strlen(args) - 1;
619
620 /* space */
621 strncat(args, " ", args_left);
622 args_left = MAX_ARGS_LEN - strlen(args) - 1;
623
624 /* name */
625 strncat(args, "-n ", args_left);
626 args_left = MAX_ARGS_LEN - strlen(args) - 1;
627 strncat(args, trace_name, args_left);
628 args_left = MAX_ARGS_LEN - strlen(args) - 1;
629
630 /* space */
631 strncat(args, " ", args_left);
632 args_left = MAX_ARGS_LEN - strlen(args) - 1;
633
634 /* trace mode */
635 strncat(args, "-m ", args_left);
636 args_left = MAX_ARGS_LEN - strlen(args) - 1;
637 strncat(args, trace_mode, args_left);
638 args_left = MAX_ARGS_LEN - strlen(args) - 1;
639
640 /* space */
641 strncat(args, " ", args_left);
642 args_left = MAX_ARGS_LEN - strlen(args) - 1;
643
644 /* Start daemon ? */
645 if(start_daemon) {
646 strncat(args, "-d", args_left);
647 args_left = MAX_ARGS_LEN - strlen(args) - 1;
648 } else {
649 /* Simply create the channel and then start tracing */
650 strncat(args, "-b", args_left);
651 args_left = MAX_ARGS_LEN - strlen(args) - 1;
652 }
653
f6f6abf0 654 /* optional arguments */
655 /* subbuffer size */
656 if(strcmp(subbuf_size, "") != 0) {
ff430216 657 /* space */
658 strncat(args, " ", args_left);
659 args_left = MAX_ARGS_LEN - strlen(args) - 1;
660
f6f6abf0 661 strncat(args, "-z ", args_left);
662 args_left = MAX_ARGS_LEN - strlen(args) - 1;
663 strncat(args, subbuf_size, args_left);
664 args_left = MAX_ARGS_LEN - strlen(args) - 1;
665 }
666
f6f6abf0 667 /* number of subbuffers */
668 if(strcmp(subbuf_num, "") != 0) {
ff430216 669 /* space */
670 strncat(args, " ", args_left);
671 args_left = MAX_ARGS_LEN - strlen(args) - 1;
672
f6f6abf0 673 strncat(args, "-x ", args_left);
674 args_left = MAX_ARGS_LEN - strlen(args) - 1;
675 strncat(args, subbuf_num, args_left);
676 args_left = MAX_ARGS_LEN - strlen(args) - 1;
677 }
86a65fdb 678
679 //strncat(args, "\'", args_left);
680 //args_left = MAX_ARGS_LEN - strlen(args) - 1;
f6f6abf0 681
86a65fdb 682 g_message("Executing (as %s) : %s\n", username, args);
ff430216 683
86a65fdb 684 execlp("su", "su", "-p", "-c", args, username, NULL);
ff430216 685 exit(-1); /* not supposed to happen! */
686 //system(args);
687 //system("echo blah");
688 //exit(0);
77ef407f 689
690 //gint ret = execvp();
691
692 } else {
693 /* error */
ff430216 694 g_warning("Error happened when forking for su");
77ef407f 695 }
696
697}
698
699
700void pause_clicked (GtkButton *button, gpointer user_data)
701{
702 ControlData *tcd = (ControlData*)user_data;
703
704
705}
706
707void stop_clicked (GtkButton *button, gpointer user_data)
708{
709 ControlData *tcd = (ControlData*)user_data;
710
711
712}
713
e7c8534e 714
715/**
716 * @fn GtkWidget* h_guicontrol(Tab*)
717 *
718 * Control Module's constructor hook
719 *
720 * This constructor is given as a parameter to the menuitem and toolbar button
721 * registration. It creates the list.
722 * @param tab A pointer to the parent window.
723 * @return The widget created.
724 */
725GtkWidget *
726h_guicontrol(Tab *tab)
727{
728 ControlData* f = gui_control(tab) ;
729
730 return NULL;
731}
732
733/**
734 * @fn static void init()
735 *
736 * This function initializes the Filter Viewer functionnality through the
737 * gtkTraceSet API.
738 */
739static void init() {
740
741 lttvwindow_register_constructor("guicontrol",
742 "/",
743 "Insert Tracing Control Module",
744 hTraceControlInsert_xpm,
745 "Insert Tracing Control Module",
746 h_guicontrol);
747}
748
749/**
750 * @fn void control_destroy_walk(gpointer,gpointer)
751 *
752 * Initiate the destruction of the current gui module
753 * on the GTK Interface
754 */
755void
756control_destroy_walk(gpointer data, gpointer user_data)
757{
758 ControlData *tcd = (ControlData*)data;
759
760 g_debug("traceontrol.c : control_destroy_walk, %p", tcd);
761
762 /* May already have been done by GTK window closing */
763 if(GTK_IS_WIDGET(guicontrol_get_widget(tcd)))
764 gtk_widget_destroy(guicontrol_get_widget(tcd));
765}
766
767/**
768 * @fn static void destroy()
769 * @brief plugin's destroy function
770 *
771 * This function releases the memory reserved by the module and unregisters
772 * everything that has been registered in the gtkTraceSet API.
773 */
774static void destroy() {
775
776 g_slist_foreach(g_control_list, control_destroy_walk, NULL );
777
778 lttvwindow_unregister_constructor(h_guicontrol);
779
780}
781
782
783LTTV_MODULE("guitracecontrol", "Trace Control Window", \
784 "Graphical module that let user control kernel tracing", \
785 init, destroy, "lttvwindow")
786
This page took 0.053943 seconds and 4 git commands to generate.