Do proper error-handling.
authorSoeren Sandmann <sandmann@redhat.com>
Sun, 5 Mar 2006 21:11:07 +0000 (21:11 +0000)
committerSøren Sandmann Pedersen <ssp@src.gnome.org>
Sun, 5 Mar 2006 21:11:07 +0000 (21:11 +0000)
2006-03-05 Soeren Sandmann <sandmann@redhat.com>

        * sysprof-text.c, collector.c, sysprof.c: Do proper
        error-handling.

ChangeLog
collector.c
collector.h
sysprof-text.c
sysprof.c

index 0ab99ec..0283278 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2006-03-05 Soeren Sandmann <sandmann@redhat.com>
+
+       * sysprof-text.c, collector.c, sysprof.c: Do proper
+       error-handling.
+
 Fri Mar  3 22:28:03 2006  Soeren Sandmann  <sandmann@redhat.com>
 
        * process.c (process_lookup_symbol): Check that the inodes match.
index 0acd2fd..ec1b240 100644 (file)
@@ -29,6 +29,9 @@
 #include <fcntl.h>
 #include <unistd.h>
 
+static void set_no_module_error (GError **err);
+static void set_cant_open_error (GError **err, int eno);
+
 struct Collector
 {
     CollectorFunc      callback;
@@ -179,12 +182,13 @@ open_fd (Collector *collector,
        if (load_module())
        {
            GTimer *timer = g_timer_new ();
-           
+
            while (fd < 0 && g_timer_elapsed (timer, NULL) < 0.5)
            {
                /* Wait for udev to discover the new device */
                usleep (100000);
 
+               errno = 0;
                fd = open (SYSPROF_FILE, O_RDONLY);
            }
 
@@ -192,12 +196,15 @@ open_fd (Collector *collector,
            
            if (fd < 0)
            {
-               /* FIXME: set "module is loaded but no file error" */
+               set_cant_open_error (err, errno);
+               return FALSE;
            }
        }
 
        if (fd < 0)
        {
+           set_no_module_error (err);
+           
            /* FIXME: set error */
            return FALSE;
        }
@@ -323,3 +330,39 @@ collector_create_profile (Collector *collector)
     
     return profile_new (info.resolved_stash);
 }
+
+static void
+set_no_module_error (GError **err)
+{
+    g_set_error (err,
+                COLLECTOR_ERROR,
+                COLLECTOR_ERROR_CANT_OPEN_FILE,
+                "Can't open " SYSPROF_FILE ". You need to insert "
+                "the sysprof kernel module. Run\n"
+                "\n"
+                "       modprobe sysprof-module\n"
+                "\n"
+                "as root");
+}
+
+static void
+set_cant_open_error (GError **err,
+                    int      eno)
+{
+    g_set_error (err,
+                COLLECTOR_ERROR,
+                COLLECTOR_ERROR_CANT_OPEN_FILE,
+                "Can't open " SYSPROF_FILE ": %s",
+                g_strerror (eno));
+}
+
+GQuark
+collector_error_quark (void)
+{
+    static GQuark q = 0;
+    
+    if (q == 0)
+        q = g_quark_from_static_string ("collector-error-quark");
+    
+    return q;
+}
index 7a5c1a8..b1d1e61 100644 (file)
@@ -23,11 +23,20 @@ typedef struct Collector Collector;
 
 typedef void (* CollectorFunc) (gpointer data);
 
+#define COLLECTOR_ERROR collector_error_quark ()
+
+GQuark collector_error_quark (void);
+
+typedef enum
+{
+    COLLECTOR_ERROR_CANT_OPEN_FILE
+} CollectorError;
+
 /* callback is called whenever a new sample arrives */
 Collector *collector_new (CollectorFunc callback,
-                       gpointer     data);
+                         gpointer     data);
 gboolean  collector_start (Collector *collector,
-                         GError   **err);
+                          GError   **err);
 void      collector_stop (Collector *collector);
 void      collector_reset (Collector *collector);
 int      collector_get_n_samples (Collector *collector);
index 8e46d20..2d16818 100644 (file)
@@ -47,91 +47,81 @@ dump_data (Application *app)
 {
     GError *err = NULL;
     Profile *profile = collector_create_profile (app->collector);
-
+    
     profile_save (profile, app->outfile, &err);
-
+    
     if (err)
     {
-        fprintf (stderr, "%s: %s\n", app->outfile, err->message);
+        fprintf (stderr, "Error saving %s: %s\n", app->outfile, err->message);
         exit (1);
     }
+    else
+    {
+       printf ("Saved profile in %s\n\n", app->outfile);
+    }
 }
 
 void
-signal_handler (int signo, gpointer data)
+signal_handler (int      signo,
+               gpointer data)
 {
     Application *app = data;
     
     dump_data (app);
-
+    
     while (g_main_iteration (FALSE))
        ;
     
     g_main_loop_quit (app->main_loop);
 }
 
-static void
-no_module (void)
+static char *
+usage_msg (const char *name)
 {
-    perror (SYSPROF_FILE);
-    fprintf (stderr,
-            "\n"
-            "Can't open " SYSPROF_FILE ". You need to insert "
-            "the sysprof kernel module. Run\n"
-            "\n"
-            "       modprobe sysprof-module\n"
-            "\n"
-            "as root.\n");
+    return g_strdup_printf (
+       "Usage: \n"
+       "    %s <outfile>\n"
+       "\n"
+       "On SIGTERM or SIGINT (Ctrl-C) the profile will be written to <outfile>",
+       name);
 }
 
 static void
-usage (const char *name)
+die (const char *err_msg)
 {
-    fprintf (stderr,
-            "\n"
-            "Usage: \n"
-            "    %s <outfile>\n"
-            "\n"
-            "On SIGTERM or SIGINT (Ctrl-C) the profile will be written to <outfile>\n"
-            "\n",
-            name);
+    if (err_msg)
+       fprintf (stderr, "\n%s\n\n", err_msg);
+    
+    exit (-1);
 }
 
 int
 main (int argc,
       char *argv[])
 {
-    gboolean quit;
     Application *app = g_new0 (Application, 1);
+    GError *err;
     
     app->collector = collector_new (NULL, NULL);
     app->outfile = g_strdup (argv[1]);
     app->main_loop = g_main_loop_new (NULL, 0);
-
-    /* FIXME: get the real error */
-    quit = FALSE;
     
-    if (!collector_start (app->collector, NULL))
-    {
-       no_module();
-       quit = TRUE;
-    }
+    err = NULL;
+    
+    if (!collector_start (app->collector, &err))
+       die (err->message);
     
     if (argc < 2)
-    {
-       usage (argv[0]);
-       quit = TRUE;
-    }
-
-    if (quit)
-       return -1;
+       die (usage_msg (argv[0]));
+    
+    if (!signal_set_handler (SIGTERM, signal_handler, app, &err))
+       die (err->message);
+    
+    if (!signal_set_handler (SIGINT, signal_handler, app, &err))
+       die (err->message);
     
-    /* FIXME: check the errors */
-    signal_set_handler (SIGTERM, signal_handler, app, NULL);
-    signal_set_handler (SIGINT, signal_handler, app, NULL);
-
     g_main_loop_run (app->main_loop);
-
+    
     signal_unset_handler (SIGTERM);
     signal_unset_handler (SIGINT);
     
index 7dcb9b3..6fe84af 100644 (file)
--- a/sysprof.c
+++ b/sysprof.c
@@ -352,6 +352,7 @@ static void
 on_start_toggled (GtkWidget *widget, gpointer data)
 {
     Application *app = data;
+    GError *err = NULL;
 
     if (!gtk_toggle_tool_button_get_active (
            GTK_TOGGLE_TOOL_BUTTON (app->start_button)))
@@ -359,7 +360,7 @@ on_start_toggled (GtkWidget *widget, gpointer data)
        return;
     }
     
-    if (collector_start (app->collector, NULL))
+    if (collector_start (app->collector, &err))
     {
        delete_data (app);
        
@@ -367,14 +368,9 @@ on_start_toggled (GtkWidget *widget, gpointer data)
     }
     else
     {
-       /* FIXME: get the real error message */
-       sorry (app->main_window,
-              "Can't open " SYSPROF_FILE ". You need to insert\n"
-              "the sysprof kernel module. Run\n"
-              "\n"
-              "       modprobe sysprof-module\n"
-              "\n"
-              "as root.");
+       sorry (app->main_window, err->message);
+
+       g_error_free (err);
     }
 
     update_screenshot_window (app);