#endif
#include <glib.h>
+#include <glib/gprintf.h>
#include <string.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <lttvwindow/lttvwindow.h>
#include <lttvwindow/lttvwindowtraces.h>
+#include <lttvwindow/callbacks.h>
#include "hTraceControlInsert.xpm"
#include "TraceControlStart.xpm"
#include <sys/wait.h>
#include <sys/poll.h>
#include <errno.h>
+#include <fcntl.h>
+#include <sched.h>
#define MAX_ARGS_LEN PATH_MAX * 10
* Prototypes
*/
GtkWidget *guicontrol_get_widget(ControlData *tcd);
-ControlData *gui_control(Tab *tab);
+ControlData *gui_control(GObject *obj);
void gui_control_destructor(ControlData *tcd);
-GtkWidget* h_guicontrol(Tab *tab);
+GtkWidget* h_guicontrol(GObject *obj);
void control_destroy_walk(gpointer data, gpointer user_data);
/*
GtkWidget *subbuf_size_entry;
GtkWidget *subbuf_num_label;
GtkWidget *subbuf_num_entry;
+ GtkWidget *lttd_threads_label;
+ GtkWidget *lttd_threads_entry;
GtkWidget *lttctl_path_label;
GtkWidget *lttctl_path_entry;
GtkWidget *lttd_path_label;
* @return The Filter viewer data created.
*/
ControlData*
-gui_control(Tab *tab)
+gui_control(GObject *obj)
{
+ Tab *tab = g_object_get_data(obj, "Tab");
g_debug("filter::gui_control()");
unsigned i;
gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->subbuf_num_label,0,2,10,11,GTK_FILL,GTK_FILL,2,2);
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);
+ tcd->lttd_threads_label = gtk_label_new("Number of lttd threads:");
+ gtk_widget_show (tcd->lttd_threads_label);
+ tcd->lttd_threads_entry = gtk_entry_new();
+ gtk_entry_set_text(GTK_ENTRY(tcd->lttd_threads_entry), "1");
+ gtk_widget_show (tcd->lttd_threads_entry);
+ gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->lttd_threads_label,0,2,11,12,GTK_FILL,GTK_FILL,2,2);
+ gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->lttd_threads_entry,2,6,11,12,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
+
tcd->lttctl_path_label = gtk_label_new("path to lttctl:");
gtk_widget_show (tcd->lttctl_path_label);
tcd->lttctl_path_entry = gtk_entry_new();
gtk_entry_set_text(GTK_ENTRY(tcd->lttctl_path_entry),PACKAGE_BIN_DIR "/lttctl");
gtk_widget_show (tcd->lttctl_path_entry);
- gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->lttctl_path_label,0,2,11,12,GTK_FILL,GTK_FILL,2,2);
- 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);
+ gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->lttctl_path_label,0,2,12,13,GTK_FILL,GTK_FILL,2,2);
+ gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->lttctl_path_entry,2,6,12,13,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
tcd->lttd_path_label = gtk_label_new("path to lttd:");
tcd->lttd_path_entry = gtk_entry_new();
gtk_entry_set_text(GTK_ENTRY(tcd->lttd_path_entry),PACKAGE_BIN_DIR "/lttd");
gtk_widget_show (tcd->lttd_path_entry);
- gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->lttd_path_label,0,2,12,13,GTK_FILL,GTK_FILL,2,2);
- 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);
+ gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->lttd_path_label,0,2,13,14,GTK_FILL,GTK_FILL,2,2);
+ gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->lttd_path_entry,2,6,13,14,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
tcd->fac_path_label = gtk_label_new("path to facilities:");
gtk_widget_show (tcd->fac_path_label);
tcd->fac_path_entry = gtk_entry_new();
- gtk_entry_set_text(GTK_ENTRY(tcd->fac_path_entry),PACKAGE_DATA_DIR "/" PACKAGE "/facilities");
+ gtk_entry_set_text(GTK_ENTRY(tcd->fac_path_entry),PACKAGE_DATA_DIR "/" "ltt-control" "/facilities");
gtk_widget_set_size_request(tcd->fac_path_entry, 250, -1);
gtk_widget_show (tcd->fac_path_entry);
- gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->fac_path_label,0,2,13,14,GTK_FILL,GTK_FILL,2,2);
- 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);
+ gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->fac_path_label,0,2,14,15,GTK_FILL,GTK_FILL,2,2);
+ gtk_table_attach( GTK_TABLE(tcd->main_box),tcd->fac_path_entry,2,6,14,15,GTK_FILL|GTK_EXPAND|GTK_SHRINK,GTK_FILL,0,0);
focus_chain = g_list_append (focus_chain, tcd->username_entry);
focus_chain = g_list_append (focus_chain, tcd->password_entry);
focus_chain = g_list_append (focus_chain, tcd->append_check);
focus_chain = g_list_append (focus_chain, tcd->subbuf_size_entry);
focus_chain = g_list_append (focus_chain, tcd->subbuf_num_entry);
+ focus_chain = g_list_append (focus_chain, tcd->lttd_threads_entry);
focus_chain = g_list_append (focus_chain, tcd->lttctl_path_entry);
focus_chain = g_list_append (focus_chain, tcd->lttd_path_entry);
focus_chain = g_list_append (focus_chain, tcd->fac_path_entry);
struct pollfd pollfd;
int num_rdy;
int num_hup = 0;
+ enum read_state { GET_LINE, GET_SEMI, GET_SPACE } read_state = GET_LINE;
+ retval = fcntl(fdpty, F_SETFL, O_WRONLY);
+ if(retval == -1) {
+ perror("Error in fcntl");
+ goto wait_child;
+ }
/* Read the output from the child terminal before the prompt. If no data in
* 200 ms, we stop reading to give the password */
g_info("Reading from child console...");
- sleep(1); /* make sure the child is ready */
while(1) {
pollfd.fd = fdpty;
pollfd.events = POLLIN|POLLPRI|POLLERR|POLLHUP|POLLNVAL;
- num_rdy = poll(&pollfd, 1, 200);
-#if 0
+ num_rdy = poll(&pollfd, 1, -1);
if(num_rdy == -1) {
perror("Poll error");
goto wait_child;
}
-#endif //0
- /* Timeout : stop waiting for chars */
- if(num_rdy == 0) break;
+ /* Timeout : Stop waiting for chars */
+ if(num_rdy == 0) goto wait_child;
switch(pollfd.revents) {
case POLLERR:
case POLLIN:
count = read (fdpty, buf, 256);
if(count > 0) {
+ unsigned int i;
buf[count] = '\0';
- printf("%s", buf);
+ g_printf("%s", buf);
+ for(i=0; i<count; i++) {
+ switch(read_state) {
+ case GET_LINE:
+ if(buf[i] == '\n') {
+ read_state = GET_SEMI;
+ g_debug("Tracecontrol input line skip\n");
+ }
+ break;
+ case GET_SEMI:
+ if(buf[i] == ':') {
+ g_debug("Tracecontrol input : marker found\n");
+ read_state = GET_SPACE;
+ }
+ break;
+ case GET_SPACE:
+ if(buf[i] == ' ') {
+ g_debug("Tracecontrol input space marker found\n");
+ goto write_password;
+ }
+ break;
+ }
+ }
} else if(count == -1) {
perror("Error in read");
goto wait_child;
goto wait_child;
}
}
-
+write_password:
+ fsync(fdpty);
+ pollfd.fd = fdpty;
+ pollfd.events = POLLOUT|POLLERR|POLLHUP|POLLNVAL;
+
+ num_rdy = poll(&pollfd, 1, -1);
+ if(num_rdy == -1) {
+ perror("Poll error");
+ goto wait_child;
+ }
+
/* Write the password */
g_info("Got su prompt, now writing password...");
int ret;
+ sleep(1);
ret = write(fdpty, password, strlen(password));
if(ret < 0) perror("Error in write");
ret = write(fdpty, "\n", 1);
if(ret < 0) perror("Error in write");
fsync(fdpty);
-
/* Take the output from the terminal and show it on the real console */
g_info("Getting data from child terminal...");
while(1) {
pollfd.events = POLLIN|POLLPRI|POLLERR|POLLHUP|POLLNVAL;
num_rdy = poll(&pollfd, 1, -1);
-#if 0
if(num_rdy == -1) {
perror("Poll error");
goto wait_child;
}
-#endif //0
if(num_rdy == 0) break;
+
+ if(pollfd.revents & (POLLERR|POLLNVAL)) {
+ g_warning("Error returned in polling fd\n");
+ num_hup++;
+ }
+
+ if(pollfd.revents & (POLLIN|POLLPRI) ) {
+ count = read (fdpty, buf, 256);
+ if(count > 0) {
+ buf[count] = '\0';
+ printf("%s", buf);
+ } else if(count == -1) {
+ perror("Error in read");
+ goto wait_child;
+ }
+ }
+
+ if(pollfd.revents & POLLHUP) {
+ g_info("Polling FD : hung up.");
+ num_hup++;
+ }
- switch(pollfd.revents) {
- case POLLERR:
- g_warning("Error returned in polling fd\n");
- num_hup++;
- break;
- case POLLHUP:
- g_info("Polling FD : hung up.");
- num_hup++;
- break;
- case POLLNVAL:
- g_warning("Polling fd tells it is not open");
- num_hup++;
- break;
- case POLLPRI:
- case POLLIN:
- count = read (fdpty, buf, 256);
- if(count > 0) {
- buf[count] = '\0';
- printf("%s", buf);
- } else if(count == -1) {
- perror("Error in read");
- goto wait_child;
- }
- break;
- }
if(num_hup > 0) goto wait_child;
}
wait_child:
if(strcmp(fac_path, "") != 0)
setenv("LTT_FACILITIES", fac_path, 1);
- g_message("Executing (as %s) : %s\n", username, command);
+ /* One comment line (must be only one) */
+ g_printf("Executing (as %s) : %s\n", username, command);
execlp("su", "su", "-p", "-c", command, username, NULL);
exit(-1); /* not supposed to happen! */
gtk_entry_get_text(GTK_ENTRY(tcd->subbuf_size_entry));
const gchar *subbuf_num =
gtk_entry_get_text(GTK_ENTRY(tcd->subbuf_num_entry));
+ const gchar *threads_num =
+ gtk_entry_get_text(GTK_ENTRY(tcd->lttd_threads_entry));
const gchar *lttctl_path =
gtk_entry_get_text(GTK_ENTRY(tcd->lttctl_path_entry));
const gchar *lttd_path = gtk_entry_get_text(GTK_ENTRY(tcd->lttd_path_entry));
args_left = MAX_ARGS_LEN - strlen(args) - 1;
}
+ /* number of lttd threads */
+ if(strcmp(threads_num, "") != 0) {
+ /* space */
+ strncat(args, " ", args_left);
+ args_left = MAX_ARGS_LEN - strlen(args) - 1;
+
+ strncat(args, "-N ", args_left);
+ args_left = MAX_ARGS_LEN - strlen(args) - 1;
+ strncat(args, threads_num, args_left);
+ args_left = MAX_ARGS_LEN - strlen(args) - 1;
+ }
+
int retval = execute_command(args, username, password, lttd_path, fac_path);
* @return The widget created.
*/
GtkWidget *
-h_guicontrol(Tab *tab)
+h_guicontrol(GObject *obj)
{
- ControlData* f = gui_control(tab) ;
+ ControlData* f = gui_control(obj);
return NULL;
}