#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
+#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#include <dirent.h>
static char *channel_root = NULL;
static char *trace_root = NULL;
-static int sigio_received = 0;
+static int sigchld_received = 0;
-void handler(int signo)
+void sigchld_handler(int signo)
{
printf("signal %d received\n", signo);
- sigio_received = 1;
+ sigchld_received = 1;
}
struct dirent *entry;
char *facilities_path = getenv("LTT_FACILITIES");
if(facilities_path == NULL) facilities_path =
- "/usr/share/LinuxTraceToolkitViewer/facilities";
+ PACKAGE_DATA_DIR "/" PACKAGE "/facilities";
ret = mkdir(trace_root, S_IRWXU|S_IRWXG|S_IRWXO);
if(ret == -1 && errno != EEXIST) {
DIR *facilities_dir = opendir(facilities_path);
+ if(facilities_dir == NULL) {
+ perror("Cannot open facilities directory");
+ ret = -1;
+ goto error;
+ }
+
while((entry = readdir(facilities_dir)) != NULL) {
if(entry->d_name[0] == '.') continue;
closedir(facilities_dir);
- error:
+error:
return ret;
}
char *lttd_path = getenv("LTT_DAEMON");
struct sigaction act;
- if(lttd_path == NULL) lttd_path = "lttd";
+ if(lttd_path == NULL) lttd_path =
+ PACKAGE_BIN_DIR "/lttd";
strcat(channel_path, channel_root);
strcat(channel_path, "/");
ret = lttctl_create_trace(handle, trace_name, mode, subbuf_size, n_subbufs);
if(ret != 0) goto create_error;
- act.sa_handler = handler;
+ act.sa_handler = sigchld_handler;
sigemptyset(&(act.sa_mask));
- sigaddset(&(act.sa_mask), SIGIO);
- sigaction(SIGIO, &act, NULL);
-
- sigio_received = 0;
+ sigaddset(&(act.sa_mask), SIGCHLD);
+ sigaction(SIGCHLD, &act, NULL);
pid = fork();
if(pid > 0) {
+ int status;
/* parent */
- while(!sigio_received) pause();
+ while(!(sigchld_received)) pause();
+
+ waitpid(pid, &status, 0);
+ ret = 0;
+ if(WIFEXITED(status))
+ ret = WEXITSTATUS(status);
+ if(ret) goto start_error;
- /* Now the trace is created, go on and create the supplementary files... */
-
printf("Creating supplementary trace files\n");
ret = create_eventdefs();
if(ret) goto start_error;
} else if(pid == 0) {
/* child */
- int ret =
- execlp(lttd_path, lttd_path, "-t", trace_root, "-c", channel_path, "-s", NULL);
+
+ int ret = execlp(lttd_path, lttd_path, "-t", trace_root, "-c",
+ channel_path, "-d", NULL);
if(ret) {
perror("Error in executing the lttd daemon");
exit(-1);
/* error handling */
start_error:
+ printf("Trace start error\n");
ret |= lttctl_destroy_trace(handle, trace_name);
create_error:
return ret;
#include <pty.h>
#include <utmp.h>
#include <sys/wait.h>
-#include <sys/select.h>
+#include <sys/poll.h>
#define MAX_ARGS_LEN PATH_MAX * 10
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);
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
- int nbdes;
- fd_set readfds;
- FD_ZERO(&readfds);
- FD_SET(fdpty, &readfds);
-
- nbdes = select(fdpty+1, &readfds, NULL, NULL, &timeout);
-
- if(nbdes > 0) {
- do {
- count = read (fdpty, buf, 256);
- if(count > 0) {
- buf[count] = '\0';
- printf("%s", buf);
- }
- } while(select(fdpty+1, &readfds, NULL, NULL, &timeout) > 0);
-
- } else if(nbdes == -1) {
- perror("Timeout occured when waiting for su password prompt");
- return;
- } else {
- g_warning("No data within 2 seconds when waiting for su prompt");
- return;
- }
+ 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...");
- sleep(1);
int ret;
ret = write(fdpty, password, strlen(password));
if(ret < 0) perror("Error in write");
if(ret < 0) perror("Error in write");
fsync(fdpty);
- FD_ZERO(&readfds);
- FD_SET(fdpty, &readfds);
- do {
- if (select(fdpty+1, &readfds, NULL, NULL, &timeout) < 0) {
- g_warning("Cannot read from child pipe");
- return;
+ /* 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(FD_ISSET(fdpty, &readfds)) {
- count = read(fdpty, buf, 256);
- buf[count] = '\0';
- printf("%s", buf);
- } else FD_SET(fdpty, &readfds);
- usleep(200);
- } while(!(ret = waitpid(pid, &status, WNOHANG)));
+ 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, exit code : %hhu",
- WEXITSTATUS(ret));
+ 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 */
setenv("LTT_FACILITIES", fac_path, 1);
/* Setup arguments to su */
- strncpy(args, "\"", 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)
- lttctl_path = "lttctl";
+ 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);
+ args_left = MAX_ARGS_LEN - strlen(args) - 1;
/* channel dir */
strncat(args, "-l ", args_left);
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;
- strncat(args, "\"", args_left);
- args_left = MAX_ARGS_LEN - strlen(args) - 1;
-
- //printf("Executing (as %s) : %s %s\n", username, lttctl_path, args);
+ g_message("Executing (as %s) : %s\n", username, args);
- execlp("su", "su", "-p", "-c", lttctl_path, username, args, NULL);
+ execlp("su", "su", "-p", "-c", args, username, NULL);
exit(-1); /* not supposed to happen! */
//system(args);
//system("echo blah");