X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Flttv%2Fmodules%2Fgui%2Ftracecontrol%2Ftracecontrol.c;h=75921a452bf203af051938a9ed60c3f2c2ff9c65;hb=86a65fdbbfe799d8a31d1fcfa6774ce9366054d4;hp=dd2fc97aedb522d2c7cb76a7cdfd10274cbdf259;hpb=f6f6abf0319447aae51aa3bc0464171b425e73b0;p=lttv.git diff --git a/ltt/branches/poly/lttv/modules/gui/tracecontrol/tracecontrol.c b/ltt/branches/poly/lttv/modules/gui/tracecontrol/tracecontrol.c index dd2fc97a..75921a45 100644 --- a/ltt/branches/poly/lttv/modules/gui/tracecontrol/tracecontrol.c +++ b/ltt/branches/poly/lttv/modules/gui/tracecontrol/tracecontrol.c @@ -41,6 +41,10 @@ #include #include #include +#include +#include +#include +#include #define MAX_ARGS_LEN PATH_MAX * 10 @@ -73,6 +77,7 @@ static void start_clicked (GtkButton *button, gpointer user_data); static void pause_clicked (GtkButton *button, gpointer user_data); static void stop_clicked (GtkButton *button, gpointer user_data); + /** * @struct _ControlData * @@ -161,6 +166,8 @@ gui_control(Tab *tab) gtk_container_add(GTK_CONTAINER(tcd->window), GTK_WIDGET(tcd->main_box)); + GList *focus_chain = NULL; + /* * start/pause/stop buttons */ @@ -279,6 +286,7 @@ gui_control(Tab *tab) 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,10,11,GTK_FILL,GTK_FILL,2,2); 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); @@ -287,6 +295,7 @@ gui_control(Tab *tab) tcd->lttd_path_label = gtk_label_new("path to lttd:"); gtk_widget_show (tcd->lttd_path_label); 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,11,12,GTK_FILL,GTK_FILL,2,2); 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); @@ -295,12 +304,48 @@ gui_control(Tab *tab) 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 "/facilities"); + gtk_entry_set_text(GTK_ENTRY(tcd->fac_path_entry),PACKAGE_DATA_DIR "/" PACKAGE "/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,12,13,GTK_FILL,GTK_FILL,2,2); 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); + + GtkWidget *start_button; + GtkWidget *pause_button; + GtkWidget *stop_button; + + GtkWidget *username_entry; + GtkWidget *password_entry; + GtkWidget *channel_dir_entry; + GtkWidget *trace_dir_entry; + GtkWidget *trace_name_entry; + GtkWidget *trace_mode_combo; + GtkWidget *start_daemon_check; + GtkWidget *subbuf_size_entry; + GtkWidget *subbuf_num_entry; + GtkWidget *lttctl_path_entry; + GtkWidget *lttd_path_entry; + GtkWidget *fac_path_entry; + + 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->start_button); + focus_chain = g_list_append (focus_chain, tcd->pause_button); + focus_chain = g_list_append (focus_chain, tcd->stop_button); + focus_chain = g_list_append (focus_chain, tcd->channel_dir_entry); + focus_chain = g_list_append (focus_chain, tcd->trace_dir_entry); + focus_chain = g_list_append (focus_chain, tcd->trace_name_entry); + focus_chain = g_list_append (focus_chain, tcd->trace_mode_combo); + focus_chain = g_list_append (focus_chain, tcd->start_daemon_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->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); + + gtk_container_set_focus_chain(GTK_CONTAINER(tcd->main_box), focus_chain); + g_signal_connect(G_OBJECT(tcd->start_button), "clicked", (GCallback)start_clicked, tcd); g_signal_connect(G_OBJECT(tcd->pause_button), "clicked", @@ -390,11 +435,138 @@ void start_clicked (GtkButton *button, gpointer user_data) const gchar *lttd_path = gtk_entry_get_text(GTK_ENTRY(tcd->lttd_path_entry)); const gchar *fac_path = gtk_entry_get_text(GTK_ENTRY(tcd->fac_path_entry)); - pid_t pid = fork(); + //pid_t pid = fork(); + pid_t pid; + int fdpty; + pid = forkpty(&fdpty, NULL, NULL, NULL); if(pid > 0) { /* parent */ + gchar buf[256]; + int status; + ssize_t count; + /* discuss with su */ + struct timeval timeout; + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + struct pollfd pollfd; + int num_rdy; + int num_hup = 0; + + + /* 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..."); + while(1) { + pollfd.fd = fdpty; + pollfd.events = POLLIN|POLLPRI; + + num_rdy = poll(&pollfd, 1, 200); +#if 0 + if(num_rdy == -1) { + perror("Poll error"); + goto wait_child; + } +#endif //0 + + /* Timeout : stop waiting for chars */ + if(num_rdy == 0) break; + + 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) { + g_warning("Child hung up too fast"); + goto wait_child; + } + } + + /* Write the password */ + g_info("Got su prompt, now writing password..."); + int ret; + 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) { + int num_hup = 0; + pollfd.fd = fdpty; + pollfd.events = POLLIN|POLLPRI; + + 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; + + 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: + g_info("Waiting for child exit..."); + + ret = waitpid(pid, &status, 0); + + if(WIFEXITED(ret)) + if(WEXITSTATUS(ret) != 0) + g_warning("An error occured in the su command : %s", + strerror(WEXITSTATUS(ret))); + g_info("Child exited."); } else if(pid == 0) { /* child */ @@ -408,13 +580,22 @@ void start_clicked (GtkButton *button, gpointer user_data) setenv("LTT_FACILITIES", fac_path, 1); /* Setup arguments to su */ - if(strcmp(lttctl_path, "") == 0) { - strncpy(args, "lttctl", args_left); - args_left = MAX_ARGS_LEN - strlen(args) - 1; - } else { - strncpy(args, lttctl_path, args_left); - args_left = MAX_ARGS_LEN - strlen(args) - 1; - } + //strncpy(args, "\'", args_left); + //args_left = MAX_ARGS_LEN - strlen(args) - 1; + + /* Command */ + strncat(args, "exec", args_left); + args_left = MAX_ARGS_LEN - strlen(args) - 1; + + /* space */ + strncat(args, " ", args_left); + args_left = MAX_ARGS_LEN - strlen(args) - 1; + + if(strcmp(lttctl_path, "") == 0) + strncat(args, "lttctl", args_left); + else + strncat(args, lttctl_path, args_left); + args_left = MAX_ARGS_LEN - strlen(args) - 1; /* space */ strncat(args, " ", args_left); @@ -470,43 +651,47 @@ void start_clicked (GtkButton *button, gpointer user_data) args_left = MAX_ARGS_LEN - strlen(args) - 1; } - /* space */ - strncat(args, " ", args_left); - args_left = MAX_ARGS_LEN - strlen(args) - 1; - /* optional arguments */ /* subbuffer size */ if(strcmp(subbuf_size, "") != 0) { + /* space */ + strncat(args, " ", args_left); + args_left = MAX_ARGS_LEN - strlen(args) - 1; + strncat(args, "-z ", args_left); args_left = MAX_ARGS_LEN - strlen(args) - 1; strncat(args, subbuf_size, args_left); args_left = MAX_ARGS_LEN - strlen(args) - 1; } - /* space */ - strncat(args, " ", args_left); - args_left = MAX_ARGS_LEN - strlen(args) - 1; - /* number of subbuffers */ if(strcmp(subbuf_num, "") != 0) { + /* space */ + strncat(args, " ", args_left); + args_left = MAX_ARGS_LEN - strlen(args) - 1; + strncat(args, "-x ", args_left); args_left = MAX_ARGS_LEN - strlen(args) - 1; strncat(args, subbuf_num, args_left); args_left = MAX_ARGS_LEN - strlen(args) - 1; } + + //strncat(args, "\'", args_left); + //args_left = MAX_ARGS_LEN - strlen(args) - 1; - g_message("Executing (as %s) : %s", username, args); + g_message("Executing (as %s) : %s\n", username, args); - //execlp("su", "-p", ); - //exit(-1): /* not supposed to happen! */ - system(args); - exit(0); + execlp("su", "su", "-p", "-c", args, username, NULL); + exit(-1); /* not supposed to happen! */ + //system(args); + //system("echo blah"); + //exit(0); //gint ret = execvp(); } else { /* error */ - + g_warning("Error happened when forking for su"); } }