make lttctl and lttd interaction more standard : real daemon
authorcompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Thu, 15 Sep 2005 16:38:31 +0000 (16:38 +0000)
committercompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Thu, 15 Sep 2005 16:38:31 +0000 (16:38 +0000)
git-svn-id: http://ltt.polymtl.ca/svn@1196 04897980-b3bd-0310-b5e0-8ef037075253

ltt/branches/poly/configure.in
ltt/branches/poly/lttctl/Makefile.am
ltt/branches/poly/lttctl/lttctl.c
ltt/branches/poly/lttd/lttd.c
ltt/branches/poly/lttv/modules/gui/tracecontrol/tracecontrol.c

index ff00a4cda299b315e50a465f434ebe8c5f4842ac..62db1a533105582faabbcdda60aaecd23a264cca 100644 (file)
@@ -40,6 +40,8 @@ AC_PROG_CC
 AC_CHECK_LIB([popt], [poptGetNextOpt], POPT_LIBS="-lpopt",AC_MSG_ERROR([libpopt is required in order to compile LinuxTraceToolkit])  )
 #AC_CHECK_LIB([m], [round], M_LIBS="-lm",AC_MSG_ERROR([Mathematical libraries are missing.])  )
 
+AC_CHECK_LIB([util], [forkpty], UTIL_LIBS="-lutil", AC_MSG_ERROR([libutil is
+required in order to compile LinuxTraceToolkit]))
 
 # Checks for header files.
 AC_HEADER_STDC
@@ -90,6 +92,7 @@ lttvwindowincludedir="${includedir}/lttvwindow"
 
 
 AC_SUBST(POPT_LIBS)
+AC_SUBST(UTIL_LIBS)
 AC_SUBST(lttvlibdir)
 AC_SUBST(lttvplugindir)
 AC_SUBST(lttlibdir)
index 7530c9db8dbab48bcdabecb89e7e22d367233617..cb33cb4127febc2be9e53e413eed9e2a70ba7ac9 100644 (file)
@@ -1,5 +1,7 @@
 ## Process this file with automake to produce Makefile.in
 
+AM_CFLAGS = -DPACKAGE_DATA_DIR=\""$(datadir)"\" -DPACKAGE_BIN_DIR=\""$(bindir)"\"
+
 bin_PROGRAMS = lttctl
 
 lttctl_SOURCES = \
index fe4be9b1f77c4424f7880f56ed93a5c8e276b453..19605c2e55888f86cf6cef78db4bce75058ff168 100644 (file)
@@ -17,6 +17,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/types.h>
+#include <sys/wait.h>
 #include <unistd.h>
 #include <signal.h>
 #include <dirent.h>
@@ -47,12 +48,12 @@ static enum trace_ctl_op op = CTL_OP_NONE;
 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;
 }
 
 
@@ -272,7 +273,7 @@ int create_eventdefs(void)
   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) {
@@ -295,6 +296,12 @@ int create_eventdefs(void)
   
   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;
     
@@ -342,7 +349,7 @@ close_dest:
 
   closedir(facilities_dir);
 
-  error:
+error:
   return ret;
 
 }
@@ -356,7 +363,8 @@ int lttctl_daemon(struct lttctl_handle *handle, char *trace_name)
        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, "/");
@@ -366,29 +374,33 @@ int lttctl_daemon(struct lttctl_handle *handle, char *trace_name)
        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);
@@ -406,6 +418,7 @@ int lttctl_daemon(struct lttctl_handle *handle, char *trace_name)
 
        /* error handling */
 start_error:
+  printf("Trace start error\n");
        ret |= lttctl_destroy_trace(handle, trace_name);
 create_error:
        return ret;
index 3553dfaeda2191c8a84cce896c65b8fe69b2b359..02724ce5285f6d10bdedfff992510f2a6b0dd93b 100644 (file)
@@ -67,7 +67,6 @@ static char *trace_name = NULL;
 static char *channel_name = NULL;
 static int     daemon_mode = 0;
 static int     append_mode = 0;
-static int     sig_parent = 0;
 volatile static int    quit_program = 0;       /* For signal handler */
 
 /* Args :
@@ -76,7 +75,7 @@ volatile static int   quit_program = 0;       /* For signal handler */
  * -c directory                Root directory of the relayfs trace channels.
  * -d                          Run in background (daemon).
  * -a                                                  Trace append mode.
- * -s                                                  Send SIGIO to parent when ready for IO.
+ * -s                                                  Send SIGUSR1 to parent when ready for IO.
  */
 void show_arguments(void)
 {
@@ -87,7 +86,6 @@ void show_arguments(void)
        printf("-c directory  Root directory of the relayfs trace channels.\n");
        printf("-d            Run in background (daemon).\n");
        printf("-a            Append to an possibly existing trace.\n");
-       printf("-s            Send SIGIO to parent when ready for IO.\n");
        printf("\n");
 }
 
@@ -133,9 +131,6 @@ int parse_arguments(int argc, char **argv)
                                        case 'a':
                                                append_mode = 1;
                                                break;
-                                       case 's':
-                                               sig_parent = 1;
-                                               break;
                                        default:
                                                printf("Invalid argument '%s'.\n", argv[argn]);
                                                printf("\n");
@@ -410,9 +405,6 @@ int read_channels(struct channel_trace_fd *fd_pairs)
                pollfd[i].events = POLLIN|POLLPRI;
        }
 
-       /* Signal the parent that ready for IO */
-       if(sig_parent) kill(getppid(), SIGIO);
-
        while(1) {
                high_prio = 0;
                num_hup = 0; 
index 4097e0cdf9db5e9cc096231c31d69dabde9c2ea1..75921a452bf203af051938a9ed60c3f2c2ff9c65 100644 (file)
@@ -44,7 +44,7 @@
 #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
 
@@ -304,7 +304,7 @@ 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);
@@ -449,32 +449,63 @@ void start_clicked (GtkButton *button, gpointer user_data)
     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");
@@ -482,26 +513,60 @@ void start_clicked (GtkButton *button, gpointer user_data)
     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 */
@@ -515,11 +580,26 @@ void start_clicked (GtkButton *button, gpointer user_data)
       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);
@@ -595,13 +675,13 @@ void start_clicked (GtkButton *button, gpointer user_data)
       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");
This page took 0.034248 seconds and 4 git commands to generate.